- 目录
- 相关概念
- 模块os
- 模块sys
- 模块time
- 模块random
- 模块pickle
- 模块json
- 模块logging
- 模块paramiko
- 模块configparser
- 模块MySQLdb
- 模块hashlib
- 模块uuid
- 模块md5
- 模块
相关概念
- 过程编程 , 函数式编程, 模块化编程是一个意思,区别于面向对象编程
- 面向对象编程好处:(特性: 封装,继承,多态)
python程序可以分解成模块,语句,表达式和 对象
- 程序由模块构成
- 模块包含语句
- 语句包含表达式
- 表达式建立并处理对象
表达式是”某事“, 语句是“做某事”即指令
语句的特性:它们改变了事物,例如,赋值语句改变了变量,print改变了屏幕输出。
模块导入的使用
1 | >>> import platform |
模块导入区别
import 导入会形成以模块名同名的名称空间,如果有个方法叫uname(),那么我们调用是print(platform.uname())加上platform名称空间前缀不会冲突
1 | >>> import random # 独立名称空间 |
from-import是导入指定模块的某些方法和属性,会导入在当前名称空间里,如果当前名称空间也有choice方法,那么会覆盖choice方法。
import和from-import是可执行语句,独立可执行片断,可以嵌套在if测试中,或出现在def中,这样在我们满足条件再导入模块。
己知模块查找此模块在系统中的路径,用法module_name.__file__
1
2
3>>> import random
>>> random.__file__
'/usr/lib/python3.4/random.py'
反射
有一种说法叫反射
1 以字符串的形式导入模块
2 以字符串的形式调用函数
例子:1
2
3
4
5
6
7
8
9
10
11
12
13root@apt:~# cat /usr/local/lib/python2.7/dist-packages/pkg/mysql.py
#!/usr/bin/python2.7
def count():
return 3306
root@apt:~#
In [1]: var = 'pkg.mysql'
In [2]: mode = __import__(var)
In [3]: mode.mysql.count()
Out[3]: 3306
In [4]: func = 'count'
In [5]: Func = getattr(mode.mysql, func)
In [6]: Func()
Out[6]: 3306
模块os
More info 详情
模块sys
利用sys模块模拟#滚动条1
2
3
4
5
6
7
8import sys,time
In [111]: for i in range(50):
.....: sys.stdout.write("\033[32;1m#\033[0m")
.....: sys.stdout.flush()
.....: time.sleep(0.05)
.....:
##################################################
time模块
random模块
几个有用的方法1
2
3
4import random
print(random.randint(1,10)) # 取1-9
print(random.randrange(1,20,2)) # 步长为2,意味着取奇数
print(random.sample([1,2,3,4,5,6,7,8],3)) # 取一个3个元素的列表[3, 6, 1]
生成随机码(一)1
2
3
4
5
6
7
8
9checkcode = ''
for i in range(4):
current=random.randrange(0,4)
if current != i:
tmp = chr(random.randint(65,90))
else:
tmp = random.randint(0,9)
checkcode += str(tmp)
print(checkcode)
生成随机码(二)1
2
3
4import string
# print(string.ascii_uppercase + string.ascii_lowercase+string.digits)
source = string.ascii_uppercase + string.ascii_lowercase+string.digits
print("".join(random.sample(source,4)))
pickle模块
pickle只是python支持,那么可以序列化python内所有数据类型
在程序运行的过程中,所有的变量都是在内存中,过程中可能改变变量,程序结束,内存变量回收。此时如果没有把修改过的变量存到磁盘上,下次程序运行又是最初的变量,怎么解决这个问题,序列化就派上用场了。
序列化: 把内存中的变量变成可存储可传输的过程称为序列化,pickling
反序列化:把变量从序列化对象重新读入内存称为反序列化,unpickling
pickle.dump() 序列化入文件
pickle.dumps() 序列化为字符串,可赋值
pickle.load() 从文件加载
pickle.loads() 从字符串加载
1 | In [27]: import pickle |
1 | In [36]: import pickle |
json模块
json是各语言通用的序列化数据交换格式,只支持序列化数据类型:str int float set dict list tuple
JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输,并且可以直接在Web页面中读取,这也是为什么json这么通用的原因。
1 | import json |
logging模块
python的logging模块提供了标准的日志接口,我们来看一下简单用法1
2
3
4
5
6
7
8
9
10
11
12root@apt:/tmp# cat log.py
#!/usr/bin/env python3
import logging
#日志级别: DEGUG INFO WARNING ERROR CRITICAL
#数字表示分别为 10 20 30 40 50
logging.warning("warning message")
logging.error("error message")
root@apt:/tmp# python3 log.py
WARNING:root:warning message
ERROR:root:error message
上面的日志是直接输出,怎么才能让应用程序日志写入文件呢? 也很简单
定义一个log.py的文件1
2
3
4
5
6
7
8
9
10
11
12
13root@apt:/tmp# cat log.py
#!/usr/bin/env python3
import logging
#日志级别: DEGUG INFO WARNING ERROR CRITICAL
#数字表示分别为 10 20 30 40 50
log_file = 'example.log'
logging.basicConfig(filename=log_file,level=logging.INFO)
logging.debug('program debug message ...')
logging.info('info message')
logging.warning("warning message")
logging.error("error message")
运行一下log.py文件1
2
3
4
5root@apt:/tmp# python3 log.py
root@apt:/tmp# cat example.log
INFO:root:info message
WARNING:root:warning message
ERROR:root:error message
我们注意到logging.debug信息并没有写入,为什么呢?因为level=logging.INFO
定义要写入日志的日志级别,只有达到定义的日志级别才会记录。
但是发现记录的日志太丑了,怎么样才能让打印的日志人性化呢,就需要格式化输出。
格式 | 说明 |
---|---|
%(name)s | Logger的名字 |
%(levelno)s | 数字形式的日志级别 |
%(levelname)s | 文本形式的日志级别 |
%(pathname)s | 调用日志输出函数的模块的完整路径名,可能没有 |
%(filename)s | 调用日志输出函数的模块的文件名 |
%(module)s | 调用日志输出函数的模块名 |
%(funcName)s | 调用日志输出函数的函数名 |
%(lineno)d | 调用日志输出函数的语句所在的代码行 |
%(created)f | 当前时间,用UNIX标准的表示时间的浮 点数表示 |
%(relativeCreated)d | 输出日志信息时的,自Logger创建以 来的毫秒数 |
%(asctime)s | 字符串形式的当前时间。默认格式是 “2017-02-01 16:49:45,896”。逗号后面的是毫秒 |
%(thread)d | 线程ID。可能没有 |
%(threadName)s | 线程名。可能没有 |
%(process)d | 进程ID。可能没有 |
%(message)s | 用户输出的消息 |
如果想同时把log打印在屏幕和文件日志里,或者有日志切割的需求,可能要复杂些
- logger提供了应用程序可以直接使用的接口;
- handler将(logger创建的)日志记录发什么方式输出,是屏幕还是文件,或二都都要;
- filter提供了细度过滤来决定哪些日志不要输出,如密码敏感信息;
- formatter决定日志记录的最终输出格式。
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
30import logging
#create logger
logger = logging.getLogger('TEST-LOG')
logger.setLevel(logging.DEBUG)
# create console handler and set level to debug
sh = logging.StreamHandler()
sh.setLevel(logging.DEBUG)
# create file handler and set level to warning
fh = logging.FileHandler("access.log")
fh.setLevel(logging.WARNING)
# create formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# add formatter to sh and fh
sh.setFormatter(formatter)
fh.setFormatter(formatter)
# add ch and fh to logger
logger.addHandler(sh)
logger.addHandler(fh)
# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')
日志切割
handlers.RotatingFileHandler:按文件大小切割
handlers.TimedRotatingFileHandler: 按时间切割
示例1:1
大小切割略
示例2:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16import logging
from logging import handler
logger = logging.getLogger(__name__)
log_file = "timelog.log"
#fh = handlers.RotatingFileHandler(filename=log_file,maxBytes=10,backupCount=3)
fh = handlers.TimedRotatingFileHandler(filename=log_file,when="S",interval=5,backupCount=3)
formatter = logging.Formatter('%(asctime)s %(module)s:%(lineno)d %(message)s')
fh.setFormatter(formatter)
logger.addHandler(fh)
logger.warning("test1")
logger.warning("test12")
logger.warning("test13")
logger.warning("test14")
模块paramiko
1 | `pycrypto-2.6.1.tar.gz`# 下载安装 |
模块configparser
生成如下example.ini 文件,该如何做呢1
2
3
4
5
6
7
8
9
10
11
12
13root@ubuntu:~# cat example.ini
[DEFAULT]
compression = yes
serveraliveinterval = 45
compressionlevel = 9
forwardx11 = yes
[bitbucket.org]
user = wxq
[topsecret.server.com]
host port = 5000
forwardx11 = no
编写如下脚本执行 python3 create_example.py即可
1 | root@ubuntu:~# cat create_example.py |
那么有了example.ini 这样的文件,如何读取呢1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22>>> import configparser # 导入模块
>>> config = configparser.ConfigParser() # 类实例化
>>> config.sections() # 调用类中一个方法
[]
>>> config.read('example.ini') # 文件读入
['example.ini']
>>> config.sections() # 除了[DEFAULT]还有哪些区块,列表呈现
['bitbucket.org', 'topsecret.server.com']
>>> 'bitbucket.org' in config
True
>>> config['bitbucket.org']['user'] # 指定区块指定字典键对应值
'wxq'
>>> config['DEFAULT']['compression']
'yes'
>>> for i in config['bitbucket.org']: # 指定区块打印键
... print(i) # 注意:包括[DEFAULT]区块的键也在这里呈现
...
user
compression
serveraliveinterval
compressionlevel
forwardx11
1 | >>> d1 = config['bitbucket.org'] # 指定区块读出其实是一个字典 |
1 | root@ubuntu:~# cat wxq.txt # 有这么一个文件 |
1 | root@ubuntu:~# cat wxq # 按照上面的写入会生成了一个新文件 |
1 | >>> config.remove_option('section3', 'k1') # 删除某键值对 |
模块MySQLdb
python连接数据库操作
- 建立数据库连接
- 创建游标cursor(用于发送sql语句,获取sql结果,解析返回结果)
- 关闭游标cursor curname.close()
- 关闭数据库连接 conname.close()
模块安装
apt-get install python-mysqldb
查看模块
help(‘modules’)
加载数据库模块
import MySQLdb as mysql
创建连接,会生成一个con.cursor()的类
con = mysql.connect(host=’127.0.0.1’,user=’root’,passwd=’dbpass’)
游标类实例化
cur = con.cursor()
cur.execute 传入一个参数执行sql语句
cur.executemany 传入多个参数执行sql语句
cur.fetchall 查询执行后的结果返回所有
cur.fetchmany查询执行后的结果返回多个
cur.fetchone 查询执行后的结果返回一个
游标回滚
help(cur.scroll)
scroll(self, value, mode=’relative’)
cur.scroll(0,mode=’absolute’)
hashlib模块
用于加密相关操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法1
2
3
4
5
6
7
8
9import hashlib
str = hashlib.sha1(b'admin123') # python3中必须bytes格式
str.hexdigest()
'f865b53623b121fd34ee5426c792e5c33af8c227'
str = hashlib.md5(b'admin123')
str.hexdigest()
'0192023a7bbd73250516f069df18b500'
1 | import hashlib |
python 还有一个 hmac 模块,它内部对我们创建 key 和 内容 再进行处理然后再加密1
2
3
4import hmac
h = hmac.new(b'wxq')
h.update(b'hi')
print(h.hexdigest())
来个实用例子:
注意:bytes只接收ascii的值,字符串为unicode,需转为ascii样的值,比如utf-8
1 | root@wxq:~# cat md5.py |
更多关于md5,sha1,sha256等介绍的文章.看这里
模块uuid
直接来个例子:1
2
3
4
5
6
7
8
9
10root@wxq:~# cat create_uuid.py
#!/usr/bin/env python3
import uuid
def create_uuid():
return (str(uuid.uuid1()))
res = create_uuid()
print(res)
root@wxq:~# python3 create_uuid.py
2cad772c-fe7d-11e6-b3db-3a71234db8d2
模块md5
1 | #password=form.cleaned_data['password'] |
update可以执行多次,效果一样1
2
3m.update(b"hello ")
m.update(b"world")
等同于m.update(b"hello world")