Python的平凡之路(5)
#Author is wspikh
# -*- coding: encoding -*-
#导入module_import包中test5程序的test方法
from module_import.test5 import test
def logger1():
test()
print("------oh!-------")
logger1()
def logger2():
test()
print("------yeah!------")
logger2()
#Author is wspikh
# -*- coding: encoding -*-
import os,time,datetime
print(time.localtime())
print(time.time())
print(time.clock())
print(time.sleep(2))
print(time.gmtime()) #时间戳转时间元组(标准时区)
print(time.localtime()) #时间戳转时间元组(本地时区)
#时间戳转(时间)元组
x = time.localtime(123213123)
print(x)
print(x.tm_year)
print("this is 1973 day:%d" %x.tm_yday)
#元组转时间戳
x = time.localtime()
print(time.mktime(x))
#元组转格式化时间(格式化的字符串)
x = time.localtime()
print(time.strftime("%Y-%m-%d %H:%M:%S",x))
#格式化时间转元组
#Author is wspikh
# -*- coding: encoding -*-
import datetime,time
print(datetime.datetime.now())
print(datetime.date.fromtimestamp(time.time()))
print(datetime.datetime.now() )
print(datetime.datetime.now() + datetime.timedelta(3)) #当前时间+3天
print(datetime.datetime.now() + datetime.timedelta(-3)) #当前时间-3天
print(datetime.datetime.now() + datetime.timedelta(hours=3)) #当前时间+3小时
print(datetime.datetime.now() + datetime.timedelta(minutes=30)) #当前时间+30分
#Author is wspikh
# -*- coding: encoding -*-
import random
print(random.randint(1,3)) #1~3都能照顾到
print(random.randrange(1,3)) #不留尾
print(random.sample("hello",2)) #多字符中选取特定数量的字符
print(random.uniform(1,3)) #随机浮点数
print(random.random()) #随机浮点数
#随机验证码
checkcode = ''
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)
输出字符串指示正在使用的平台。如果是window 则用'nt'表示,对于Linux/Unix用户,它是'posix'。
2、os.getcwd()
函数得到当前工作目录,即当前Python脚本工作的目录路径。
3、os.listdir()
返回指定目录下的所有文件和目录名。
>>> os.listdir(os.getcwd())
['Django', 'DLLs', 'Doc', 'include', 'Lib', 'libs', 'LICENSE.txt', 'MySQL-python-wininst.log', 'NEWS.txt', 'PIL-wininst.log', 'python.exe', 'pythonw.exe', 'README.txt', 'RemoveMySQL-python.exe', 'RemovePIL.exe', 'Removesetuptools.exe', 'Scripts', 'setuptools-wininst.log', 'tcl', 'Tools', 'w9xpopen.exe']
>>>
4、os.remove()
删除一个文件。
5、os.system()
运行shell命令。
>>> os.system('dir')
0
>>> os.system('cmd') #启动dos
6、os.sep 可以取代操作系统特定的路径分割符。
7、os.linesep字符串给出当前平台使用的行终止符
>>> os.linesep
'\r\n' #Windows使用'\r\n',Linux使用'\n'而Mac使用'\r'。
>>> os.sep
'\\' #Windows
>>>
8、os.path.split()
函数返回一个路径的目录名和文件名
>>> os.path.split('C:\\Python25\\abc.txt')
('C:\\Python25', 'abc.txt')
9、os.path.isfile()和os.path.isdir()函数分别检验给出的路径是一个文件还是目录。
>>> os.path.isdir(os.getcwd())
True
>>> os.path.isfile('a.txt')
False
10、os.path.exists()函数用来检验给出的路径是否真地存在
>>> os.path.exists('C:\\Python25\\abc.txt')
False
>>> os.path.exists('C:\\Python25')
True
>>>
11、os.path.abspath(name):获得绝对路径
12、os.path.normpath(path):规范path字符串形式
13、os.path.getsize(name):获得文件大小,如果name是目录返回0L
14、os.path.splitext():分离文件名与扩展名
>>> os.path.splitext('a.txt')
('a', '.txt')
15、os.path.join(path,name):连接目录与文件名或目录
>>> os.path.join('c:\\Python','a.txt')
'c:\\Python\\a.txt'
>>> os.path.join('c:\\Python','f1')
'c:\\Python\\f1'
>>>
16、os.path.basename(path):返回文件名
>>> os.path.basename('a.txt')
'a.txt'
>>> os.path.basename('c:\\Python\\a.txt')
'a.txt'
>>>
17、os.path.dirname(path):返回文件路径
'c:\\Python'
if len(sys.argv) > 1:
print "there are", len(sys.argv)-1, "arguments:" # 使用len(sys.argv)-1采集参数个数-1为减去[0]脚本名称
for arg in sys.argv[1:]: #输出除了[0]外所有参数
print arg
else:
print "there are no arguments!"
启动 Python 时,这个列表从根据内建规则, PYTHONPATH 环境变量的内容, 以及注册表( Windows 系统)等进行初始化.
由于它只是一个普通的列表, 你可以在程序中对它进行操作,
使用sys模块操作模块搜索路径
sys.path.insert(0, "samples") #将路径插入到path,[0]中
import sample
sys.path = [] #删除path中所有路径
import random
使用sys模块查找内建模块
print module, "=>",
if module in sys.builtin_module_names: #查找内建模块是否存在
print "<BUILTIN>"
else:
module = _ _import_ _(module) #非内建模块输出模块路径
print module._ _file_ _
dump("os")
dump("sys")
dump("string")
dump("strop")
dump("zlib")
os => C:\python\lib\os.pyc
sys => <BUILTIN>
string => C:\python\lib\string.pyc
strop => <BUILTIN>
zlib => C:\python\zlib.pyd
使用sys模块查找已导入的模块
modules 字典包含所有加载的模块. import 语句在从磁盘导入内容之前会先检查这个字典.
Python 在处理你的脚本之前就已经导入了很多模块.
['os.path', 'os', 'exceptions', '_ _main_ _', 'ntpath', 'strop', 'nt',
'sys', '_ _builtin_ _', 'site', 'signal', 'UserDict', 'string', 'stat']
使用sys模块获得当前平台
sys.platform 返回当前平台 出现如: "win32" "linux2" 等
处理标准输出/输入
标准输入和标准错误 (通常缩写为 stdout 和 stderr) 是内建在每一个 UNIX 系统中的管道。
当你 print 某些东西时,结果前往 stdout 管道;
当你的程序崩溃并打印出调试信息 (例如 Python 中的 traceback (错误跟踪)) 的时候,信息前往 stderr 管道
... print'Dive in'
Dive in
Dive in
Dive in
>>> import sys
>>> for i in range(3):
... sys.stdout.write('Dive in')
Dive inDive inDive in
>>> for i in range(3):
... sys.stderr.write('Dive in')
saveout = sys.stdout # 终在重定向前保存stdout,这样的话之后你还可以将其设回正常
fsock = open('out.log', 'w') # 打开一个新文件用于写入。如果文件不存在,将会被创建。如果文件存在,将被覆盖。
sys.stdout = fsock # 所有后续的输出都会被重定向到刚才打开的新文件上。
print 'This message will be logged instead of displayed' # 这样只会将输出结果“打印”到日志文件中;屏幕上不会看到输出
sys.stdout = saveout # 在我们将 stdout 搞乱之前,让我们把它设回原来的方式。
fsock = open('error.log', 'w') # 打开你要存储调试信息的日志文件。
sys.stderr = fsock # 将新打开的日志文件的文件对象赋值给stderr以重定向标准错误。
raise Exception, 'this error will be logged' # 引发一个异常,没有在屏幕上打印出任何东西,所有正常的跟踪信息已经写进error.log
还要注意你既没有显式关闭日志文件,也没有将 stderr 设回最初的值。
这样挺好,因为一旦程序崩溃 (由于引发的异常),Python 将替我们清理并关闭文件
打印到 stderr
向标准错误写入错误信息是很常见的,所以有一种较快的语法可以立刻导出信息
entering function
>>> import sys
>>> print >> sys.stderr, 'entering function'
print "hello"
try:
sys.exit(1)
except SystemExit: # 捕获退出的异常
pass # 捕获后不做任何操作
print "there
print "world"
sys.exit(1) # 退出自动调用exitfunc()后,程序依然退出了
shutil.copyfileobj(fsrc, fdst[, length])
将文件内容拷贝到另一个文件中
|
1
2
3
|
import shutil
shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w')) |
shutil.copyfile(src, dst)
拷贝文件
|
1
|
shutil.copyfile('f1.log', 'f2.log') |
shutil.copymode(src, dst)
仅拷贝权限。内容、组、用户均不变
|
1
|
shutil.copymode('f1.log', 'f2.log') |
shutil.copystat(src, dst)
仅拷贝状态的信息,包括:mode bits, atime, mtime, flags
|
1
|
shutil.copystat('f1.log', 'f2.log') |
shutil.copy(src, dst)
拷贝文件和权限
|
1
|
shutil.copy('f1.log', 'f2.log') |
shutil.copy2(src, dst)
拷贝文件和状态信息
|
1
|
shutil.copy2('f1.log', 'f2.log') |
shutil.ignore_patterns(*patterns)
shutil.copytree(src, dst, symlinks=False, ignore=None)
递归的去拷贝文件夹
|
1
2
3
|
shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))shutil.copytree('f1', 'f2', symlinks=True, ignore=shutil.ignore_patterns('*.pyc', 'tmp*')) |
shutil.rmtree(path[, ignore_errors[, onerror]])
递归的去删除文件
|
1
|
shutil.rmtree('folder1') |
shutil.move(src, dst)
递归的去移动文件,它类似mv命令,其实就是重命名。
|
1
|
shutil.move('folder1', 'folder3') |
shutil.make_archive(base_name, format,...)
创建压缩包并返回文件路径,例如:zip、tar
创建压缩包并返回文件路径,例如:zip、tar
- base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
如:www =>保存至当前路径
如:/Users/wupeiqi/www =>保存至/Users/wupeiqi/ - format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
- root_dir: 要压缩的文件夹路径(默认当前目录)
- owner: 用户,默认当前用户
- group: 组,默认当前组
- logger: 用于记录日志,通常是logging.Logger对象
|
1
2
3
4
5
6
7
8
|
#将 /Users/wupeiqi/Downloads/test 下的文件打包放置当前程序目录import shutilret = shutil.make_archive("wwwwwwwwww", 'gztar', root_dir='/Users/wupeiqi/Downloads/test') #将 /Users/wupeiqi/Downloads/test 下的文件打包放置 /Users/wupeiqi/目录import shutilret = shutil.make_archive("/Users/wupeiqi/wwwwwwwwww", 'gztar', root_dir='/Users/wupeiqi/Downloads/test') |
shutil 对压缩包的处理是通过调用ZipFile 和 TarFile两个模块来进行的。
|
1
2
3
4
5
6
7
8
9
10
11
12
|
import zipfile
# 压缩z = zipfile.ZipFile('laxi.zip', 'w')
z.write('a.log')z.write('data.data')z.close()# 解压z = zipfile.ZipFile('laxi.zip', 'r')
z.extractall()z.close() |
|
1
2
3
4
5
6
7
8
9
10
11
12
|
import tarfile
# 压缩tar = tarfile.open('your.tar','w')
tar.add('/Users/wupeiqi/PycharmProjects/bbs2.log', arcname='bbs2.log')tar.add('/Users/wupeiqi/PycharmProjects/cmdb.log', arcname='cmdb.log')tar.close()# 解压tar = tarfile.open('your.tar','r')
tar.extractall() # 可设置解压地址tar.close() |
1 # dumps功能
2 # 将数据通过特殊的形式转换为所有程序语言都认识的字符串
3 >>> import json
4 >>> data = ['aa', 'bb', 'cc']
5 >>> j_str = json.dumps(data)
6 >>> j_str
7 '["aa", "bb", "cc"]'
1 # loads功能
2 # 将json编码的字符串再转换为python的数据结构
3 >>> j_str
4 '["aa", "bb", "cc"]'
5 >>> mes = json.loads(j_str)
6 >>> mes
7 ['aa', 'bb', 'cc']
1 # dump功能
2 # 将数据通过特殊的形式转换为所有程序语言都认识的字符串,并写入文件
3 with open('D:/tmp.json', 'w') as f:
4 json.dump(data, f)
1 # load功能
2 # 从数据文件中读取数据,并将json编码的字符串转换为python的数据结构
3 with open('D:/tmp.json', 'r') as f:
4 data = json.load(f)
对于字典,json会假设key是字符串(字典中的任何非字符串key都会在编码时转换为字符串),要符合JSON规范,应该只对python列表和字典进行编码。此外,在WEB应用中,把最顶层对象定义为字典是一种标准做法。
json编码的格式几乎和python语法一致,略有不同的是:True会被映射为true,False会被映射为false,None会被映射为null,元组()会被映射为列表[],因为其他语言没有元组的概念,只有数组,也就是列表。
2 >>> data = {'a':True, 'b':False, 'c':None, 'd':(1,2), 1:'abc'}
3 >>> j_str = json.dumps(data)
4 >>> j_str
5 '{"a": true, "c": null, "d": [1, 2], "b": false, "1": "abc"}'
1 # dumps功能
2 mport pickle
3 data = ['aa', 'bb', 'cc']
4 # dumps 将数据通过特殊的形式转换为只有python语言认识的字符串
5 p_str = pickle.dumps(data)
6 print(p_str)
7 b'\x80\x03]q\x00(X\x02\x00\x00\x00aaq\x01X\x02\x00\x00\x00bbq\x02X\x02\x00\x00\x00ccq\x03e.
1 # loads功能
2 # loads 将pickle数据转换为python的数据结构
3 mes = pickle.loads(p_str)
4 print(mes)
5 ['aa', 'bb', 'cc']
1 # dump功能
2 # dump 将数据通过特殊的形式转换为只有python语言认识的字符串,并写入文件
3 with open('D:/tmp.pk', 'w') as f:
4 pickle.dump(data, f)
2 # load 从数据文件中读取数据,并转换为python的数据结构
3 with open('D:/tmp.pk', 'r') as f:
4 data = pickle.load(f)
- In [2]: s = shelve.open('test.db')
- In [3]: s['x'] = ['a','b','c']
- In [4]: s['x']
- Out[4]: ['a', 'b', 'c']
- In [5]: s['x'].append('d')
- In [6]: s['x']
- Out[6]: ['a', 'b', 'c']
(1)列表['a', 'b', 'c']存储在键x下
#!/usr/bin/env python
#Author is wspikh
# -*- coding: encoding -*-
import shelve
def store_person(db):
pid = input("Enter unique ID number:")
person = {}
person['name'] = input('Enter name:')
person['age'] = input('Enter age:')
person['phone'] = input('Enter phone:')
db[pid]= person
def lookup_person(db):
pid = input("Enter ID numbers:")
field = input("What would you like to know?(name,age,phone):")
#capitalize函数将字符串的第一个字母变成大写,其他字母变小写
print(field.capitalize()+":",db[pid][field])
def print_help():
print("The avaliable commands are:")
print("store: stores information about a person")
print("lookup: looks up a person from ID number")
print("quit: save changes and exit")
print("?: prints this message")
def enter_command():
cmd = input("Enter command(? for help):")
cmd = cmd.strip().lower()
return cmd
def main():
database = shelve.open("test.db")
try:
while True:
cmd = enter_command()
if cmd == "store":
store_person(database)
elif cmd == "lookup":
lookup_person(database)
elif cmd == "?":
print_help()
elif cmd == "quit":
return
else:
print("please sure input is right!")
exit()
finally:
database.close()
if __name__ == "__main__":main()
(1)以上代码将所有内容都放到函数中会让程序更加结构化。
- /Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5 /Users/khwsp/PycharmProjects/a18/day5/shelve2.py
- Enter command(? for help):?
- The avaliable commands are:
- store: stores information about a person
- lookup: looks up a person from ID number
- quit: save changes and exit
- ?: prints this message
- Enter command(? for help):store
- Enter unique ID number:789
- Enter name:wspkh
- Enter age:44
- Enter phone:13877779999
- Enter command(? for help):?
- The avaliable commands are:
- store: stores information about a person
- lookup: looks up a person from ID number
- quit: save changes and exit
- ?: prints this message
- Enter command(? for help):lookup
- Enter ID numbers:789
- What would you like to know?(name,age,phone):age
- Age: 44
- Enter command(? for help):quit
##### ini 文件示例 ########[section1] name = wang
age = 18
[section2]name:pythonage = 19
#### 文件格式说明 #########[XXX] 代表节点XX = XX 或者 XX : XX 代表参数
import configparser # 导入模块
config = configparser.ConfigParser() # 创建对象
config.read("user.ini", encoding="utf-8") # 读取配置文件,如果配置文件不存在则创建# 查看secs = config.sections() # 获取所有的节点名称
print(secs)# ['section1', 'section2']options = config.options('section1') # 获取指定节点的所有key
print(options)# ['name', 'age']item_list = config.items('section1') # 获取指定节点的键值对
print(item_list)#[('name', 'wang'), ('age', '18')]val = config.get('section1', 'name') # 获取指定节点的指定key的value
print(val)# wangval = config.getint('section1', 'age') # 获取节点section1的age属性,属性需要是int型,否则ValueError
print(val)# 18val = config.has_section('section1') # 检查指定节点是否存在,返回True或False
print(val)# Trueval = config.has_option('section1', 'age') # 检查指定节点中是否存在某个key,返回True或False
print(val)#True# 增删改config.add_section("node") # 添加一个节点,节点名为node, 此时添加的节点node尚未写入文件config.write(open('user.ini', "w")) # 将添加的节点node写入配置文件config.remove_section("node") # 删除一个节点,节点名为node, 删掉了内存中的节点nodeconfig.write(open("user.ini", "w")) # 将删除节点node后的文件内容回写到配置文件config.set("section1", "k1", "v1") # 在已存在的节点中添加一个键值对k1 = v1 ,如果该节点不存在则报错,如果key已经存在,则修改value# configparser.NoSectionError: No section: 'section'config.write(open("user.ini", "w"))1 hash = hashlib.md5()
2 hash.update('admin'.encode('utf-8'))
3 print(hash.hexdigest())
4 21232f297a57a5a743894a0e4a801fc3
2. sha1加密
1 hash = hashlib.sha1()
2 hash.update('admin'.encode('utf-8'))
3 print(hash.hexdigest())
4 d033e22ae348aeb5660fc2140aec35850c4da997
3. sha256加密
1 hash = hashlib.sha256()
2 hash.update('admin'.encode('utf-8'))
3 print(hash.hexdigest())
4 8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
4. sha384加密
1 hash = hashlib.sha384()
2 hash.update('admin'.encode('utf-8'))
3 print(hash.hexdigest())
4 9ca694a90285c034432c9550421b7b9dbd5c0f4b6673f05f6dbce58052ba20e4248041956ee8c9a2ec9f10290cdc0782
5. sha512加密
1 hash = hashlib.sha512()
2 hash.update('admin'.encode('utf-8'))
3 print(hash.hexdigest())
4 c7ad44cbad762a5da0a452f9e854fdc1e0e7a52a38015f23f3eab1d80b931dd472634dfac71cd34ebc35d16ab7fb8a90c81f975113d6c7538dc69dd8de9077ec
6. ‘加盐’加密
以上加密算法虽然很厉害,但仍然存在缺陷,通过撞库可以反解。所以必要对加密算法中添加自定义key再来做加密。
1 ###### md5 加密 ############
2 hash = hashlib.md5('python'.encode('utf-8'))
3 hash.update('admin'.encode('utf-8'))
4 print(hash.hexdigest())
5 75b431c498b55557591f834af7856b9f
7. hmac加密
hmac内部对我们创建的key和内容进行处理后在加密
1 import hmac
2 h = hmac.new('python'.encode('utf-8'))
3 h.update('helloworld'.encode('utf-8'))
4 print(h.hexdigest())
5 b3b867248bb4cace835b59562c39fd55
8. 获取文件的MD5
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import hashlibdef md5sum(filename): """ 用于获取文件的md5值 :param filename: 文件名 :return: MD5码 """ if not os.path.isfile(filename): # 如果校验md5的文件不是文件,返回空 return myhash = hashlib.md5() f = open(filename, 'rb') while True: b = f.read(8096) if not b: break myhash.update(b) f.close() return myhash.hexdigest() |
#Author is wspikh
# -*- coding: encoding -*-
import hmac
h = hmac.new(b"wueiqi")
h.update(b"hellowo")
print(h.hexdigest())
h.update(b"wohello")
print(h.hexdigest())
#h的结果等同于h2
h2 = hmac.new(b"wueiqi")
h2.update(b"hellowowohello")
|
1
2
3
4
5
6
7
|
# subprocess用来替换多个旧模块和函数os.systemos.spawn*os.popen*popen2.*commands.* |
1. call
执行命令,返回状态码,shell = True允许shell命令时字符串形式
|
1
2
|
subprocess.check_call(["ls", "-l"])subprocess.check_call("exit 1", shell=True) |
2. check_call
执行命令,如果执行状态码是0,则返回0,否则抛出异常
|
1
2
|
subprocess.check_call(["ls", "-l"])subprocess.check_call("exit 1", shell=True) |
3. check_output
执行命令,如果状态码是0,则返回执行结果,否则抛出异常
|
1
2
|
subprocess.check_output(["echo", "Hello World!"])subprocess.check_output("exit 1", shell=True) |
4. subprocess.Popen(...)
用于执行复杂的系统命令
参数:
- args: 可以是字符串或者序列类型(如:list, tuple)。默认的,要执行的程序应该是序列的第一个字段,如果是单个字符串,它的解析依赖于平台。在unix中,如果args是一个字符串,那么这个字符串解释成被执行程序的名字或路径,然而,这种情况只能用在不需要参数的程序。
- bufsieze: 指定缓冲。0表示无缓冲,1表示缓冲,任何其他的整数值表示缓冲大小,负数值表示使用系统默认缓冲,通常表示完全缓冲。默认值为0即没有缓冲。
- stdin, stdout, stderr:分别表示程序的标准输入,输出,错误句柄
- preexec_fn : 只在unix平台有效,用于指定一个可执行对象,它将在子进程中运行之前被调用
- close_fds : 在windows平台下,如果close_fds被设置为true,则新创建的子进程将不会继承父进程的输入,输出,错误管道。所以不能将close_fds设置为true同时重定向子进程的标准输入,输出与错误。
- shell : 默认值为False, 声明了是否使用shell来执行程序,如果shell=True,它将args看做一个字符串,而不是一个序列。在unix系统中,且shell=True, shell默认使用/bin/sh。
- cwd : 用于设置子进程的当前目录。当它不为None时,子程序在执行前,它的当前路径会被替换成cwd的值。这个路径并不会被添加到可执行程序的搜索路径,所以cwd不能是相对路径。
- env : 用于指定子进程的环境变量。如果env=None,子进程的环境变量将从父进程中继承。当它不为None时,它是新进程的环境变量的映射。可以用它来代替当前进程的环境。
- universal_newlines : 不同系统的换行符不同, 文件对象stdout和stderr都被以文本文件的方式打开
- startupinfo 与 createionflags只在windows下生效。将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等
执行普通命令:
|
1
2
3
|
import subprocess
ret1 = subprocess.Popen(["mkdir","t1"])
ret2 = subprocess.Popen("mkdir t2", shell=True)
|
终端输入的命令分为两种:
- 输入即可得到输出,如:ifconfig
- 输入进行某环境,依赖在输入,如: python
|
1
2
3
|
import subprocess
obj = subprocess.Popen("mkdir t3", shell=True, cwd='/home/dev',)
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
import subprocess
obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
obj.stdin.write("print(1)\n")obj.stdin.write("print(2)")obj.stdin.close()cmd_out = obj.stdout.read()
obj.stdout.close()cmd_error = obj.stderr.read()
obj.stderr.close()print(cmd_out)print(cmd_error) |
|
1
2
3
4
5
6
7
8
|
import subprocess
obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
obj.stdin.write("print(1)\n")obj.stdin.write("print(2)")out_error_list = obj.communicate()
print(out_error_list) |
|
1
2
3
4
5
|
import subprocess
obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
out_error_list = obj.communicate('print("hello")')
print(out_error_list) |
1.简单的将日志打印到屏幕
import logging
logging.debug('This is debug message')
logging.info('This is info message')
logging.warning('This is warning message')
屏幕上打印:
WARNING:root:This is warning message
默认情况下,logging将日志打印到屏幕,日志级别为WARNING; 日志级别大小关系为:CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET,当然也可以自己定义日志级别。
2.通过logging.basicConfig函数对日志的输出格式及方式做相关配置
import logging logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%a, %d %b %Y %H:%M:%S',
filename='myapp.log',
filemode='w') logging.debug('This is debug message')
logging.info('This is info message')
logging.warning('This is warning message')
./myapp.log文件中内容为:
Sun, 24 May 2009 21:48:54 demo2.py[line:11] DEBUG This is debug message
Sun, 24 May 2009 21:48:54 demo2.py[line:12] INFO This is info message
Sun, 24 May 2009 21:48:54 demo2.py[line:13] WARNING This is warning message
logging.basicConfig函数各参数:
filename: 指定日志文件名
filemode: 和file函数意义相同,指定日志文件的打开模式,'w'或'a'
format: 指定输出的格式和内容,format可以输出很多有用信息,如上例所示:
%(levelno)s: 打印日志级别的数值
%(levelname)s: 打印日志级别名称
%(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0]
%(filename)s: 打印当前执行程序名
%(funcName)s: 打印日志的当前函数
%(lineno)d: 打印日志的当前行号
%(asctime)s: 打印日志的时间
%(thread)d: 打印线程ID
%(threadName)s: 打印线程名称
%(process)d: 打印进程ID
%(message)s: 打印日志信息
datefmt: 指定时间格式,同time.strftime()
level: 设置日志级别,默认为logging.WARNING
stream: 指定将日志的输出流,可以指定输出到sys.stderr,sys.stdout或者文件,默认输出到sys.stderr,当stream和filename同时指定时,stream被忽略
3.将日志同时输出到文件和屏幕
import logging logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%a, %d %b %Y %H:%M:%S',
filename='myapp.log',
filemode='w')##################################################################################################定义一个StreamHandler,将INFO级别或更高的日志信息打印到标准错误,并将其添加到当前的日志处理对象#
console = logging.StreamHandler()
console.setLevel(logging.INFO)
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
console.setFormatter(formatter)
logging.getLogger('').addHandler(console)################################################################################################# logging.debug('This is debug message')
logging.info('This is info message')
logging.warning('This is warning message')
屏幕上打印:
root : INFO This is info message
root : WARNING This is warning message
./myapp.log文件中内容为:
Sun, 24 May 2009 21:48:54 demo2.py[line:11] DEBUG This is debug message
Sun, 24 May 2009 21:48:54 demo2.py[line:12] INFO This is info message
Sun, 24 May 2009 21:48:54 demo2.py[line:13] WARNING This is warning message
4.logging之日志回滚
import logging
from logging.handlers importRotatingFileHandler##################################################################################################定义一个RotatingFileHandler,最多备份5个日志文件,每个日志文件最大10MRthandler=RotatingFileHandler('myapp.log', maxBytes=10*1024*1024,backupCount=5)Rthandler.setLevel(logging.INFO)
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')Rthandler.setFormatter(formatter)
logging.getLogger('').addHandler(Rthandler)################################################################################################
从上例和本例可以看出,logging有一个日志处理的主对象,其它处理方式都是通过addHandler添加进去的。
logging的几种handle方式如下:
logging.StreamHandler: 日志输出到流,可以是sys.stderr、sys.stdout或者文件
logging.FileHandler: 日志输出到文件
日志回滚方式,实际使用时用RotatingFileHandler和TimedRotatingFileHandler
logging.handlers.BaseRotatingHandler
logging.handlers.RotatingFileHandler
logging.handlers.TimedRotatingFileHandler
logging.handlers.SocketHandler: 远程输出日志到TCP/IP sockets
logging.handlers.DatagramHandler: 远程输出日志到UDP sockets
logging.handlers.SMTPHandler: 远程输出日志到邮件地址
logging.handlers.SysLogHandler: 日志输出到syslog
logging.handlers.NTEventLogHandler: 远程输出日志到Windows NT/2000/XP的事件日志
logging.handlers.MemoryHandler: 日志输出到内存中的制定buffer
logging.handlers.HTTPHandler: 通过"GET"或"POST"远程输出到HTTP服务器
由于StreamHandler和FileHandler是常用的日志处理方式,所以直接包含在logging模块中,而其他方式则包含在logging.handlers模块中, 上述其它处理方式的使用请参见python2.5手册!
5.通过logging.config模块配置日志
#logger.conf
###############################################
[loggers]
keys=root,example01,example02
[logger_root]
level=DEBUG
handlers=hand01,hand02
[logger_example01]
handlers=hand01,hand02
qualname=example01
propagate=0
[logger_example02]
handlers=hand01,hand03
qualname=example02
propagate=0
###############################################
[handlers]
keys=hand01,hand02,hand03
[handler_hand01]
class=StreamHandler
level=INFO
formatter=form02
args=(sys.stderr,)
[handler_hand02]
class=FileHandler
level=DEBUG
formatter=form01
args=('myapp.log', 'a')
[handler_hand03]
class=handlers.RotatingFileHandler
level=INFO
formatter=form02
args=('myapp.log', 'a', 10*1024*1024, 5)
###############################################
[formatters]
keys=form01,form02
[formatter_form01]
format=%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s
datefmt=%a, %d %b %Y %H:%M:%S
[formatter_form02]
format=%(name)-12s: %(levelname)-8s %(message)s
datefmt=
上例3:
import logging
import logging.config logging.config.fileConfig("logger.conf")
logger = logging.getLogger("example01") logger.debug('This is debug message')
logger.info('This is info message')
logger.warning('This is warning message')
上例4:
import logging.config
logging.config.fileConfig("logger.conf")
logger = logging.getLogger("example02")
logger.debug('This is debug message')
logger.info('This is info message')
| 语法 | 意义 | 说明 |
| "." | 任意字符 | |
| "^" | 字符串开始 | '^hello'匹配'helloworld'而不匹配'aaaahellobbb' |
| "$" | 字符串结尾 | 与上同理 |
| "*" | 0 个或多个字符(贪婪匹配) | <*>匹配<title>chinaunix</title> |
| "+" | 1 个或多个字符(贪婪匹配) | 与上同理 |
| "?" | 0 个或多个字符(贪婪匹配) | 与上同理 |
| *?,+?,?? | 以上三个取第一个匹配结果(非贪婪匹配) | <*>匹配<title> |
| {m,n} | 对于前一个字符重复m到n次,{m}亦可 | a{6}匹配6个a、a{2,4}匹配2到4个a |
| {m,n}? | 对于前一个字符重复m到n次,并取尽可能少 | ‘aaaaaa’中a{2,4}只会匹配2个 |
| "\\" | 特殊字符转义或者特殊序列 | |
| [] | 表示一个字符集 | [0-9]、[a-z]、[A-Z]、[^0] |
| "|" | 或 | A|B,或运算 |
| (...) | 匹配括号中任意表达式 | |
| (?#...) | 注释,可忽略 | |
| (?=...) | Matches if ... matches next, but doesn't consume the string. | '(?=test)' 在hellotest中匹配hello |
| (?!...) | Matches if ... doesn't match next. | '(?!=test)' 若hello后面不为test,匹配hello |
| (?<=...) | Matches if preceded by ... (must be fixed length). | '(?<=hello)test' 在hellotest中匹配test |
| (?<!...) | Matches if not preceded by ... (must be fixed length). | '(?<!hello)test' 在hellotest中不匹配test |
| 特殊序列符号 | 意义 |
| \A | 只在字符串开始进行匹配 |
| \Z | 只在字符串结尾进行匹配 |
| \b | 匹配位于开始或结尾的空字符串 |
| \B | 匹配不位于开始或结尾的空字符串 |
| \d | 相当于[0-9] |
| \D | 相当于[^0-9] |
| \s | 匹配任意空白字符:[\t\n\r\r\v] |
| \S | 匹配任意非空白字符:[^\t\n\r\r\v] |
| \w | 匹配任意数字和字母:[a-zA-Z0-9] |
| \W | 匹配任意非数字和字母:[^a-zA-Z0-9] |
re.compile(pattern[, flags])
作用:把正则表达式语法转化成正则表达式对象
flags定义包括:
re.I:忽略大小写
re.L:表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境
re.M:多行模式
re.S:’ . ’并且包括换行符在内的任意字符(注意:’ . ’不包括换行符)
re.U: 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库
更多用法可以在http://www.devexception.com/sitemap_index.xml上查找
search
re.search(pattern, string[, flags])
search (string[, pos[, endpos]])
作用:在字符串中查找匹配正则表达式模式的位置,返回 MatchObject 的实例,如果没有找到匹配的位置,则返回 None。
match
re.match(pattern, string[, flags])
match(string[, pos[, endpos]])
作用:match() 函数只在字符串的开始位置尝试匹配正则表达式,也就是只报告从位置 0 开始的匹配情况,而 search() 函数是扫描整个字符串来查找匹配。如果想要搜索整个字符串来寻找匹配,应当用 search()。
下面是几个例子:
例:最基本的用法,通过re.RegexObject对象调用
- #!/usr/bin/env python
- import re
- r1 = re.compile(r'world')
- if r1.match('helloworld'):
- print 'match succeeds'
- else:
- print 'match fails'
- if r1.search('helloworld'):
- print 'search succeeds'
- else:
- print 'search fails'
说明一下:r是raw(原始)的意思。因为在表示字符串中有一些转义符,如表示回车'\n'。如果要表示\表需要写为'\\'。但如果我就是需要表示一个'\'+'n',不用r方式要写为:'\\n'。但使用r方式则为r'\n'这样清晰多了。
例:设置flag
- #r2 = re.compile(r'n$', re.S)
- #r2 = re.compile('\n$', re.S)
- r2 = re.compile('World$', re.I)
- if r2.search('helloworld\n'):
- print 'search succeeds'
- else:
- print 'search fails'
例:直接调用
- if re.search(r'abc','helloaaabcdworldn'):
- print 'search succeeds'
- else:
- print 'search fails'
split
re.split(pattern, string[, maxsplit=0, flags=0])
split(string[, maxsplit=0])
作用:可以将字符串匹配正则表达式的部分割开并返回一个列表
例:简单分析ip
- #!/usr/bin/env python
- import re
- r1 = re.compile('W+')
- print r1.split('192.168.1.1')
- print re.split('(W+)','192.168.1.1')
- print re.split('(W+)','192.168.1.1',
1)
结果如下:
['192', '168', '1', '1']
['192', '.', '168', '.', '1', '.', '1']
['192', '.', '168.1.1']
findall
re.findall(pattern, string[, flags])
findall(string[, pos[, endpos]])
作用:在字符串中找到正则表达式所匹配的所有子串,并组成一个列表返回
例:查找[]包括的内容(贪婪和非贪婪查找)
- #!/usr/bin/env python
- import re
- r1 = re.compile('([.*])')
- print re.findall(r1,"hello[hi]heldfsdsf[iwonder]lo")
- r1 = re.compile('([.*?])')
- print re.findall(r1,"hello[hi]heldfsdsf[iwonder]lo")
- print re.findall('[0-9]{2}',"fdskfj1323jfkdj")
- print re.findall('([0-9][a-z])',"fdskfj1323jfkdj")
- print re.findall('(?=www)',"afdsfwwwfkdjfsdfsdwww")
- print re.findall('(?<=www)',"afdsfwwwfkdjfsdfsdwww")
finditer
re.finditer(pattern, string[, flags])
finditer(string[, pos[, endpos]])
说明:和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并组成一个迭代器返回。同样 RegexObject 有:
sub
re.sub(pattern, repl, string[, count, flags])
sub(repl, string[, count=0])
说明:在字符串 string 中找到匹配正则表达式 pattern 的所有子串,用另一个字符串 repl 进行替换。如果没有找到匹配 pattern 的串,则返回未被修改的 string。Repl 既可以是字符串也可以是一个函数。
例:
- #!/usr/bin/env python
- import re
- p = re.compile('(one|two|three)')
- print p.sub('num','one word two words three words
apple', 2)
re.subn(pattern, repl, string[, count, flags])
subn(repl, string[, count=0])
Python的平凡之路(5)的更多相关文章
- Python的平凡之路(8)
(本文是对平凡之路(7)的补充等) 一.动态导入模块 import importlib __import__('import_lib.metaclass') #这是解释器自己内部用的 #importl ...
- Python的平凡之路(20)
(提问复习为主) 一.Django请求的生命周期 武彦涛: 路由系统 -> 视图函数(获取模板+数据=>渲染) -> 字符串返回给用户 二.路由 ...
- Python的平凡之路(19)
一.Django请求生命周期 对于所有的web框架来说本质就是一个socket服务端,浏览器是socket客户端 ...
- Python的平凡之路(18)
一.JS 正则部分 test - 判断字符串是否符合规定的正则rep = /\d+/;rep.test("asdfoiklfasdf89asdfasdf")# truerep ...
- Python的平凡之路(16)
一.HTML+CSS补充 0.常用页面布局 <!DOCTYPE html> <html lang="en"><head> <meta ch ...
- Python的平凡之路(13)
一.Python的paramiko模块介绍 Python 的paramiko模块,该模块和SSH用于连接远程服务器并执行相关操作 SSH client 用于连接远程服务器并执行基本命令 基于用户名和密 ...
- Python的平凡之路(12)
一.数据库介绍 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库,每个数据库都有一个或多个不同的API用于创建,访问,管理,搜索和复制所保存的数据.我们也可以将数据存储在文件中,但 ...
- Python的平凡之路(11)
一. rabbitmq 1 进程Queue: 父进程与子进程进行交互,或者同属于同一父进程下多个子进程进行交互 2 队列通信: send1.py #!/usr/bin/env python#Au ...
- Python的平凡之路(10)
异步IO 数据库 队列 缓存 1.Gevent协程 定义:用户态的轻量级线程.协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下 ...
- Python的平凡之路(9)
一.Paramiko模块练习 1. Paramiko模块介绍 Paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接 2 .SSHclie ...
随机推荐
- 使用 supervisor 管理进程
安装: # yum install python-setuptools # easy_install supervisor 如果已经安装了epel和python-pip, 也可以简单 pip inst ...
- Android Layout XML属性
转载自并做少量添加:http://www.cnblogs.com/playing/archive/2011/04/07/2008620.html Layout对于迅速的搭建界面和提高界面在不同分辨率的 ...
- LA 3713 宇航员分组
题目链接:http://vjudge.net/contest/142615#problem/B 题意:有A,B,C三个人物要分配个N个宇航员,每个宇航员恰好要分配一个任务,设平均年龄为X,只有年龄大于 ...
- MariaDB链接超时优化
查看mysql server超时时间: MariaDB [(none)]> use xspeeder; MariaDB [xspeeder]> show global variables ...
- uploadify springMVC
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...
- 系统收到了多个不同的 Content-Disposition 标头。为了避免遭到 HTTP 响应拆分攻击,这种情况是不允许的。
今天使用Struts2进行上传下载的时候发现了一个现象 我的Struts2配置文件 <action name="share_ExportExcel" class=" ...
- 关于js touch事件 的引用设置
一开始做前端页面的时候,接触的也是js,但是随后便被简单高效的jquery吸引过去,并一直使用至今. 而js,则被我主观的认为底层技术而抛弃. 直到这几天工作需要,研究移动端页面的触屏滑动事件,搜索j ...
- CoreText原理及基本使用方法
关于富文本的排版也是现在的一个技术点,以下是近日关于CoreText的学习记录以及个人理解,希望能对正在学习CoreText的朋友起到帮助. 1.框架坐标系 首先让我们先来看看CoreText坐标系和 ...
- 进程、线程、socket套接字-资源大小 & 切换代价
另,进程 & 线程的很多知识可以看这里:http://www.cnblogs.com/charlesblc/p/6135666.html 今天查了一下进程和线程的资源占用. 比如问:栈和堆的大 ...
- 【转】Vim十大必备插件
[转]Vim十大必备插件 转自:http://my.oschina.net/zhoukuo/blog/336315 Taglist taglist是一个用于显示定位程序中各种符号的插件,例如宏定义.变 ...