Python学习----第二模块笔记(函数和常用模块)

1、匿名函数

没有函数名的函数,使用lambda来创建。e.g:

>>> a = lambda x:x*3
>>> a(3)
9

>>> a = lambda n:print(n)
>>> a("aaa")
aaa

a = map(lambda x: x*2, range(5))
for i in a:
    print(i)
结果:
0
2
4
6
8
#匿名函数与其他函数搭配使用

2、内置函数

内置函数

abs():返回数字的绝对值

all():判断给定的可迭代对象 iterable 中的所有元素是否不为 0、''、False 或者 iterable 为空,如果是返回 True,否则返回 False,e.g:

>>> all([])
True
#空列表
>>> all([0,1,2,3])
False
#0为False
>>> all([1,2,"",4])
False
#空元素
>>> all([1,2,3,4])
True

any():判断给定的可迭代对象 iterable 是否全部为空对象,如果都为空、0、false,则返回 False,如果不都为空、0、false,则返回 True,注意与all()的区别,e.g:

>>> any([])
False
#空列表
>>> any([0,1,2,3])
True
#一个为真即为真
>>> any([1,2,"",4])
True
>>> any([1,2,3,4])
True

ascii():类似 repr() 函数, 返回一个表示对象的字符串, 但是对于字符串中的非 ASCII 字符则返回\x, \u 或 \U 编码的字符,e.g:

>>> a = [1,2,3]
>>> ascii(a)
'[1, 2, 3]'

bin():返回一个整数的二进制,e.g:

>>> bin(10)
'0b1010'

bool():将给定参数转换为布尔类型,如果没有参数,返回 False,e.g:

>>> bool(0)
False
>>> bool(1)
True

bytearray():返回一个新字节数组。这个数组里的元素是可变的,并且每个元素的值范围: 0 <= x < 256,

  • 如果传入参数为整数,则返回一个长度为 source 的初始化数组;
  • 如果传入参数为字符串,则按照指定的 encoding 将字符串转换为字节序列;
  • 如果传入参数为可迭代类型,则元素必须为[0 ,255] 中的整数;
  • 如果传入参数为与 buffer 接口一致的对象,则此对象也可以被用于初始化 bytearray;
  • 如果没有输入任何参数,默认就是初始化数组为0个元素。

e.g:

>>> bytearray()
bytearray(b'')
>>> bytearray([1,2,3])
bytearray(b'\x01\x02\x03')
>>> bytearray('a', 'utf-8')
bytearray(b'a')

bytes():返回一个新的 bytes 对象,该对象是一个 0 <= x < 256 区间内的整数不可变序列。它是 bytearray 的不可变版本,e.g:

>>> bytes()
b''
>>> bytes([1,2,3])
b'\x01\x02\x03'
>>> bytes('a','utf-8')
b'a'

callable():检查一个对象是否是可调用,e.g:

>>> callable(1)
False
>>> def hello():
...     pass
...
>>> callable(hello)
True

chr():返回当前整数对应的ascii字符,e.g:

classmethod:类相关函数,未学

compile():将一个字符串编译为字节代码,语法如下:

compile(source, filename, mode[, flags[, dont_inherit]])

# source -- 字符串或者AST(Abstract Syntax Trees)对象
# filename -- 代码文件名称,如果不是从文件读取代码则传递一些可辨认的值
# mode -- 指定编译代码的种类。可以指定为 exec, eval, single
# flags -- 变量作用域,局部命名空间,如果被提供,可以是任何映射对象
# flags和dont_inherit是用来控制编译源码时的标志

e.g:

>>>str = "for i in range(0,5): print(i)" 
>>> c = compile(str,'','exec') 
>>> c
<code object <module> at 0x10141e0b0, file "", line 1>
>>> exec(c)
0
1
2
3
4

complex():创建一个值为 real + imag * j 的复数或者转化一个字符串或数为复数。如果第一个参数为字符串,则不需要指定第二个参数

delattr():用于删除属性,delattr(x,'name') = del x.name

dict():用于创建一个字典,e.g:

>>> dict(a=1,b=2,c=3)
{'a': 1, 'b': 2, 'c': 3}
>>> dict(a='a',b='b')
{'a': 'a', 'b': 'b'}

dir():不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时,返回参数的属性、方法列表。如果参数包含方法__dir__(),该方法将被调用。如果参数不包含__dir__(),该方法将最大限度地收集参数信息,e.g:

>>> dir([])
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

divmod():把除数和余数运算结果结合起来,返回一个包含商和余数的元组,e.g:

>>> divmod(10,3)
(3, 1)

enumerate():用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中,e.g:

>>> for i in enumerate(['a','b','c']):
...     print(i)
...
(0, 'a')
(1, 'b')
(2, 'c')

eval():用来执行一个字符串表达式,并返回表达式的值,e.g:

>>> eval('1+2')
3
>>> eval('[1,2,3]')
[1, 2, 3]

exec():执行储存在字符串或文件中的 Python 语句,相比于 eval,exec可以执行更复杂的 Python 代码,e.g:

>>> exec('for i in range(3):print(i)')
0
1
2

filter():用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。该函数接收两个参数,第一个为函数,第二个为可迭代对象,可迭代对象的每个元素作为参数传递给函数进行判,然后返回 True 或 False,最后将返回 True 的元素放到新列表中,e.g:

def is_odd(n):
    return n % 2 == 1
for i in filter(is_odd, range(10)):
    print(i)
结果:
1
3
5
7
9

float():用于将整数和字符串转换成浮点数

format():用于字符串的格式化输出,e.g:

name = "Python"
age = 28
print("{}的年龄为{}".format(name, age))
结果:
Python的年龄为28

frozenset():返回一个冻结的集合,冻结后集合不能再添加或删除任何元素

getattr():用于返回一个对象属性值

getattr(object, name[, default])
#object -- 对象
#name -- 字符串,对象属性
#default -- 默认返回值,如果不提供该参数,在没有对应属性时,将触发 AttributeError

globals():以字典类型返回当前位置的全部全局变量

hasattr():用于判断对象是否包含对应的属性,e.g:

>>> hasattr([],'append')
True
>>> hasattr([],'isdigit')
False

hash():获取取一个对象(字符串或者数值等)的哈希值,e.g:

>>> hash('a')
7807180544025395620

help():用于查看函数或模块用途的详细说明

hex():用于将10进制整数转换成16进制整数,e.g:

>>> hex(10)
'0xa'

id():用于获取对象的内存地址

input():用于获取控制台输入

int():将字符串数字转换为整型

isinstance():判断一个对象是否是一个已知的类型,e.g:

>>> isinstance(a,int)
True
>>> isinstance(a,str)
False
>>> isinstance(a,(int,str,list))
True
#是元组中的一个是返回True

issubclass():用于判断是否是子类

iter():用于生成迭代器

len():返回对象(字符、列表、元组等)长度或项目个数

list():将元组转换为列表

locals():以字典类型返回当前位置的全部局部变量

map():接收一个函数和一个列表,并通过把函数依次作用在列表的每个元素上,得到一个新的列表并返回,e.g:

>>> a = map(lambda x:x*2,range(5))
>>> for i in a:
...     print(i)
...
0
2
4
6
8

max():返回给定参数的最大值

memoryview():返回给定参数的内存查看对象(Momory view)。所谓内存查看对象,是指对支持缓冲区协议的数据进行包装,在不需要复制对象基础上允许Python代码访问

min():返回给定参数的最小值

next():返回可迭代对象的下一个值

oct():将一个整数转换成八进制

open():打开文件

ord():chr()函数的反函数

pow():返回 xy(x的y次方) 的值,e.g:

>>> pow(1,2)
1

print():打印输出

property() :在新式类中返回属性值

range():创建整数列表

repr():将对象转化为供解释器读取的字符串形式,e.g:

>>> a = {'a':1,'b':2}
>>> repr(a)
"{'a': 1, 'b': 2}"

reversed():反转可迭代对象,e.g:

>>> a = [1,2,3]
>>> list(reversed(a))
[3, 2, 1]

round():返回浮点数的四舍五入值

set():创建一个集合

setattr():对应函数getatt()用于设置属性值,该属性必须存在

slice():实现切片对象,主要用在切片操作函数里的参数传递,e.g:

>>> a = [1,2,3,4,5]
>>> myslice = slice(2)
>>> a[myslice]
[1, 2]

sorted():对可迭代对象排序

staticmethod():返回函数的静态方法

str():将对象转换成始于人阅读的字符串形式

sum():对可迭代对象求和,e.g:

>>> sum([1,2,3])
6

super():函数用于调用下一个父类(超类)并返回该父类实例的方法。super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。MRO 就是类的方法解析顺序表, 其实也就是继承父类方法时的顺序表

tuple():将列表转换成元组

type():返回对象的数据类型,e.g:

>>> type(1)
<class 'int'>
>>> type('1')
<class 'str'>

vars():返回对象的属性和属性值的字典对象

zip():用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表,e.g:

>>> a = [1,2,3]
>>> b = [4,5,6]
>>> list(zip(a,b))
[(1, 4), (2, 5), (3, 6)]

__import__():用于动态加载类和函数 。如果一个模块经常变化就可以使用 __import__() 来动态载入

3、装饰器

decorator,本质上是一个函数,用于装饰其他函数,为其他函数添加新的功能。

装饰器需要遵循以下原则:

  • 不能修改被装饰函数的源代码
  • 不能修改被装饰函数的调用方式

装饰器需要知识:

  • 函数即“变量”,函数名 = 函数体,必须先声明再调用
  • 高阶函数,满足以下条件之一 

               a.把一个函数名当作实参传给另一个函数(实现在不修改被装饰函数源代码的情况下为其添加新功能)

               b.返回值中包含函数(实现不修改函数的调用方式)

  • 嵌套函数,在一个函数的函数体内用def声明一个新的函数
  • 闭包,在一个内部函数里,对在外部作用域(不是全局作用域)的变量进行引用,这个内部函数就是闭包(closure)

装饰器 = 高阶函数+嵌套函数+闭包

def test():
    print("测试函数!")

print(test)
print(test())

#结果(注意调用函数带括号与不带括号时的区别)
<function test at 0x000001D23579AEA0>    # 不带括号指向函数的内存地址
测试函数!    # 带括号执行函数
None    # 函数的返回值,无return语句返回None

e.g:

#函数带一个参数例子
#未加装饰器
def test1(name):
    print("你的名字%s" % name)

test1("Python")
#结果
你的名字Python

#加上装饰器
def deco(func):
    def test(x):
        print("装饰器例子。")
        func(x)
        print("结束。")
    return test


@deco
def test1(name):
    print("你的名字%s" % name)

test1("Python")
#结果
装饰器例子。
你的名字Python
结束。
#函数带多个参数
def deco(func):
    def test(*args, **kwargs):
        print("装饰器例子。")
        func(*args, **kwargs)
        print("结束。")
    return test


@deco
def test1(name, age):
    print("你的名字%s,你的年龄%s" % (name, age))

test1("Python", 28)
#结果
装饰器例子。
你的名字Python,你的年龄28
结束。
#带参数的装饰器
def deco(x):
    def test(func):
        def test1(*args, **kwargs):
            print("装饰器例子。")
            func(*args, **kwargs)
            print("结束。看看带参数的装饰器%s" % x)
        return test1
    return test


@deco(1)
def test2(name, age):
    print("你的名字%s,你的年龄%s" % (name, age))

test2("Python", 28)
#结果
装饰器例子。
你的名字Python,你的年龄28
结束。看看带参数的装饰器1
def login(func):
    def deco(*args, **kwargs):
        func(*args, **kwargs)
        name, pw = "abc", "abc123"
        username = input("请输入用户名-->")
        password = input("请输入密码-->")
        if username == name and password == pw:
            print("欢迎%s回来!" % username)
        else:
            print("用户名或密码错误!")
    return deco


def welcome():
    print("欢迎你的到来!")


@login
def user():
    print("请登录-->")

welcome()

user()
#结果
欢迎你的到来!
请登录-->
请输入用户名-->abc
请输入密码-->abc123
欢迎abc回来!

4、列表生成式

生成列表,可以使代码更整洁,e.g:

>>> a = [i*2 for i in range(5)]
>>> a
[0, 2, 4, 6, 8]
#生成一个列表,列表成员为0-4依次乘于2

5、生成器

受内存限制,列表的容量有限,创建大量元素的列表需要的存储空间巨大,而且列表的元素是固定存在的,如果只访问前面的元素,那么后面的元素占用的空间就浪费了。

生成器generator,一边循环一边计算的机制,只在调用时才生成相应的数据,只记住当前值,无法返回前面的值,只能下一个,将列表生成式的[]换成()就可以创建一个生成器,e.g:

>>> a = (i*2 for i in range(5))
>>> next(a)
0
>>> next(a)
2
>>> next(a)
4
#使用next()函数调用下一个值
>>> for i in a:
...     print(i)
...
6
8
#通过for循环调用,注意输出结果,因为已经使用next()函数调用了三个值,所以for循环只输出了最后两个值

#另外一种next使用方法
>>> a = (i*2 for i in range(5))
>>> a.__next__()
0
>>> a.__next__()
2
>>> a.__next__()
4
#使用函数创建生成器

#原函数
def test():
    for i in range(4):
        print(i)
        
test()
#结果
0
1
2
3

#创建生成器
def test():
    for i in range(4):
        yield i

data = test()

print(next(data))
print(next(data))
print(next(data))
print(next(data))
#结果
0
1
2
3
#生成器并行运算

def test(name):
    while True:
        yield
        print("他的名字是%s" % name)


def test1(name):
    a = test("JAVA")
    a.__next__()
    for i in range(3):
        print("我的名字是%s" % name)
        a.send(i)     # 回到上次yield中断的地方

test1("Python")
#结果
我的名字是Python
他的名字是JAVA
我的名字是Python
他的名字是JAVA
我的名字是Python
他的名字是JAVA

6、迭代器

可迭代对象(Iterable):所以可以直接作用于for循环的对象,如列表、字典、生成器等

迭代器(Iterator):可以被next()函数调用并不断返回下一个值的对象,惰性计算序列,只有在需要返回值的时候才进行计算

#可以使用isinstance()函数判断是否是可迭代对象或者迭代器

#可以使用for循环的都是可迭代对象
>>> from collections import Iterable
>>> isinstance([],Iterable)
True
>>> isinstance({},Iterable)
True
>>> isinstance((i*2 for i in range(5)),Iterable)
True

#列表、字典无法使用next()函数,所以不是迭代器
>>> from collections import Iterator
>>> isinstance([],Iterator)
False
>>> isinstance({},Iterator)
False

#生成器可以使用next()函数,所以是迭代器
>>> isinstance((i*2 for i in range(5)),Iterator)
True
#使用iter()函数可以把一个可迭代对象转换成迭代器
>>> from collections import Iterator
>>> isinstance(iter([]),Iterator)
True

7、软件目录开发规范

Foo/
|-- bin/    #存放项目的一些可执行文件
|   |-- foo.py    #程序执行文件,调用main.py文件实现各种功能
|
|-- foo/    #存放项目的所有源代码(1) 源代码中的所有模块、包都应该放在此目录,不要置于顶层目录;(2) 其子目录tests/存放单元测试代码; (3) 程序的入口最好命名为main.py。
|   |-- tests/
|   |   |-- __init__.py
|   |   |-- test_main.py
|   |
|   |-- __init__.py
|   |-- main.py    #程序的主入口,负责调用其他模块
|
|-- docs/       #存放一些文档
|
|-- conf/    #存放配置文件
|   |--conf.py
|
|-- setup.py    #安装、部署、打包的脚本
|-- requirements.txt    #存放软件依赖的外部Python包列表
|-- README

8、Python模块及import的本质

模块在本质上是.py文件,用来从逻辑上组织python代码,以实现某个功能

包在本质上是一个带有__init__.py文件的目录,用来从逻辑上组织模块。导入包的本质即解释目录下的__init__.py文件。

模块的导入方法

import xxx

from xxx import xxx

from xxx import xxx as xxx
#as可以将原模块名在导入的时候定义一个新名称

import在本质上就是把import的模块中的代码解释一遍并赋值给模块名

模块的分类:

  • 标准库(内置模块)
  • 开源模块(第三方模块)
  • 自定义模块(自己写的模块)
#不同目录间模块调用
#使用os,sys模块的功能
#目录结构如下
|--a/
|  |--aa/
|     |--aaa.py
|
|  |--bb/
|     |--bbb.py
#在aaa.py中需要调用bbb.py

os.path.abspath(__file__)    #返回当前文件的绝对路径,在这里为a/aa/aaa.py
os.path.dirname()   #返回当前文件所在的目录
os.path.dirname(os.path.abspath(__file__))   #这里为a/aa
os.path.dirname(os.path.dirname(os.path.abspath(__file__)))    #这里为a,已经可以找到bb了
sys.path.append()    #将路径加入python搜索模块的路径列表中

#代码如下
import os
import sys
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_dir)
from bb import bbb
bbb.xxx()#调用bbb下的xxx方法

9、Python标准库(内置模块)

9.1、time和date time模块

Python中表示时间的方式:

  • 时间戳,表示从1970年1月1日00:00:00开始按秒计算的偏移量
  • 格式化的时间字符串
  • 元组(struct_time),共九个元素

UTC(世界协调时),格林威治时间,世界标准时间。中国位于东八区,即UTC+8

import time

#time.process_time()(time.clock()) 测量处理器运算时间,不包括sleep的时间,e.g:
>>> time.process_time()
0.109375

#time.time() 返回当前时间戳,e.g:
>>> time.time()
1508682933.4166296

#time.altzone 返回格林威治西部的夏令时地区的偏移秒数,如果该地区在格林威治东部会返回负值(如西欧,包括英国),对夏令时启用地区才能使用,e.g:
>>> time.altzone
-32400

#time.asctime() 接受struct_time并返回时间格式“Sun Oct 22 22:40:53 2017”,e.g:
>>> time.asctime(time.localtime())
'Sun Oct 22 22:43:34 2017'

#time.localtime() 返回本地时间的struct_time,e.g:
>>> time.localtime()
time.struct_time(tm_year=2017, tm_mon=10, tm_mday=22, tm_hour=22, tm_min=45, tm_sec=48, tm_wday=6, tm_yday=295, tm_isdst=0)

#time.gmtime() 返回UTC时间的struct_time,e.g:
>>> time.gmtime()
time.struct_time(tm_year=2017, tm_mon=10, tm_mday=22, tm_hour=14, tm_min=47, tm_sec=12, tm_wday=6, tm_yday=295, tm_isdst=0)

#time.ctime() 同time.asctime(),e.g:
>>> time.ctime()
'Sun Oct 22 22:49:55 2017'

#time.strptime 将日期字符串转成struct_time,e.g:
>>> time.strptime("2017/01/22","%Y/%m/%d")
time.struct_time(tm_year=2017, tm_mon=1, tm_mday=22, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=6, tm_yday=22, tm_isdst=-1)

#time.mktime() 将struct_time转成时间戳,e.g:
>>> time.mktime(time.localtime())
1508684200.0

#time.strftime() 将struct_time转成指定的字符串格式,e.g:
>>> time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
'2017-10-22 22:59:33'
#格式:
# %a    本地(locale)简化星期名称    
# %A    本地完整星期名称    
# %b    本地简化月份名称    
# %B    本地完整月份名称    
# %c    本地相应的日期和时间表示    
# %d    一个月中的第几天(01 - 31)    
# %H   一天中的第几个小时(24小时制,00 - 23)    
# %I     第几个小时(12小时制,01 - 12)    
# %j     一年中的第几天(001 - 366)    
# %m   月份(01 - 12)    
# %M   分钟数(00 - 59)    
# %p    本地am或者pm的相应符
# %S    秒(01 - 61)
# %U    一年中的星期数。(00 - 53星期天是一个星期的开始。)第一个星期天之前的所有天数都放在第0周。
# %w    一个星期中的第几天(0 - 6,0是星期天)
# %W   和%U基本相同,不同的是%W以星期一为一个星期的开始。    
# %x     本地相应日期    
# %X    本地相应时间    
# %y     去掉世纪的年份(00 - 99)    
# %Y    完整的年份    
# %Z    时区的名字(如果不存在为空字符)    
# %%    ‘%’字符
#时间加减
import datetime

#datetime.datetime.now() 
>>> print(datetime.datetime.now())
2017-10-22 23:13:54.766792

#datetime.date.fromtimestamp() 时间戳直接转成日期格式
>>>>>> print(datetime.date.fromtimestamp(time.time()))
2017-10-22

#当前时间+3天
>>> print(datetime.datetime.now() + datetime.timedelta(3))
2017-10-25 23:14:43.124703

#当前时间-3天
>>> print(datetime.datetime.now() + datetime.timedelta(-3))
2017-10-19 23:15:31.525936

#当前时间+3小时
>>> print(datetime.datetime.now() + datetime.timedelta(hours=3))
2017-10-23 02:17:01.242468

#当前时间+30分钟
>>> print(datetime.datetime.now() + datetime.timedelta(minutes=30))
2017-10-22 23:47:34.411346

#时间替换
>>> c_time  = datetime.datetime.now()
>>> print(c_time)
2017-10-22 23:19:10.420363
>>> print(c_time.replace(minute=3,hour=2))
2017-10-22 02:03:10.420363

time

9.2、random模块

用于生成一个随机数

import random

#random.random() 生成一个0到1的随机浮点数,e.g:
>>> random.random()
0.11953524555173556
>>> random.random()
0.43441252324763446
>>> random.random()
0.2674464150139263

#random.randint() 生成一个指定范围的随机整数,e.g:
>>> random.randint(2,9)
8
>>> random.randint(2,9)
3
>>> random.randint(2,9)
8

#random.randrange() 从指定范围内,按指定基数递增的集合中获取一个随机数,e.g:
>>> random.randrange(0,20,2)
4
>>> random.randrange(0,20,2)
2
>>> random.randrange(0,20,2)
12

#random.choice() 从序列中获取一个随机元素,e.g:
>>> random.choice("I am Python")
'I'
>>> random.choice("I am Python")
' '
>>> random.choice("I am Python")
'y'
>>> random.choice([1,3,5,7,9])
5
>>> random.choice([1,3,5,7,9])
7
>>> random.choice([1,3,5,7,9])
3

#random.sample() 从指定序列中随机获取指定长度的片段,e.g:
>>> random.sample([1,3,5,7,9,11,13,15,17,19],3)
[7, 19, 15]
>>> random.sample([1,3,5,7,9,11,13,15,17,19],3)
[9, 7, 15]
>>> random.sample([1,3,5,7,9,11,13,15,17,19],3)
[11, 9, 3]

9.3、os模块和sys模块

#os模块
import os

#os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径,e.g:
>>> os.getcwd()
'C:\\Users\\MAIMAI'

#os.chdir() 改变当前脚本工作目录,e.g:
>>> os.chdir(r"d:")
>>> os.getcwd()
'D:\\'

#os.curdir 返回当前目录: ('.'),e.g:
>>> os.curdir
'.'

#os.pardir  获取当前目录的父目录字符串名:('..'),e.g:
>>> os.pardir
'..'

#os.makedirs() 可生成多层递归目录,e.g:
>>> os.makedirs(r"d:\a\b\c")

#os.removedirs() 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推

#os.mkdir() 生成单级目录,e.g:
>>> os.mkdir(r"d:\d")
>>> os.mkdir(r"d:\f\d")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
FileNotFoundError: [WinError 3] 系统找不到指定的路径。: 'd:\\f\\d'    # 只能生成单级目录,上级目录不存在时报错

#os.rmdir() 删除单级空目录,若目录不为空则无法删除,报错

#os.listdir() 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印,e.g:
>>> os.listdir(r"d:\a")
['b', 'c', 'd']

#os.remove() 删除一个文件

#os.rename() 重命名文件/目录,e.g:
>>> os.listdir(r"d:\a")
['b', 'c', 'd']
>>> os.rename(r"d:\a\b",r"d:\a\e")
>>> os.listdir(r"d:\a")
['c', 'd', 'e']

#os.stat() 获取文件/目录信息,e.g:
>>> os.stat(r"d:\a")
os.stat_result(st_mode=16895, st_ino=11821949021849245, st_dev=520988, st_nlink=1, st_uid=0, st_gid=0, st_size=0, st_atime=1508687570, st_mtime=1508687570, st_ctime=1508687154)

#os.sep 输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/"

#os.linesep 输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"

#os.pathsep 输出用于分割文件路径的字符串

#os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix'

#os.system() 运行shell命令,直接显示,e.g:
>>> os.system("ping www.baidu.com")

正在 Ping www.a.shifen.com [183.232.231.173] 具有 32 字节的数据:
来自 183.232.231.173 的回复: 字节=32 时间=23ms TTL=52
来自 183.232.231.173 的回复: 字节=32 时间=22ms TTL=52
来自 183.232.231.173 的回复: 字节=32 时间=21ms TTL=52
来自 183.232.231.173 的回复: 字节=32 时间=24ms TTL=52

183.232.231.173 的 Ping 统计信息:
    数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
    最短 = 21ms,最长 = 24ms,平均 = 22ms
0

#os.environ 获取系统环境变量

#os.path.abspath() 返回规范化的绝对路径

#os.path.split() 将路径分割成目录和文件名二元组返回,e.g:
>>> os.path.split(r"d:\a")
('d:\\', 'a')

#os.path.dirname() 返回文件所在的目录,其实就是os.path.split()的第一个元素

#os.path.basename() 返回目录/文件最后的名称,如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素,e.g:
>>> os.path.basename(r"d:\a")
'a'

#os.path.exists() 存在,返回True;不存在,返回False,e.g:
>>> os.path.exists(r"d:\a")
True

#os.path.isabs() 如果是绝对路径,返回True,e.g:
>>> os.path.isabs(r"d:\a")
True

#os.path.isfile()  如果是一个存在的文件,返回True,否则返回False,e.g:
>>> os.path.isfile(r"d:\a")
False
>>> os.path.isfile(r"d:\a\a.txt")
True

#os.path.isdir() 如果是一个存在的目录,则返回True,否则返回False,e.g:
>>> os.path.isdir(r"d:\a")
True

#os.path.join() 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略,e.g:
>>> os.path.join(r"d:",r"\a",r"b",r"c")
'd:\\a\\b\\c'

#os.path.getatime() 返回所指向的文件或者目录的最后存取时间

#os.path.getmtime() 返回所指向的文件或者目录的最后修改时间

os模块补充

#os.walk() os.walk() 方法用于通过在目录树种游走输出在目录中的文件名,向上或者向下。
#os.walk(top[, topdown=True[, onerror=None[, followlinks=False]]])
#top -- 根目录下的每一个文件夹(包含它自己), 产生3-元组 (dirpath, dirnames, filenames)【文件夹路径, 文件夹名字[列表], 文件名[列表]】。
#topdown --可选,为True或者没有指定, 一个目录的的3-元组将比它的任何子文件夹的3-元组先产生 (目录自上而下)。如果topdown为 False, 一个目录的3-元组将比它的任何子文件夹的3-元组后产生 (目录自下而上)。
#onerror -- 可选,是一个函数; 它调用时有一个参数, 一个OSError实例。报告这错误后,继续walk,或者抛出exception终止walk。
#followlinks -- 设置为 true,则通过软链接访问目录。
#e.g:
for dirpath, dirname, filename in os.walk(r"f:"):
    print(dirpath, dirname, filename)
sys模块

import sys

#sys.argv 命令行参数List,第一个元素是程序本身路径,e.g:
import sys
print(sys.argv[1:])
--->test.py
f:\python>python test.py 1 2 3
['1', '2', '3']

#sys.exit() 引发一个 SystemExit异常,若没有捕获这个异常,Python解释器会直接退出,捕获这个异常可以做一些额外的清理工作。0为正常退出,其他数值(1-127)为不正常,可抛异常事件供捕获

#sys.version 获取Python解释器的版本信息
>>> sys.version
'3.6.2 (v3.6.2:5fd33b5, Jul  8 2017, 04:57:36) [MSC v.1900 64 bit (AMD64)]'

#sys.path 返回列表形式的模块的搜索路径,

#sys.platform 返回操作系统的名称

#sys.stdout.write 输出,类似print

9.4、shutil模块

高级的文件、文件夹、压缩包处理模块

import shutil

#shutil.copyfileobj(fsrc, fdst[, length]) 将文件内容拷贝到另一个文件中,可以部分内容,需要先用open打开文件

#shutil.copyfile(src, dst) 拷贝文件,不用先open

#shutil.copymode(src, dst) 仅拷贝权限,内容、组、用户均不变

#shutil.copystat(src, dst) 拷贝状态的信息,包括权限、组、用户、时间等

#shutil.copy(src, dst) 拷贝文件和仅权限

#shutil.copy2(src, dst) 拷贝文件和文件的所有状态信息

#shutil.ignore_patterns(*patterns)
#shutil.copytree(src, dst, symlinks=False, ignore=None) 递归的去拷贝文件
#e.g:copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*'))

#shutil.rmtree(path[, ignore_errors[, onerror]]) 递归的去删除文件

#shutil.move(src, dst) 递归的去移动文件

#shutil.make_archive(base_name, format,...) 创建压缩包并返回文件路径
# base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径
#  format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
#  root_dir: 要压缩的文件夹路径(默认当前目录)
#  owner: 用户,默认当前用户
#  group: 组,默认当前组
# logger: 用于记录日志,通常是logging.Logger对象

9.5、json、pickle和shelve模块

json模块用来编码和解码JSON对象,只支持简单的数据类型,如列表、字典等

import json

#json.dumps 将Python对象编码成JSON字符串
#json.loads 将JSON字符串解码成Python对象

#json.dump 将Python对象编码成JSON字符串并写入文件
#json.load 从文件中读取JSON字符串并解码成Python对象

#json只支持简单的数据类型,如列表、字典等

pickle模块用于python特有的类型和python的数据类型间进行转换,可序列化python所有数据类型

import pickle

#pickle.dumps 序列化
#pickle.loads 反序列化

#pickle.dump 写入文件
#pickle.load 从文件中读取

#存储的是二进制文件,open文件时应该使用rb、wb、ab模式

shelve模块通过键值对的形式对内存数据进行文件持久化的模块,可以持久化任何pickle可支持的python数据格式,e.g:

import shelve

a = [1, 2, 3]

f = shelve.open("test")
f["test"] = a
f.close()
#将列表持久化保存
f1 = shelve.open("test")
print(f1["test"])
f1.close()
#通过键从文件中读取列表

#结果
[1, 2, 3]

9.6、xml处理模块

用于处理xml文件,需导入xml.etree.ElementTree模块。

#以下是一个xml文件的内容

<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank updated="yes">5</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank updated="yes">69</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>
#xml文件的读取

import xml.etree.ElementTree as xml_ET  # 模块名太长,改个名

tree = xml_ET.parse("test.xml")
root = tree.getroot()   # <data></data>包起来的内容
print(root.tag)    # 打印root标签

#结果
data
import xml.etree.ElementTree as xml_ET  # 模块名太长,改个名

tree = xml_ET.parse("test.xml")
root = tree.getroot()   # <data></data>包起来的内容

for child in root:    # 遍历整个xml文件
    print(child.tag, child.attrib)    #读取标签及属性

#结果
country {'name': 'Liechtenstein'}
country {'name': 'Singapore'}
country {'name': 'Panama'}

import xml.etree.ElementTree as xml_ET  # 模块名太长,改个名

tree = xml_ET.parse("test.xml")
root = tree.getroot()   # <data></data>包起来的内容

for child in root:    # 遍历整个xml文件
    for i in child:    # 遍历<country></country>包起来的内容
        print(i.tag, i.text)    # 读取标签及标签包起来的内容

#结果
rank 2
year 2008
gdppc 141100
neighbor None
neighbor None
rank 5
year 2011
gdppc 59900
neighbor None
rank 69
year 2011
gdppc 13600
neighbor None
neighbor None

import xml.etree.ElementTree as xml_ET  # 模块名太长,改个名

tree = xml_ET.parse("test.xml")
root = tree.getroot()   # <data></data>包起来的内容

for node in root.iter("year"):  # 只遍历year节点
    print(node.tag, node.text)     # 打印标签及标签包起来的内容

#结果
year 2008
year 2011
year 2011
#xml文件的修改

import xml.etree.ElementTree as xml_ET

tree = xml_ET.parse("test.xml")
root = tree.getroot()

for node in root.iter("year"):    # 修改year节点
    new_year = int(node.text) + 1
    node.text = str(new_year)
    node.set("updated", "yes")    # <year>标签修改成<year updated="yes">

tree.write("test.xml")    # 修改内容写入xml文件

# 删除node
for country in root.findall("country"):
    rank = int(country.find("rank").text)   # 读取<rank></rank>中的内容
    if rank > 50:
        root.remove(country)    # 删除符合条件的country

tree.write("output.xml")
#创建xml文件

import xml.etree.ElementTree as xml_ET

new_xml = xml_ET.Element("namelist")    # 大标签
name = xml_ET.SubElement(new_xml, "name", attrib={"enrolled": "yes"})   # 大标签下的子标签及子标签属性
age = xml_ET.SubElement(name, "age", attrib={"checked": "no"})
sex = xml_ET.SubElement(name, "sex")
sex.text = '33'   # <sex>中的内容
name2 = xml_ET.SubElement(new_xml, "name", attrib={"enrolled": "no"})
age = xml_ET.SubElement(name2, "age")
age.text = '19'

et = xml_ET.ElementTree(new_xml)  # 生成文档对象
et.write("test1.xml", encoding="utf-8", xml_declaration=True)   # 写入文件并打上xml标志

xml_ET.dump(new_xml)  # 打印生成的格式

9.7、PyYAML和configparser模块

PyYAML模块用来处理ymal文档格式,具体用法参照http://pyyaml.org/wiki/PyYAMLDocumentation 

configparser模块用于创建和修改常用的配置文件。

#以下是一个配置文件的内容

[DEFAULT]
ServerAliveInterval = 45
Compression = yes
CompressionLevel = 9
ForwardX11 = yes
 
[bitbucket.org]
User = hg
 
[topsecret.server.com]
Port = 50022
ForwardX11 = no
#创建配置文件

import configparser

config = configparser.ConfigParser()

config["DEFAULT"] = {'ServerAliveInterval': '45',
                     'Compression': 'yes',
                     'CompressionLevel': '9'}

config['bitbucket.org'] = {}
config['bitbucket.org']['User'] = 'hg'

config['topsecret.server.com'] = {}
topsecret = config['topsecret.server.com']
topsecret['Host Port'] = '50022'
topsecret['ForwardX11'] = 'no'
config['DEFAULT']['ForwardX11'] = 'yes'
with open('example.ini', 'w') as configfile:
    config.write(configfile)
# 实质上就是对字典的操作
#读取配置文件

import configparser

config = configparser.ConfigParser()
print(config.read("example.ini"))
print(config.sections())
print(config.options("bitbucket.org"))
print(config.items("bitbucket.org"))    # 输出列表形式的键值对
print(config.get("bitbucket.org", "compression"))   # 输出字符串
print(config.getint("bitbucket.org", "compressionlevel"))   # 输出int
print(config["bitbucket.org"]["user"])

#结果
['example.ini']
['bitbucket.org', 'topsecret.server.com']
['user', 'serveraliveinterval', 'compression', 'compressionlevel', 'forwardx11']
[('serveraliveinterval', '45'), ('compression', 'yes'), ('compressionlevel', '9'), ('forwardx11', 'yes'), ('user', 'hg')]
yes
9
hg
#修改配置文件

import configparser

config = configparser.ConfigParser()
config.read("example.ini")    # 必须先读取配置文件

config.add_section("baidu.com")    # 新建

config.set("topsecret.server.com", "forwardx11", "yes")    # 修改

config.remove_option("topsecret.server.com", "Port")   # 删除

config.remove_section("topsecret.server.com")

config.write(open("example.ini", "w"))    # 修改内容写入配置文件

#检查一个section是否存在
import configparser

config = configparser.ConfigParser()
config.read("example.ini")

print(config.has_section("baidu.com"))

#结果
True

9.8、hashlib模块

用于加密的模块,提供了SHA1,SHA224,SHA256,SHA384,SHA512,MD5 算法,e.g:

import hashlib

m_b = hashlib.md5()
m_b.update(b"I am Python")    # 直接传入字符串报错,需转编码
print(m_b.hexdigest())    # 十六进制输出
m_utf8 = hashlib.md5()
m_utf8.update("I am Python".encode("utf-8"))    # 转utf-8
print(m_utf8.hexdigest())

b = hashlib.sha1()
b.update(b"I am Python")
print(b.hexdigest())

zh_cn = hashlib.md5()
zh_cn.update("我是Python".encode("utf-8"))    # 中文直接传utf-8
print(zh_cn.hexdigest())

#结果
563f710d7f1020c8ee1c95f77650918a
563f710d7f1020c8ee1c95f77650918a
a1780aaa27454ce0a9ee7a7518405d8c72523843
c46b544b85b64a0a45c6081e2fbacbaf

hmac模块可对自定义的key和内容进行处理后再加密,e.g:

import hmac

a = hmac.new("我是Python".encode("utf-8"), "我是Python2".encode("utf-8"))
print(a.hexdigest())

#结果
deb7cd3a5ac6169c841fdaaf8b10f384

9.9、logging模块

logging模块提供标准的日志接口,可存储各种格式的日志,logging的日志分为debug、info、warning、error、critical五个级别 ,

  • DEBUG:详细的信息,通常只出现在诊断问题上
  • INFO:确认一切按预期运行
  • WARNING:一个迹象表明,一些意想不到的事情发生了,或表明一些问题在不久的将来(例如。磁盘空间低”)。这个软件还能按预期工作。
  • ERROR:更严重的问题,软件没能执行一些功能
  • CRITICAL:一个严重的错误,这表明程序本身可能无法继续运行
import logging

logging.debug("debug")
logging.info("info")
logging.warning("warning")
logging.error("error")
logging.critical("critical")

#结果
WARNING:root:warning
ERROR:root:error
CRITICAL:root:critical
#报警按级别显示,debug、info默认不显示

logging.basicConfig(filename='test.log',level=logging.INFO) 
#将日志写入文件,level定义记录的日志级别,低于该级别的日志不被记录

logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
#为日志加上一些格式

#日志格式具体如下
# %(name)s               Logger的名字
# %(levelno)s            数字形式的日志级别
# %(levelname)s          文本形式的日志级别
# %(pathname)s           调用日志输出函数的模块的完整路径名,可能没有
# %(filename)s           调用日志输出函数的模块的文件名
# %(funcName)s           调用日志输出函数的函数名
# %(lineno)d             调用日志输出函数的语句所在的代码行
# %(created)f            当前时间,用UNIX标准的表示时间的浮点数表示
# %(relativeCreated)d    输出日志信息时的,自Logger创建以来的毫秒数
# %(asctime)s            字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
# %(thread)d             线程ID。可能没有
# %(threadName)s         线程名。可能没有
# %(process)d            进程ID。可能没有
# %(message)s            用户输出的消息

Python 使用logging模块记录日志涉及四个主要类:

  • logger提供了应用程序可以直接使用的接口
  • handler将(logger创建的)日志记录发送到合适的目的输出
  • filter提供了细度设备来决定输出哪条日志记录
  • formatter决定日志记录的最终输出格式
logger

每个程序在输出信息之前都要获得一个Logger,Logger通常对应了程序的模块名

logging.getLogger():获得一个Logger

Logger.setLevel():指定最低的日志级别,低于设置的级别将被忽略

Logger.addFilter()、Logger.removeFilter():添加或删除指定的filter

Logger.addHandler()、Logger.removeHandler():增加或删除指定的handler

Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical():可以设置的日志级别

handler

handler对象负责发送相关的信息到指定目的地。Python的日志系统有多种Handler可以使用。有些Handler可以把信息输出到控制台,有些Handler可以把信息输出到文件,还有些 Handler可以把信息发送到网络上。如果觉得不够用,还可以编写自己的Handler。可以通过addHandler()方法添加多个多handler

Handler.setLevel():指定被处理的信息级别,低于设置级别的信息将被忽略
Handler.setFormatter():给这个handler选择一个格式
Handler.addFilter()、Handler.removeFilter():新增或删除一个filter对象

常用Handler:

1、logging.StreamHandler,使用这个Handler可以向类似与sys.stdout或者sys.stderr的任何文件对象(file object)输出信息。它的构造函数是:StreamHandler([strm]),其中strm参数是一个文件对象。默认是sys.stderr。

2、logging.FileHandler,和StreamHandler类似,用于向一个文件输出日志信息。FileHandler会帮你打开这个文件。它的构造函数是:FileHandler(filename[,mode]),filename是文件名,必须指定一个文件名。mode是文件的打开方式,默认是“a”,即添加到文件末尾。

3、logging.handlers.RotatingFileHandler,这个Handler类似于上面的FileHandler,但是它可以管理文件大小。当文件达到一定大小之后,它会自动将当前日志文件改名,然后创建一个新的同名日志文件继续输出。比如日志文件是chat.log。当chat.log达到指定的大小之后,RotatingFileHandler自动把文件改名为chat.log.1。不过,如果chat.log.1已经存在,会先把chat.log.1重命名为chat.log.2。。。最后重新创建 chat.log,继续输出日志信息。它的构造函数是:RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]]),其中filename和mode两个参数和FileHandler一样。maxBytes用于指定日志文件的最大文件大小。如果maxBytes为0,意味着日志文件可以无限大,这时上面描述的重命名过程就不会发生。backupCount用于指定保留的备份文件的个数。比如,如果指定为2,当上面描述的重命名过程发生时,原有的chat.log.2并不会被更名,而是被删除。
4、logging.handlers.TimedRotatingFileHandler,这个Handler和RotatingFileHandler类似,不过,它没有通过判断文件大小来决定何时重新创建日志文件,而是间隔一定时间就 自动创建新的日志文件。重命名的过程与RotatingFileHandler类似,不过新的文件不是附加数字,而是当前时间。它的构造函数是:TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]]),其中filename参数和backupCount参数和RotatingFileHandler具有相同的意义,interval是时间间隔,when参数是一个字符串。表示时间间隔的单位,不区分大小写。它有以下取值:
S 秒
M 分
H 小时
D 天
W 每星期(interval==0时代表星期一)
midnight 每天凌晨

e.g:

import logging

logger = logging.getLogger("TESE")
logger.setLevel(logging.DEBUG)
# 获得一个logger并定义记录级别

screen = logging.StreamHandler()
screen.setLevel(logging.DEBUG)
# 定义一个屏幕输出Handler并定义记录级别

file = logging.FileHandler("test.log")
file.setLevel(logging.DEBUG)
# 定义一个文件输出Handler并定义记录级别

formatter = logging.Formatter("%(asctime)s-%(levelname)s-%(filename)s")
# 定义一个日志记录格式

screen.setFormatter(formatter)
file.setFormatter(formatter)
# 为Handler指定记录格式

logger.addHandler(screen)
logger.addHandler(file)
# 添加日志的Handler

logger.debug("This is a debug_log")
logger.info("This is a info_log")
logger.warning("This is a warning_log")
logger.error("This is a error_log")
logger.critical("This is a critical_log")
# 每个级别的输出信息

#结果
#屏幕输出
2017-10-23 14:40:09,892-DEBUG-test.py
2017-10-23 14:40:09,893-INFO-test.py
2017-10-23 14:40:09,893-WARNING-test.py
2017-10-23 14:40:09,893-ERROR-test.py
2017-10-23 14:40:09,893-CRITICAL-test.py
#信息同时写入test.log文件

9.10、re模块

re模块用于对正则表达式的操作。

import re

#常用匹配语法
#re.match 从头开始匹配,e.g:
>>> re.match("a","abc").group()
'a'
>>> re.match("b","abc").group()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'

#re.search 匹配包含,e.g:
>>> re.search("b","abc").group()
'b'

#re.findall 把所有匹配到的字符放到以列表中的元素返回,e.g:
>>> re.findall("\w","abcdefg")
['a', 'b', 'c', 'd', 'e', 'f', 'g']

#re.split 以匹配到的字符当做列表分隔符,e.g:
>>> re.split("b","abc")
['a', 'c']

#re.sub 匹配字符并替换
>>> re.sub("b","c","ab")
'ac
#常用正则表达式符号

#"." 默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行,e.g:
>>> re.search(".","abcd").group()
'a'
>>> re.search(".","+-*/").group()
'+'

#"^" 匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE),e.g:
>>> re.search("^a","abc").group()
'a'
>>> re.search("^b","abc").group()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'

#"$" 匹配字符结尾,若指定flags MULTILINE,re.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也可以匹配上,e.g:
>>> re.search("c$","abc").group()
'c'
>>> re.search("b$","abc").group()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'

#"*" 匹配*号前的字符0次或多次,e.g:
>>> re.findall("ab*","abcabcabc")
['ab', 'ab', 'ab']

#"+" 匹配前一个字符1次或多次,e.g:
>>> re.findall("a+","abcabcabc")
['a', 'a', 'a']

#"?" 匹配前一个字符1次或0次

#"{m}" 匹配前一个字符m次

#"{n,m}" 匹配前一个字符n到m次

#"[]" 匹配字符集中的任意一个字符。[^]表示取反。
>>> re.search("[ad]","abc").group()
'a'
>>> re.findall("[^a]","abc")
['b', 'c']

#"x|y" 匹配x或y的字符,e.g:
>>> re.search("a|d","abc").group()
'a'

#"()" 分组匹配

#"\A" 只从字符开头匹配,e.g:
>>> re.search("\Aa","abc").group()
'a'
>>> re.search("\Ab","abc").group()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'

#"\Z" 匹配字符结尾,同$

#"\d" 匹配数字0-9

#"\D" 匹配非数字

#"\w" 匹配A-Z、a-z、0-9

#"\W" 匹配非A-Z、a-z、0-9

#"\s" 匹配空白字符、\t、\n、\r ,e.g:
>>> re.search("\s","\nabc").group()
'\n'

#"(?P)" 分组匹配并生成一个字典,e.g:
>>> re.search("(?P<a>a)(?P<b>b)(?P<c>c)","abc").groupdict()
{'a': 'a', 'b': 'b', 'c': 'c'}

#re.I(re.IGNORECASE):忽略大小写(括号内为完整写法)
#re.M(MULTILINE):多行模式,改变'^'和'$'的行为
#re.S(DOTALL):任意匹配模式,改变"."的行为

9.11、subprocess模块

subprocess模块用于与系统进行交互,通过子进程来执行系统指令。

#以下在Linux下进行,Windows下结果有所不同

#subprocess.run()推荐的常用方法
>>> subprocess.run(["df", "-m"])
文件系统        1M-块   已用   可用 已用% 挂载点
udev             1953      0   1953    0% /dev
tmpfs             395      6    390    2% /run
/dev/sda1      499806 200207 274189   43% /
tmpfs            1975     20   1956    1% /dev/shm
tmpfs               5      1      5    1% /run/lock
tmpfs            1975      0   1975    0% /sys/fs/cgroup
tmpfs             395      1    395    1% /run/user/1000
CompletedProcess(args=['df', '-m'], returncode=0)
>>> subprocess.run("df -m", shell = True)
文件系统        1M-块   已用   可用 已用% 挂载点
udev             1953      0   1953    0% /dev
tmpfs             395      6    390    2% /run
/dev/sda1      499806 200207 274189   43% /
tmpfs            1975     20   1956    1% /dev/shm
tmpfs               5      1      5    1% /run/lock
tmpfs            1975      0   1975    0% /sys/fs/cgroup
tmpfs             395      1    395    1% /run/user/1000
CompletedProcess(args='df -m', returncode=0)

#subprocess.call()执行命令,返回命令执行结果及执行状态,成功为0,失败非0
>>> subprocess.call(["df", "-h"])
文件系统        容量  已用  可用 已用% 挂载点
udev            2.0G     0  2.0G    0% /dev
tmpfs           395M  6.0M  390M    2% /run
/dev/sda1       489G  196G  268G   43% /
tmpfs           2.0G   26M  2.0G    2% /dev/shm
tmpfs           5.0M  4.0K  5.0M    1% /run/lock
tmpfs           2.0G     0  2.0G    0% /sys/fs/cgroup
tmpfs           395M   48K  395M    1% /run/user/1000
0
>>> subprocess.call(["df", "-t"])
df:选项需要一个参数 -- t
Try 'df --help' for more information.
1

#subprocess.check_call()执行命令,成功执行返回0,失败则抛出异常
>>> subprocess.check_call(["df", "-m"])
文件系统        1M-块   已用   可用 已用% 挂载点
udev             1953      0   1953    0% /dev
tmpfs             395      6    390    2% /run
/dev/sda1      499806 200207 274188   43% /
tmpfs            1975     18   1957    1% /dev/shm
tmpfs               5      1      5    1% /run/lock
tmpfs            1975      0   1975    0% /sys/fs/cgroup
tmpfs             395      1    395    1% /run/user/1000
0
>>> subprocess.check_call(["df", "-t"])
df:选项需要一个参数 -- t
Try 'df --help' for more information.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.5/subprocess.py", line 581, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['df', '-t']' returned non-zero exit status 1

#subprocess.getstatusoutput()返回一个元组,第一个元素是执行状态,第二个元素是执行结果
>>> subprocess.getstatusoutput(["df", "-h"])
(0, '文件系统           1K-块      已用      可用 已用% 挂载点\nudev             1999728         0   1999728    0% /dev\ntmpfs             404424      6080    398344    2% /run\n/dev/sda1      511801088 205011900 280768172   43% /\ntmpfs            2022108     18836   2003272    1% /dev/shm\ntmpfs               5120         4      5116    1% /run/lock\ntmpfs            2022108         0   2022108    0% /sys/fs/cgroup\ntmpfs             404424        48    404376    1% /run/user/1000')

#subprocess.getoutput()以字符串形式返回执行结果
>>> subprocess.getoutput(["df", "-m"])
'文件系统           1K-块      已用      可用 已用% 挂载点\nudev             1999728         0   1999728    0% /dev\ntmpfs             404424      6080    398344    2% /run\n/dev/sda1      511801088 205012144 280767928   43% /\ntmpfs            2022108     18836   2003272    1% /dev/shm\ntmpfs               5120         4      5116    1% /run/lock\ntmpfs            2022108         0   2022108    0% /sys/fs/cgroup\ntmpfs             404424        48    404376    1% /run/user/1000'

#subprocess.check_output()
>>> subprocess.check_output(["df", "-m"])
b'\xe6\x96\x87\xe4\xbb\xb6\xe7\xb3\xbb\xe7\xbb\x9f        1M-\xe5\x9d\x97   \xe5\xb7\xb2\xe7\x94\xa8   \xe5\x8f\xaf\xe7\x94\xa8 \xe5\xb7\xb2\xe7\x94\xa8% \xe6\x8c\x82\xe8\xbd\xbd\xe7\x82\xb9\nudev             1953      0   1953    0% /dev\ntmpfs             395      6    390    2% /run\n/dev/sda1      499806 200208 274188   43% /\ntmpfs            1975     20   1956    1% /dev/shm\ntmpfs               5      1      5    1% /run/lock\ntmpfs            1975      0   1975    0% /sys/fs/cgroup\ntmpfs             395      1    395    1% /run/user/1000\n'
#subprocess.Popen()subprocess模块的底层方法

#可用参数
# args:shell命令,可以是字符串或者序列类型(如:list,元组)
# bufsize:指定缓冲。0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲
# stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
# preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
# close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管道。所以不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。
# shell:同上
# cwd:用于设置子进程的当前目录
# env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
universal_newlines:不同系统的换行符不同,True -> 同意使用 \n
# startupinfo与createionflags只在windows下有效,将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等

#e,g:
subprocess.Popen(["df", "-m"], stdout = subprocess.PIPE)

posted on 2017-10-10 11:00  青蛙二世  阅读(567)  评论(0编辑  收藏  举报

导航