python_study

记录Python常用的组件

redis

redis模块用于Python连接redis数据库。redis提供了两个类Redis和StrictRedis用于实现Redis的命令。

安装redis

1
pip install redis

基本使用

1
2
3
4
# 连接服务
import redis
client = redis.Redis(host='localhost', port=6739, decode_responses=True)

decode_responses=True,表示写入的键值对中的value为字符串类型,为False(默认值)表示写入字节类型。
除了直连方式,redis还提供了连接池功能,这样可以更优的使用连接:

1
2
3
import redis
clientPool = redis.ConnectionPool(host='host', port=6397, decode_responses=True)

set命令

set命令的语法为:set(name, value, ex=None, px=None nx=False, xx=False)

ex:过期时间-秒
nx:过期时间-毫秒
px:设置True时,只有name不存在时才执行
xx:设置True时,只有name存在时才执行

其他命令 >> https://www.jianshu.com/p/2639549bedc8

mysql

MySQLdb是用于Pyton连接Mysql数据库的接口,它实现了Python数据库API规范V2.0,基于MySQL C API上建立的。

安装MySQLdb

在通过如下脚本引入 MySQLdb 模块时

1
2
3
4
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import MySQLdb

如果发生如下报错:

1
2
3
4
Traceback (most recent call last):
File "test.py", line 3, in <module>
import MySQLdb
ImportError: No module named MySQLdb

则说明,当前python环境中没有安装 MySQLdb模块。

安装MySQLdb可以参考“https://pypi.python.org/pypi/MySQL-python”,基本上执行

1
pip install MySQL-python

命令就可以了。

基本使用

MySQLdb的使用指南:https://mysqlclient.readthedocs.io/user_guide.html#mysqldb
使用这个模块,首先就是导入:

1
2
3
4
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import MySQLdb

然后调用MySQLdb的connect方法与server建立连接:

1
2
3
4
5
# 创建连接
conn = MySQLdb.connect("host", "userName", "password", "DB-name", port, charset='utf8' )
# 为了防止连接泄漏,不用的时候需要关闭
conn.close()

建立连接后,就可以用来创建游标,并使用游标来进行各种操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 调用cursor方法获取游标
cursor = conn.cursor()
# 调用游标执行sql
cursor.execute("sql...")
# 对于查询sql的执行,通过游标获取数据
row = cursor.fetchone()
rows = cursor.fetchall()
c = cursor.rowcount()
# 对于执行写入的sql,需要连接提交
conn.commit()
# 如果写入失败,需要连接回滚
conn.rollback()

使用用例

Zookeeper

Python中用于操作Zookeeper的模块是 kazoo。

安装kazoo

基本使用

要想使用kazoo,需要先进行导入

1
from kazoo.client import KazooClient,KazooState

然后便可以创建Zookeeper客户端

1
2
3
4
# 创建客户端
zk = KazooClient(host='127.0.12.1:2181,127.0.0.1:2181', timeout=10, logger=logging)
# 启动后开始和server心跳
zk.start()

timeout 是连接超时时间
logger 是用来进行日志输出的日志对象

1
2
3
4
5
6
7
8
9
10
11
12
# 获取节点数据和状态
data, stat = zk.get('/myZnode')
# 获取子节点
children = zk.get_children("/")
# 监听节点变化
def zkEvent(event):
print type(event)
print event
zk.exists("/zNode", zkEvent)

其他方法可以参考kazoo的文档

使用用例

logging

loggine模块用来处理日志信息。

基本使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
需要使用logging模块,首先要引入
import loggine
# 调用 logging的方法来记录不同级别的日志
logging.warning("here is warning")
logging.info("here is info")
# 如果不设置,日志的数据级别默认为waring,如下设置日志的输出级别,以及日志格式
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s:%(name)s:%s(levelname)s:%(message)s')
# 没有创建logger,默认是root logger,我们可以创建自己的logger
logger = logging.getLogger("kafka")
logger.setLevel(logging.DEBUG)
# 日志信息是否向上传播
logger.propagate = False
# 添加Handler,用于处理日志的输出位置
kafka_log_handler = logging.FileHandler(filename="myKafka.log")
# 定义日志格式
kafka_formatter = logging.Formatter('%(asctime)s:%(name)s:%s(levelname)s:%(message)s')
# 将formatter赋值给handler,将handler赋值给 logger
kafka_log_handler.setFormatter(kafka_formatter)
logger.addHandler(kafka_log_handler)
# 定义一个继承前面kafka的logger
logger_c = logging.getLogger("kafka.child")
# 这样logger_c的日志也会输出到 kafka的 logger中。

上面使用过实例化logging.logger,然后给logger添加所需的设置,除此之外,我们还可以通过

1
logging.config.dictConfig来从配置文件生成logger

配置文件定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
PATTERN = {
'version': 1,
'formatters': {
'normal': {
'format': '%(name)s %(asctime)s %(levelname)s %(message)s',
'datefmt': '%Y-%m-%d %H:%M:%S'
},
'raw': {
'format': '%(message)s',
},
},
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'stream': 'ext://sys.stdout',
'formatter': 'normal',
},
'root': {
'class': 'logging.handlers.WatchedFileHandler',
'formatter': 'normal',
'filename': RUNTIME_HOME + '/var/log/root.log',
'mode': 'a',
'level': 'INFO',
},
'extapi': {
'class': 'logging.handlers.WatchedFileHandler',
'formatter': 'normal',
'filename': RUNTIME_HOME + '/var/log/ext_api.log',
'mode': 'a',
'level': 'DEBUG',
},
'api': {
'class': 'logging.handlers.WatchedFileHandler',
'formatter': 'normal',
'filename': RUNTIME_HOME + '/var/log/api.log',
'mode': 'a',
'level': 'DEBUG',
},
},
'loggers': {
'API': {'level': 'DEBUG',
'handlers': ['api'],
},
'EXTAPI': {'level': 'DEBUG',
'handlers': ['extapi'],
},
'requests.packages.urllib3.connectionpool': {'level': 'ERROR'},
},
'root': {
'handlers': ['root',],
'level': 'INFO',
}
}

然后使用配置文件初始化logging

1
2
3
4
logging.config.dictConfig(log_config.PATTERN)
# 然后通过getLogger方法获取logger
api_logger = logging.getLogger("API")

Formatter的设置

%(levelno)s:打印日志的级别数值信息。
%(levelname)s:打印日志的级别名称。
%(pathname)s:打印当前执行程序的路径信息。
%(filenae)s:打印当前执行程序的名字。
%(funcName)s:打印当前的函数名。
%(lineno)d:打印日志的当前行号。
%(asctime)s:打印日志的时间。
%(thread)d:打印线程ID。
%(threadName)s:打印线程名称。
%(process)d:打印进程ID。
%(message)s:打印日志信息。

日志的滚动和日志保留个数

使用TimedRotatingFileHandler可以设置日志的滚动方式以及保留的日志文件个数。

1
2
log_file_handler = TimedRotatingFileHandle(filename='roll_log', when='M', interval=2, backupCount=1)
# filename是日志文件的名字, when是日志滚动的时间单位,interval是日志滚动的间隔,backupCount是日志文件保留的个数。

when的取值

S:秒
M:分钟
H:小时
D:天
W:周
midnight:午夜。
如果选择D,不是以日期天来滚动的,是以启动日志时,24小时为一天算。

参考文档:https://docs.python.org/2/library/logging.config.html#logging-config-dictschema