第2周总结

1 MySQL 的 utf-8

MySQL 数据库的 utf-8 编码数据读取:MySQL 如果数据库创建时使用了utf-8,存数据的时候是utf-8,那么在python读数据库,那么在也需要设定 utf-8 编码。

推荐使用

import MySQLdb
db = MySQLdb.connect(...)
db.set_character_set('utf8')
cursor = db.cursor()
cursor.execute('SET NAMES utf8;')

或者参数上设定charset。参照 python,mysql,MySQLDb支持中文(utf-8编码)

db = MySQLdb.connect(..., charset="utf8");
db = db.cursor();
db.execute("SET NAMES utf8");

或者两个值都写到参数中。参照 Writing UTF-8 String to MySQL with Python

conn = MySQLdb.connect(charset='utf8', init_command='SET NAMES UTF8')

对于 db.execute("SET NAMES utf8") 语句,以下三条效果是一样的:

cursor.execute("SET NAMES utf8;") 
cursor.execute("SET CHARACTER SET utf8;") 
cursor.execute("SET character_set_connection=utf8;") 

2 Python 自带的 logging 模块

logging 模块的使用。以下代码实现了:debug及以上级别日志写入 my_app.log 文件中,同时 info 级别及其以上级别的日志也输出到终端。

# coding:utf-8
import logging

logging_cfg = {'filename':'my_app.log'}

def init_logging():
    logging.basicConfig(level=logging.DEBUG,
                        format='[%(asctime)s - %(levelname)-8s - %(filename)s - line: %(lineno)d]  %(message)s',
                        datefmt='%a, %d %b %Y %H:%M:%S',
                        filename=logging_cfg.get('filename', 'default_logging.log'),
                        filemode='a')

    # 定义一个StreamHandler,将INFO级别或更高的日志信息打印到标准错误,并将其添加到当前的日志处理对象
    console = logging.StreamHandler()
    console.setLevel(logging.INFO)
    formatter = logging.Formatter('[%(asctime)s - %(name)s - %(levelname)-8s] %(message)s')
    console.setFormatter(formatter)
    logging.getLogger('').addHandler(console)
    logging.info('logging module initialized, save as {}'.format(logging_cfg.get('filename', 'default_logging.log')))

init_logging()

logging.info('MAIN PROCEDURE BEGIN')
logging.debug('This is debug message')
logging.info('This is info message')
logging.warning('This is warning message')
logging.info('MAIN PROCEDURE BEGIN')

logging 模块可参考:

15.7. logging— Logging facility for Python

Logging HOWTO

3 Python 字符串占位符 %s.format()

%s 是旧式占位符,.format() 是新式占位符,更推荐使用。

3.1 占位符对于位数的控制

我第一次看见看见 "%3d" % 这种操作时,以为是做“求余”的运算,特别是对后面的随机数求余,然而并不是。所以尽量使用 .format() 提高可读性。

import random
print "%3d" % random.randint(1, 999)
print "{:0>3d}".format(random.randint(1, 999))

# 构建齐整的位数
print "user_name" + "{:0>3d}".format(random.randint(1, 999))

print "%0.2f" % 99.12345
print "{:.2f}".format(+99.12345)
print "{:.2f}".format(-99.12345)
print "{:+.2f}".format(+99.12345)
print "{:+.2f}".format(-99.12345)

输出结果

606
531
user_name234
99.12
99.12
-99.12
+99.12
-99.12

3.2 更多的 .format() 的好处

%s 一不注意就会写成第一行注释掉的代码,导致报错。对于多变量的占位符,必须构成元组。而且元组中的变量个数要和占位符数量相等。所以还是推荐 .format(),可以用 {},也可以指定元素所在位置 {1},或者可以使用变量代替。

# print "Here are %s and %s" % "Li Lei", "Han Meimei"   # 不写括号来构成元组,Python 会报错
print "Here are %s and %s" % ("Li Lei", "Han Meimei")

# 类似于 %s 的用法
print "Here are {} and {}".format("Li Lei", "Han Meimei")

# 指定位数
print "Here are {1} and {0}. {0} is the first.".format("Li Lei", "Han Meimei")
print "Here are {1} and {2}".format("Li Lei", "Han Meimei", "Jim")

# 变量名代替
print "Here comes {person_1} and {person_2}".format(person_1="Li Lei", person_2="Han Meimei")
# 变量名代替,而且可以只是用一个变量
print "Here comes {person_1}.".format(person_1="Li Lei", person_2="Han Meimei")

4 两种方式获取当前时间 datetime 与 time

重点是 datetime.datetim.now() 不是秒时间,用 time.time() 得到的秒数,int() 转换之后,就可以两个时间简单相减获得时间间隔,用来获取某一段代码耗时比较有用。



​```python
In [1]: from datetime import datetime
In [1]: from datetime import datetime

In [2]: from time import time

In [3]: t = datetime.fromtimestamp(time())

In [4]: t
Out[4]: datetime.datetime(2017, 8, 3, 17, 23, 22, 6560)

In [5]: t.strftime("%H:%M:%S")
Out[5]: '17:23:22'

In [6]: t.strftime("%H:%M:%S:%f")
Out[6]: '17:23:22:006560'

In [7]: t.strftime("%H:%M:%S %f")
Out[7]: '17:23:22 006560'

In [8]: t.strftime("%H:%M:%S %fms")
Out[8]: '17:23:22 006560ms'

In [9]: datetime.now().strftime("%H:%M:%S %fms")
Out[9]: '17:25:15 110922ms'

5 文件顶部的语句会被执行

假设同一目录下,有两个文件 a.py 和 b.py,如果想在 a.py 文件中引用了 b.py 文件中的 var_c 变量。

# a.py
from b import var_c

print var_c

结果发现,引用的时候,会同时把 var_c = 123 以上的语句都执行了。

# b.py
print "hello"

def te():
    print "where"
te()

var_c = 123

参考 写在Python模块顶层的代码引起的一个Bug

6 另外的小 tips

6.1 Linux 查找进程,并 kill 进程

ps aux 是查看所有进程,grep xxx 是查找对应名称,kill -9 XXX 是杀死 xxx 编号的进程.

ps aux|grep python en.py
kill -9 xxx

6.2 python 函数可以使用函数外变量,但是要改变变量,加 global

参考 python中在哪些情况下必须使用global来声明全局变量?

6.3 二进制去除 '0b' 并补齐位数

zfill() 函数补齐至相应位数。

  • 对于 1 到 3 取数
  • 对每个数求二进制数,用 bin() 方法,得到 0b 开头的二进制数
  • replace(),去除 0b
  • 最后用 zfill(10) 填满10位。
>>> for i in range(1, 3):
...     print bin(i).replace("0b","").zfill(10)
...
0000000001
0000000010
0000000011

你可能感兴趣的:(第2周总结)