二. python函数与模块

第四章.内置函数与装饰器详解

1.内置函数补充1

注:红色圆圈:必会;  紫红色方框:熟练;   绿色:了解node

callable()   判断函数是否能够被调用执行
def f1():
    pass
f1()

f2 = 123
print(callable(f1))
print(callable(f2))
###########################################################################################
# chr(), ord()  对ascii码表中的字符与十进制数互相转换
r = chr(65)   # 把ascii表中十进制数转为字母,只能单个转换。
print(r)
输出结果:A
n = ord("B")   # 把ascii表中字母转为字母十进制数,只能单个转换。
print(n)
输出结果:66
###########################################################################################
#随机验证码基础知识
import random
i = random.randrange(65,91)
c = chr(i)
print(c)
输出结果:随机输出一个大写字母
---------------------------------------------------------------------------------
import random
li = []
for i in range(6):
    temp = random.randrange(65,91)  # ASCII码表大写字母A-Z对应的十进制数范围
    c = chr(temp)         # 输出大写字母
    li.append(c)
result = ".".join(li)
print(result)
输出结果:随机输出6个大写字母
###########################################################################################
#随机验证码完整代码
import random
li = []
for i in range(6):
    r = random.randrange(0,5)  #  0<=r<5
    if r==2 or r==4:
        num = random.randrange(0,10)
        li.append(str(num))
    else:
        temp = random.randrange(65,91)
        c = chr(temp)
        li.append(c)
result = " ".join(li)
print(result)
输出结果:随机生成6个大写字母和数字的组合
###########################################################################################
# compile()  编译单行模式
# eval()     编译表达式模式
# exec()     编译整个python代码

s = "print(123)"   # 定义字符串
r = compile(s,"<string>","exec")  # 编译字符串s转换为python代码
exec(r)         # 执行编译好的代码
输出结果:123
-----------------------------------------------------------------------
s = 8*8
ret = eval("s")  # 接收字符串,并将字符串做为python表达式进行计算的功能,返回表达式运算结果
print(ret)
输出结果:64
-----------------------------------------------------------------------
a = exec("7+8+9")   # 执行python代码,接收代码或字符串
b = eval("6+7+8")   # 执行表达式,而且获取计算结果
print(a,b)
输出结果:None 21
###########################################################################################
# dir()   快速查看对象提供哪些功能
print(dir(dict))
print(dir(list))
help(dict)
help(list)
输出结果:
['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
['__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']
Help on class dict in module builtins:

class dict(object)
 |  dict() -> new empty dictionary
 |  dict(mapping) -> new dictionary initialized from a mapping object's
 |      (key, value) pairs
 |  dict(iterable) -> new dictionary initialized as if via:
 |      d = {}
 |      for k, v in iterable:
 |          d[k] = v
 |  dict(**kwargs) -> new dictionary initialized with the name=value pairs
 |      in the keyword argument list.  For example:  dict(one=1, two=2)
 |  
 |  Methods defined here:
 |  
 |  __contains__(self, key, /)
 |      True if D has a key k, else False.
 |  
 |  __delitem__(self, key, /)
 |      Delete self[key].
 |  
 |  __eq__(self, value, /)
 |      Return self==value.
 |  
 |  __ge__(self, value, /)
 |      Return self>=value.
 |  
 |  __getattribute__(self, name, /)
 |      Return getattr(self, name).
 |  
 |  __getitem__(...)
 |      x.__getitem__(y) <==> x[y]
 |  
 |  __gt__(self, value, /)
 |      Return self>value.
 |  
 |  __init__(self, /, *args, **kwargs)
 |      Initialize self.  See help(type(self)) for accurate signature.
 |  
 |  __iter__(self, /)
 |      Implement iter(self).
 |  
 |  __le__(self, value, /)
 |      Return self<=value.
 |  
 |  __len__(self, /)
 |      Return len(self).
 |  
 |  __lt__(self, value, /)
 |      Return self<value.
 |  
 |  __ne__(self, value, /)
 |      Return self!=value.
 |  
 |  __new__(*args, **kwargs) from builtins.type
 |      Create and return a new object.  See help(type) for accurate signature.
 |  
 |  __repr__(self, /)
 |      Return repr(self).
 |  
 |  __setitem__(self, key, value, /)
 |      Set self[key] to value.
 |  
 |  __sizeof__(...)
 |      D.__sizeof__() -> size of D in memory, in bytes
 |  
 |  clear(...)
 |      D.clear() -> None.  Remove all items from D.
 |  
 |  copy(...)
 |      D.copy() -> a shallow copy of D
 |  
 |  fromkeys(iterable, value=None, /) from builtins.type
 |      Returns a new dict with keys from iterable and values equal to value.
 |  
 |  get(...)
 |      D.get(k[,d]) -> D[k] if k in D, else d.  d defaults to None.
 |  
 |  items(...)
 |      D.items() -> a set-like object providing a view on D's items
 |  
 |  keys(...)
 |      D.keys() -> a set-like object providing a view on D's keys
 |  
 |  pop(...)
 |      D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
 |      If key is not found, d is returned if given, otherwise KeyError is raised
 |  
 |  popitem(...)
 |      D.popitem() -> (k, v), remove and return some (key, value) pair as a
 |      2-tuple; but raise KeyError if D is empty.
 |  
 |  setdefault(...)
 |      D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D
 |  
 |  update(...)
 |      D.update([E, ]**F) -> None.  Update D from dict/iterable E and F.
 |      If E is present and has a .keys() method, then does:  for k in E: D[k] = E[k]
 |      If E is present and lacks a .keys() method, then does:  for k, v in E: D[k] = v
 |      In either case, this is followed by: for k in F:  D[k] = F[k]
 |  
 |  values(...)
 |      D.values() -> an object providing a view on D's values
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |  
 |  __hash__ = None

Help on class list in module builtins:

class list(object)
 |  list() -> new empty list
 |  list(iterable) -> new list initialized from iterable's items
 |  
 |  Methods defined here:
 |  
 |  __add__(self, value, /)
 |      Return self+value.
 |  
 |  __contains__(self, key, /)
 |      Return key in self.
 |  
 |  __delitem__(self, key, /)
 |      Delete self[key].
 |  
 |  __eq__(self, value, /)
 |      Return self==value.
 |  
 |  __ge__(self, value, /)
 |      Return self>=value.
 |  
 |  __getattribute__(self, name, /)
 |      Return getattr(self, name).
 |  
 |  __getitem__(...)
 |      x.__getitem__(y) <==> x[y]
 |  
 |  __gt__(self, value, /)
 |      Return self>value.
 |  
 |  __iadd__(self, value, /)
 |      Implement self+=value.
 |  
 |  __imul__(self, value, /)
 |      Implement self*=value.
 |  
 |  __init__(self, /, *args, **kwargs)
 |      Initialize self.  See help(type(self)) for accurate signature.
 |  
 |  __iter__(self, /)
 |      Implement iter(self).
 |  
 |  __le__(self, value, /)
 |      Return self<=value.
 |  
 |  __len__(self, /)
 |      Return len(self).
 |  
 |  __lt__(self, value, /)
 |      Return self<value.
 |  
 |  __mul__(self, value, /)
 |      Return self*value.n
 |  
 |  __ne__(self, value, /)
 |      Return self!=value.
 |  
 |  __new__(*args, **kwargs) from builtins.type
 |      Create and return a new object.  See help(type) for accurate signature.
 |  
 |  __repr__(self, /)
 |      Return repr(self).
 |  
 |  __reversed__(...)
 |      L.__reversed__() -- return a reverse iterator over the list
 |  
 |  __rmul__(self, value, /)
 |      Return self*value.
 |  
 |  __setitem__(self, key, value, /)
 |      Set self[key] to value.
 |  
 |  __sizeof__(...)
 |      L.__sizeof__() -- size of L in memory, in bytes
 |  
 |  append(...)
 |      L.append(object) -> None -- append object to end
 |  
 |  clear(...)
 |      L.clear() -> None -- remove all items from L
 |  
 |  copy(...)
 |      L.copy() -> list -- a shallow copy of L
 |  
 |  count(...)
 |      L.count(value) -> integer -- return number of occurrences of value
 |  
 |  extend(...)
 |      L.extend(iterable) -> None -- extend list by appending elements from the iterable
 |  
 |  index(...)
 |      L.index(value, [start, [stop]]) -> integer -- return first index of value.
 |      Raises ValueError if the value is not present.
 |  
 |  insert(...)
 |      L.insert(index, object) -- insert object before index
 |  
 |  pop(...)
 |      L.pop([index]) -> item -- remove and return item at index (default last).
 |      Raises IndexError if list is empty or index is out of range.
 |  
 |  remove(...)
 |      L.remove(value) -> None -- remove first occurrence of value.
 |      Raises ValueError if the value is not present.
 |  
 |  reverse(...)
 |      L.reverse() -- reverse *IN PLACE*
 |  
 |  sort(...)
 |      L.sort(key=None, reverse=False) -> None -- stable sort *IN PLACE*
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |  
 |  __hash__ = None
View Code

2.内置函数补充2

# divmod()
# 应用场景:共有97条数,每页显示10条,需多少页?
r = divmod(97,10)     # 97/10 运算后所得的商和余数
n1,n2 = divmod(98,10) # 把商和余数分别赋值给n1,n2
print(r)        # 返回一个元组
print(n1,n2)
输出结果:
(9, 7)
9 8
###########################################################################################
# isinstance()  判断一个对象是不是某个类的实例(对象的功能都封装在类里,对象是类的实例)
s = "raymond"            # s是字符串
r1 = isinstance(s,str)   # s是str类的实例
r2 = isinstance(s,dict)  # s不是dict类的实例
print(r1,r2)

输出结果: True False
###########################################################################################
# filter() 是可迭代的对象
# 普通方法:过滤一个列表(保留大于22的元素)
def f1(args):
    result = []
    for item in args:
        if item > 22:
            result.append(item)
    return result
li = [11,22,33,44,55]
ret = f1(li)
print(ret)

输出结果:
[33, 44, 55]
# -----------------------------------------------------------------
# 用filter()方法过滤大于22的元素
def f2(a):
    if a > 22:
        return True
li = [11,22,33,44,55]
ret = filter(f2,li)
 '''
# 1. filter()内部循环第二个参数,让每一个循环元素做为参数传递给第一个函数参数,而后执行函数。
# 2. 若是函数返回True,则将元素赋值给ret并保存在列表输出;函数返回False,则丢弃元素。
 '''
print(list(ret))
#
输出结果:
[33, 44, 55]
###########################################################################################
# lambda 内部返回bool值
f1 = lambda a: a > 30
a = f1(10)
b = f1(90)
print(a,b)
输出结果:False True
# -----------------------------------------------------------------
# filter() + lambda 组合使用场景
li = [11,22,33,44,55]
result = filter(lambda a:a>30,li)
print(list(result))
#
输出结果:
[33, 44, 55]
###########################################################################################
# 通常方法:
li = [11,22,33,44,55]
def f1(args):
    result = []
    for item in args:
        result.append(item+100)
    return result
ret = f1(li)
print(list(ret))

输出结果:
[111, 122, 133, 144, 155]
# ---------------------------------------------------------------------------
# map()函数,可迭代的对象(能够for循环的东西)
# 使用map()函数实现以上代码功能:
li = [11,22,33,44,55]
def f2(a):
    return  a+100
result = map(f2,li)
print(list(result))

输出结果:
[111, 122, 133, 144, 155]
# ---------------------------------------------------------------------------
# 使用map() + lambda 组合应用场景:对列表中每一个元素进行一样功能的批量处理
# map() + lambda 实现以上代码:
li = [11, 22, 33, 44, 55]
result = map(lambda a:a+100,li)
print(list(result))

输出结果:[111, 122, 133, 144, 155]
---------------------------------------------------------------------------
# 总结:1. filter() 返回True,将列表元素添加到结果中
#       2. map()  将函数返回值添加到结果中
###########################################################################################
#  globals()  表明全部全局变量
#  locals()  表明全部局部变量
NAME = "raymond"
def show():
    a = 123
    b = 456
    print(locals())    # 输出变量名与值对应的字典
    print(globals())   # 除了输出全局变量,还有一些python内部的全局变量
show()

输出结果:
{'b': 456, 'a': 123}
{'__name__': '__main__', '__doc__': '\n1. filter()内部循环第二个参数,让每一个循环元素做为参数传递给第一个函数参数,而后执行函数。\n2. 若是函数返回True,则将元素赋值给ret并保存在列表输出;函数返回False,则丢弃元素。\n', '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000002165F7DCB00>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:/PythonProject/python13-day1/text.py', '__cached__': None, 'NAME': 'raymond', 'show': <function show at 0x000002165F382E18>}
###########################################################################################
# hash()
s1 = 'raymond'
s2 = 'jshfjsfhsjdfhsfsfkskdjf'
print("s1:",hash(s1))
print("s2:",hash(s2))
print(len(str(hash(s1))))   # 输出hash值的长度
输出结果:随机输出两串19位的数字
s1: 4413186832486012387
s2: -6135389105302975698
###########################################################################################
# max(), min(), sum()
li = [11,22,33,44,55]
r = max(li)
s = min(li)
t = sum (li)
print(r,s,t)
输出结果:55 11 165
###########################################################################################
pow()
r = pow(2,10)   # 表示2的10次方
print(r)
###########################################################################################
# reverse() 翻转
li = [11,22,1,1]
li = reversed(li)    # 内部执行了li.reverse()方法,两个效果同样
print(li)
###########################################################################################
r = round(1.8)     # 四舍五入
print(r)
输出结果:2
###########################################################################################
# sorted()
li = [55,11,22,44,33]
li.sort()     # 按列表元素从小到大的顺序输出
sorted(li)    # 按列表元素本来顺序输出
print(li)
###########################################################################################
# zip()
r = ["raymond",11,22,33]
s = ["is",22,33,44]
t = ["boy",33,44,55]

a = zip(r,s)
print(list(a))
# -------------------------------------------------------------------------------------------
b = zip(r,s,t)   # 会把每一个以不一样列表的元素按相同下标的元素组合成一个元组,每一个元组构成的元素造成新列表。元素少的列表不与别的列表元素匹配。
temp = list(b)[0]      #需调试
ret = ' '.join(temp)
print(ret)

输出结果:
[('raymond', 'is'), (11, 22), (22, 33), (33, 44)]
raymond is boy
# ###########################################################################################
# 其余内置函数
id()          # 查看内存地址
issubclass()  # 查看一个类是不是另外一个类的派生类
len()         # 查看长度,2.x按字节计算;3.x按字符计算
memoryview()  # 查看内存地址的一个数
object()      # 表示全部类的父类
range()       # 表示范围
vars()        # 当前模块变量哪些可以使用
repr(object)  # 将对象转化为供解释器读取的形式。
slice()       # 3.x新加的切片功能
View Code

3.上节做业剖析

4.装饰器概要

# 在a.py文件中建立装饰器代码
# 应用场景:能够对多个业务功能f1(),f2()在不修改的前提下进行添加新的业务功能。
# 能够根据流水线业务的前后顺序在原来功能的前面和后面均可添加新业务功能
def outer(func):
    def inner():
        print('log')
        func()
        print('after')
    return inner

@outer
def f1():
    print("f1")

@outer
def f2():
    print("f2")
# ###########################################################################################
# # 如下代码在b.py中建立,导入a.py
import a

a.f1()
a.f2()
View Code

5.装饰器流程剖析储备知识

def f1():
    print(123)
def f1():
    print(456)
f1()       # 两个函数f1()相似一个变量名前后赋两个值,输出第二个函数的值

输出结果:456
###########################################################################################
def f1():    # 建立f1()函数,并将整个函数体放入内存中
    print(123)    
def f2(x):   # 此处接收f1函数体,至关于x=f1
    x()      # 此处至关于x()=f1(),是执行f1()函数
f2(f1)       # f1不加括号,表明x形参接收f1所有函数体

输出结果:123
View Code

6.装饰器流程剖析之原理步骤、返回值和参数传递

  代码详解:python

# 如下代码段在a.py中建立
# 定义好函数未调用时,函数内部不执行
# 函数名(不加括号)代替整个函数;加括号后,执行函数
def outer(func):    # 括号里func=f1
    def inner():
        print('before')
        func()      # 此处func()=f1(),执行下面原有f1()
        print('after')
    return inner    # 返回值inner表示整个inner函数体,此处会将inner整个函数赋值给f1函数,下面f1()=inner()

@outer
# @outer 功能解释以下:
# 1. 程序运行到此处,自动执行outer函数,而且将其下面装饰的函数名f1看成参数传递到上面func形参中
# 2. 将outer函数的返回值,从新赋值给f1
# 3. 若是一个函数f1()被装饰器函数outer()装饰后,这个函数f1会被从新赋值成装饰器的内层函数,调用f1()会执行outer函数的内层函数inner()
# 4. 应用场景:假如f1()是一个功能的底层函数,那么装饰器函数outer()会在不修改底层函数的前提下,对其进行增长业务功能
def f1():
    print('F1')
# ###########################################################################################
# 如下代码在b.py中建立,导入a.py
import a

a.f1()

输出结果:
before
F1
after
View Code

    运行步骤:正则表达式

#单行运行步骤:
def outer(func):     # 第一步
    def inner():     # 第三步
        print('before')  # 第五步
        func()           # 第六步   此处调用下面f1()本来功能
        print('after')   # 第八步
    return inner     # 第四步    此处若是inner+(),则表明执行inner(),返回值为None;从新赋值给f1,f1()返回None,改变原有f1()功能。

@outer              # @outer+f1()总体: 第二步
def f1():
    print('F1')     # 第七步 (调用原本函数功能)
View Code

  返回值和参数:算法

# 完整装饰器函数调用,可接收任意参数
def outer(*args,**kwargs):      # 可接收任意个参数
    def inner(*args,**kwargs):
        print('before')
        r = func()
        print('after')
        return r     
    return inner

@outer
def f1(arg):        # 调用f1()传一个参数
    print('F1')
    return  123     # 原函数f1()带有返回值的状况

@outer
def f2(arg1,arg2):  # def f1(arg):        # 调用f2()传两个参数,也能够有更多参数
    print('F2')
    return  456
#------------------------------------------------------------------------------------
# 如下代码在b.py中建立,导入a.py
import a

a.f1(3)
a.f2(2,3)
View Code

7.实例:用户管理程序

8.今日做业

第五章.双层装饰器、字符串格式化、生成器、迭代器以及重要模块介绍

1.双层装饰器实现用户登陆和权限验证1

2.双层装饰器实现用户登陆和权限验证2

3.多层装饰器原理

4.python字符串格式化

  Python的字符串格式化有两种方式: 百分号方式、format方式shell

  百分号的方式相对来讲比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前二者并存。编程

百分号方式:json

%[(name)][flags][width].[precision]typecode
  • (name)      可选,用于选择指定的key
  • flags          可选,可供选择的值有:
    • +       右对齐;正数前加正好,负数前加负号;
    • -        左对齐;正数前无符号,负数前加负号;
    • 空格    右对齐;正数前加空格,负数前加负号;
    • 0        右对齐;正数前无符号,负数前加负号;用0填充空白处
  • width         可选,占有宽度
  • .precision   可选,小数点后保留的位数
  • typecode    必选
    • s,获取传入对象的__str__方法的返回值,并将其格式化到指定位置
    • r,获取传入对象的__repr__方法的返回值,并将其格式化到指定位置
    • c,整数:将数字转换成其unicode对应的值,10进制范围为 0 <= i <= 1114111(py27则只支持0-255);字符:将字符添加到指定位置
    • o,将整数转换成 八  进制表示,并将其格式化到指定位置
    • x,将整数转换成十六进制表示,并将其格式化到指定位置
    • d,将整数、浮点数转换成 十 进制表示,并将其格式化到指定位置
    • e,将整数、浮点数转换成科学计数法,并将其格式化到指定位置(小写e)
    • E,将整数、浮点数转换成科学计数法,并将其格式化到指定位置(大写E)
    • f, 将整数、浮点数转换成浮点数表示,并将其格式化到指定位置(默认保留小数点后6位)
    • F,同上
    • g,自动调整将整数、浮点数转换成 浮点型或科学计数法表示(超过6位数用科学计数法),并将其格式化到指定位置(若是是科学计数则是e;)
    • G,自动调整将整数、浮点数转换成 浮点型或科学计数法表示(超过6位数用科学计数法),并将其格式化到指定位置(若是是科学计数则是E;)
    • %,当字符串中存在格式化标志时,须要用 %%表示一个百分号

注:Python中百分号格式化是不存在自动将整数转换成二进制表示的方式windows

经常使用格式化:浏览器

tpl = "i am %s" % "alex"
 
tpl = "i am %s age %d" % ("alex", 18)
 
tpl = "i am %(name)s age %(age)d" % {"name": "alex", "age": 18}
 
tpl = "percent %.2f" % 99.97623
 
tpl = "i am %(pp).2f" % {"pp": 123.425556, }
 
tpl = "i am %.2f %%" % {"pp": 123.425556, }

Format方式:安全

[[fill]align][sign][#][0][width][,][.precision][type]
  •  fill           【可选】空白处填充的字符
  • align        【可选】对齐方式(需配合width使用)
  • <,内容左对齐
  • >,内容右对齐(默认)
  • =,内容右对齐,将符号放置在填充字符的左侧,且只对数字类型有效。 即便:符号+填充物+数字
  • ^,内容居中
  • sign         【可选】有无符号数字
    • +,正号加正,负号加负;
    •  -,正号不变,负号加负;
    • 空格 ,正号空格,负号加负;
  • #            【可选】对于二进制、八进制、十六进制,若是加上#,会显示 0b/0o/0x,不然不显示
  • ,            【可选】为数字添加分隔符,如:1,000,000
  • width       【可选】格式化位所占宽度
  • .precision 【可选】小数位保留精度
  • type         【可选】格式化类型
    • 传入” 字符串类型 “的参数
      • s,格式化字符串类型数据
      • 空白,未指定类型,则默认是None,同s
    • 传入“ 整数类型 ”的参数
      • b,将10进制整数自动转换成2进制表示而后格式化
      • c,将10进制整数自动转换为其对应的unicode字符
      • d,十进制整数
      • o,将10进制整数自动转换成8进制表示而后格式化;
      • x,将10进制整数自动转换成16进制表示而后格式化(小写x)
      • X,将10进制整数自动转换成16进制表示而后格式化(大写X)
    • 传入“ 浮点型或小数类型 ”的参数
      • e, 转换为科学计数法(小写e)表示,而后格式化;
      • E, 转换为科学计数法(大写E)表示,而后格式化;
      • f , 转换为浮点型(默认小数点后保留6位)表示,而后格式化;
      • F, 转换为浮点型(默认小数点后保留6位)表示,而后格式化;
      • g, 自动在e和f中切换
      • G, 自动在E和F中切换
      • %,显示百分比(默认显示小数点后6位)

 经常使用格式化:

tpl = "i am {}, age {}, {}".format("seven", 18, 'alex')
  
tpl = "i am {}, age {}, {}".format(*["seven", 18, 'alex'])
  
tpl = "i am {0}, age {1}, really {0}".format("seven", 18)
  
tpl = "i am {0}, age {1}, really {0}".format(*["seven", 18])
  
tpl = "i am {name}, age {age}, really {name}".format(name="seven", age=18)
  
tpl = "i am {name}, age {age}, really {name}".format(**{"name": "seven", "age": 18})
  
tpl = "i am {0[0]}, age {0[1]}, really {0[2]}".format([1, 2, 3], [11, 22, 33])
  
tpl = "i am {:s}, age {:d}, money {:f}".format("seven", 18, 88888.1)
  
tpl = "i am {:s}, age {:d}".format(*["seven", 18])
  
tpl = "i am {name:s}, age {age:d}".format(name="seven", age=18)
  
tpl = "i am {name:s}, age {age:d}".format(**{"name": "seven", "age": 18})
 
tpl = "numbers: {:b},{:o},{:d},{:x},{:X}, {:%}".format(15, 15, 15, 15, 15, 15.87623, 2)
 
tpl = "numbers: {:b},{:o},{:d},{:x},{:X}, {:%}".format(15, 15, 15, 15, 15, 15.87623, 2)
 
tpl = "numbers: {0:b},{0:o},{0:d},{0:x},{0:X}, {0:%}".format(15)
 
tpl = "numbers: {num:b},{num:o},{num:d},{num:x},{num:X}, {num:%}".format(num=15)

6.python生成器

一个函数调用时返回一个迭代器,那这个函数就叫作生成器(generator);若是函数中包含yield语法,那这个函数就会变成生成器;

def func():
    yield 1
    yield 2
    yield 3
    yield 4

上述代码中:func是函数称为生成器,当执行此函数func()时会获得一个迭代器。

>>> temp = func()
>>> temp.__next__()
1
>>> temp.__next__()
2
>>> temp.__next__()
3
>>> temp.__next__()
4
>>> temp.__next__()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

 示例: 

# 生成器(具备生成数据的功能叫生成器)
def func():     # 若是函数里有yield,则该函数变为生成器
    print('start')
    yield 1
    yield 2
    yield 3
ret = func()    # 函数执行到此处,并不执行函数
print(ret)      # 返回一个生成器对象(generator object),循环这个对象才能够取值
输出结果:
<generator object func at 0x0000028098630FC0>
----------------------------------------------------------------------------------------
r = ret.__next__()      # 调用此函数找到yield,每次只能取一个yield后面的值
print(r)
输出结果:
<generator object func at 0x0000024DA6F90FC0>
start
1

r = ret.__next__()      # 合并上次取到的值,再取第二个yield后面的值。
print(r)
输出结果:
<generator object func at 0x0000024DA6F90FC0>
start
1
2
###########################################################################################
# 用for循环取生成器中的值,结果输出所有生成器的返回值
def func():
    print('start')
    yield 1
    yield 2
    yield 3
ret = func()

for item in ret:        # 每循环一次,去func()中依次取函数输出值以及yield后面的返回值。
    print(item)         # 分别取到:start,1,2,3

输出结果:
start
1
2
3
View Code

7.基于生成器实现range功能以及python迭代器

# 基于生成器实现range功能
def myrange(arg):
    start = 0
    while True:
        if start > arg:
            return
        else:
            yield start  # 具备生成数据功能的叫生成器。
            start += 1
ret = myrange(5)    # 可迭代的对对象,叫迭代器。可经过__next__()去取值,一直到取完值后,报错!
r = ret.__next__()
print(r)            # 输出结果:0
r = ret.__next__()
print(r)            # 输出结果:0,1
View Code

8.python函数递归

# 若是函数无返回值,默认返回None
def fun(n):     # 递归函数
    n = n + 1
    if n >= 4:
        return  'end'
    return fun(n)
r = fun(1)
print(r)
输出结果:end
View Code

9.利用递归实现阶乘实例

# 递归函数(函数反复调用本身)
def func(num):
    if num ==1:
        return 1
    return num*func(num - 1)
x = func(7)
print(x)

输出结果:5040

10.python模块介绍

  在python安装目录中:D:\Program Files\Python\Python36\Lib

  此目录中包含全部python模块,如:xxx.py

  模块分为:

  • 内置模块
  • 自定义模块
  • 第三方模块

  模块先导入,后使用。示例以下:

import sys
print(sys.path)

输出结果:
['E:\\PythonProject\\python13-day1', 'E:\\PythonProject\\python13-day1', 'E:\\PythonProject\\zgf', 'E:\\PythonProject\\python13-day1\\venv\\Scripts\\python36.zip', 'E:\\PythonProject\\python13-day1\\venv\\DLLs', 'E:\\PythonProject\\python13-day1\\venv\\lib', 'E:\\PythonProject\\python13-day1\\venv\\Scripts', 'D:\\Program Files\\Python\\Python36\\Lib', 'D:\\Program Files\\Python\\Python36\\DLLs', 'E:\\PythonProject\\python13-day1\\venv', 'E:\\PythonProject\\python13-day1\\venv\\lib\\site-packages', 'D:\\Program Files\\JetBrains\\PyCharm professional 2017.3.2\\helpers\\pycharm_matplotlib_backend']

  单模块用法:

  • import  模块名
  • from 模块名 import 函数名

  嵌套在文件夹里的模块:

  • from 文件夹名 import  文件名
  • from 文件夹名 import  文件名 as 别名

注:自定义模块名不要与内置模块名重名

11.安装第三方模块

  pip3 install requests  (python 3.x 自带pip3安装工具,2.x不带,需本身安装)

  源码安装:解压requests包-->进入目录-->python3 setup.py install

12.python序列化之json和pickle模块

# python序列化和反序列化:dumps(),loads()
import json

li = ['k1','v1']
ret = json.dumps(li)  # 将python基本数据类型转化为字符串格式
print(ret,type(ret))

输出结果:
["k1", "v1"] <class 'str'>
##########################################################################################
# s1 = '{'k1':123}'
import json
li = '["alex","eric"] '
ret = json.loads(li)   # 将字符串格式转化成python基本数据类型,反序列化时列表内必定要使用""
print(ret,type(ret))

输出结果:
['alex', 'eric'] <class 'list'>
###########################################################################################
# # 基于天气API获取天气相关JSON数据
import requests
import json
response = requests.get('http://wthrcdn.etouch.cn/weather_mini?city=%E5%8C%97%E4%BA%AC')
response.encoding = 'utf-8'
print(response.text)       # 获取 http请求返回的数据

输出结果:
{"data":{"yesterday":{"date":"25日星期三","high":"高温 25℃","fx":"南风","low":"低温 11℃","fl":"<![CDATA[3-4级]]>","type":"多云"},"city":"北京","aqi":"101","forecast":[{"date":"26日星期四","high":"高温 26℃","fengli":"<![CDATA[<3级]]>","low":"低温 11℃","fengxiang":"南风","type":""},{"date":"27日星期五","high":"高温 25℃","fengli":"<![CDATA[3-4级]]>","low":"低温 13℃","fengxiang":"西南风","type":""},{"date":"28日星期六","high":"高温 27℃","fengli":"<![CDATA[3-4级]]>","low":"低温 17℃","fengxiang":"西南风","type":""},{"date":"29日星期天","high":"高温 29℃","fengli":"<![CDATA[<3级]]>","low":"低温 17℃","fengxiang":"南风","type":"多云"},{"date":"30日星期一","high":"高温 26℃","fengli":"<![CDATA[3-4级]]>","low":"低温 15℃","fengxiang":"东北风","type":"多云"}],"ganmao":"各项气象条件适宜,无明显降温过程,发生感冒机率较低。","wendu":"24"},"status":1000,"desc":"OK"}

ret = json.loads(response.text)    # 将http返回的字符串转化为python基本数据类型字典
print(ret)

 输出结果:
{"data":{"yesterday":{"date":"25日星期三","high":"高温 25℃","fx":"南风","low":"低温 11℃","fl":"<![CDATA[3-4级]]>","type":"多云"},"city":"北京","aqi":"101","forecast":[{"date":"26日星期四","high":"高温 26℃","fengli":"<![CDATA[<3级]]>","low":"低温 11℃","fengxiang":"南风","type":""},{"date":"27日星期五","high":"高温 25℃","fengli":"<![CDATA[3-4级]]>","low":"低温 13℃","fengxiang":"西南风","type":""},{"date":"28日星期六","high":"高温 27℃","fengli":"<![CDATA[3-4级]]>","low":"低温 17℃","fengxiang":"西南风","type":""},{"date":"29日星期天","high":"高温 29℃","fengli":"<![CDATA[<3级]]>","low":"低温 17℃","fengxiang":"南风","type":"多云"},{"date":"30日星期一","high":"高温 26℃","fengli":"<![CDATA[3-4级]]>","low":"低温 15℃","fengxiang":"东北风","type":"多云"}],"ganmao":"各项气象条件适宜,无明显降温过程,发生感冒机率较低。","wendu":"24"},"status":1000,"desc":"OK"}
{'data': {'yesterday': {'date': '25日星期三', 'high': '高温 25℃', 'fx': '南风', 'low': '低温 11℃', 'fl': '<![CDATA[3-4级]]>', 'type': '多云'}, 'city': '北京', 'aqi': '101', 'forecast': [{'date': '26日星期四', 'high': '高温 26℃', 'fengli': '<![CDATA[<3级]]>', 'low': '低温 11℃', 'fengxiang': '南风', 'type': ''}, {'date': '27日星期五', 'high': '高温 25℃', 'fengli': '<![CDATA[3-4级]]>', 'low': '低温 13℃', 'fengxiang': '西南风', 'type': ''}, {'date': '28日星期六', 'high': '高温 27℃', 'fengli': '<![CDATA[3-4级]]>', 'low': '低温 17℃', 'fengxiang': '西南风', 'type': ''}, {'date': '29日星期天', 'high': '高温 29℃', 'fengli': '<![CDATA[<3级]]>', 'low': '低温 17℃', 'fengxiang': '南风', 'type': '多云'}, {'date': '30日星期一', 'high': '高温 26℃', 'fengli': '<![CDATA[3-4级]]>', 'low': '低温 15℃', 'fengxiang': '东北风', 'type': '多云'}], 'ganmao': '各项气象条件适宜,无明显降温过程,发生感冒机率较低。', 'wendu': '24'}, 'status': 1000, 'desc': 'OK'}
###########################################################################################
# 将文件内容序列化和反序列化:dump(),load()
import json
li =[11,22,33]
json.dump(li,open('db1','w'))     # 把li列表转为字符串,再写入db文件中

ret = json.load(open('db1','r'))  # 先读db文件,而后再把文件中字符串数据反序列化为列表
print(ret,type(ret))

输出结果:
[11, 22, 33] <class 'list'>
###########################################################################################
# python 序列化之pickle,只提供python使用
import pickle
li = [11,22,33]
r = pickle.dumps(li)    # 序列化为python特定的格式
print(r)

输出结果:
b'\x80\x03]q\x00(K\x0bK\x16K!e.'
---------------------------------------------------------------------------------
ret = pickle.loads(r)   # 把特定的格式反序列化为原来的列表
print(ret)

输出结果:
[11, 22, 33]
###########################################################################################
import  pickle
li = [11,22,33,44]
pickle.dump(li,open('db2','wb'))  # pickle序列化列表数据类型到文件,必须以字节码写入
# 写入文件内容是python特定格式:�]q (KKK!K,e.
r = pickle.load(open('db2','rb'))  # 把文件乱码内容还原为列表数据
print(r)

输出结果:
[11, 22, 33, 44]
View Code

 总结:

  • json:只能处理python的基本数据类型(dict,lixt,tuple,str,int,float,True,False);支持各类编程语言数据的序列化,适合基本数据类型。

  • pickle:除了能够处理json的基本数据类型外,还能够用于复杂数据类型的操做。例如:可记忆存储游戏闯关类数据文档。但只支持python使用,python不一样版本之间的序列化和反序列化,可能报错。

13.基于天气API获取天气相关JSON数据

# 基于天气API获取天气相关JSON数据
import requests
import json
response = requests.get('http://wthrcdn.etouch.cn/weather_mini?city=%E5%8C%97%E4%BA%AC')
response.encoding = 'utf-8'
print(response.text)       # 获取 http请求返回的数据

输出结果:
{"data":{"yesterday":{"date":"25日星期三","high":"高温 25℃","fx":"南风","low":"低温 11℃","fl":"<![CDATA[3-4级]]>","type":"多云"},"city":"北京","aqi":"101","forecast":[{"date":"26日星期四","high":"高温 26℃","fengli":"<![CDATA[<3级]]>","low":"低温 11℃","fengxiang":"南风","type":""},{"date":"27日星期五","high":"高温 25℃","fengli":"<![CDATA[3-4级]]>","low":"低温 13℃","fengxiang":"西南风","type":""},{"date":"28日星期六","high":"高温 27℃","fengli":"<![CDATA[3-4级]]>","low":"低温 17℃","fengxiang":"西南风","type":""},{"date":"29日星期天","high":"高温 29℃","fengli":"<![CDATA[<3级]]>","low":"低温 17℃","fengxiang":"南风","type":"多云"},{"date":"30日星期一","high":"高温 26℃","fengli":"<![CDATA[3-4级]]>","low":"低温 15℃","fengxiang":"东北风","type":"多云"}],"ganmao":"各项气象条件适宜,无明显降温过程,发生感冒机率较低。","wendu":"24"},"status":1000,"desc":"OK"}

ret = json.loads(response.text)    # 将http返回的字符串转化为python基本数据类型字典
print(ret)

 输出结果:
{"data":{"yesterday":{"date":"25日星期三","high":"高温 25℃","fx":"南风","low":"低温 11℃","fl":"<![CDATA[3-4级]]>","type":"多云"},"city":"北京","aqi":"101","forecast":[{"date":"26日星期四","high":"高温 26℃","fengli":"<![CDATA[<3级]]>","low":"低温 11℃","fengxiang":"南风","type":""},{"date":"27日星期五","high":"高温 25℃","fengli":"<![CDATA[3-4级]]>","low":"低温 13℃","fengxiang":"西南风","type":""},{"date":"28日星期六","high":"高温 27℃","fengli":"<![CDATA[3-4级]]>","low":"低温 17℃","fengxiang":"西南风","type":""},{"date":"29日星期天","high":"高温 29℃","fengli":"<![CDATA[<3级]]>","low":"低温 17℃","fengxiang":"南风","type":"多云"},{"date":"30日星期一","high":"高温 26℃","fengli":"<![CDATA[3-4级]]>","low":"低温 15℃","fengxiang":"东北风","type":"多云"}],"ganmao":"各项气象条件适宜,无明显降温过程,发生感冒机率较低。","wendu":"24"},"status":1000,"desc":"OK"}
{'data': {'yesterday': {'date': '25日星期三', 'high': '高温 25℃', 'fx': '南风', 'low': '低温 11℃', 'fl': '<![CDATA[3-4级]]>', 'type': '多云'}, 'city': '北京', 'aqi': '101', 'forecast': [{'date': '26日星期四', 'high': '高温 26℃', 'fengli': '<![CDATA[<3级]]>', 'low': '低温 11℃', 'fengxiang': '南风', 'type': ''}, {'date': '27日星期五', 'high': '高温 25℃', 'fengli': '<![CDATA[3-4级]]>', 'low': '低温 13℃', 'fengxiang': '西南风', 'type': ''}, {'date': '28日星期六', 'high': '高温 27℃', 'fengli': '<![CDATA[3-4级]]>', 'low': '低温 17℃', 'fengxiang': '西南风', 'type': ''}, {'date': '29日星期天', 'high': '高温 29℃', 'fengli': '<![CDATA[<3级]]>', 'low': '低温 17℃', 'fengxiang': '南风', 'type': '多云'}, {'date': '30日星期一', 'high': '高温 26℃', 'fengli': '<![CDATA[3-4级]]>', 'low': '低温 15℃', 'fengxiang': '东北风', 'type': '多云'}], 'ganmao': '各项气象条件适宜,无明显降温过程,发生感冒机率较低。', 'wendu': '24'}, 'status': 1000, 'desc': 'OK'}
View Code

14.python时间处理之time&datetime模块 

import time
import datetime

print(time.time())      #1 时间戳 (UNIX官方发布时间1970-01-01 00:00:00 距离当前时间段的秒数)  *****
print(time.ctime())     #2 打印当前时间
print(time.ctime(3600)) #3 把时间戳转为具体日期
print(time.mktime(time.localtime()))    #4 把当前时间转为距1970年的时间戳
print(time.sleep(3))  #5 CPU中止工做3秒   *****
print(time.clock())     #6 计算CPU执行时间
print(time.gmtime())    #7 结构化时间(元组格式),以世界UTC标准时间为标准输出,北京与UTC时间相差8小时。UTC=1000,北京=1800
print(time.localtime()) #8 输出本地当地当前时间,与本地PC时间相同  *****
print(time.strftime('%Y-%m-%d %H:%M:%S'))   #9 字符串格式化输出时间    *****
print(time.strptime('2018-04-27 10:43:39','%Y-%m-%d %H:%M:%S'))  #10 把字符串格式化时间转为结构化时间 *****
a = time.strptime('2018-04-27 10:43:39','%Y-%m-%d %H:%M:%S')
print(a.tm_year)    #11 可单独取出日期和时间的年、月、日 和 时,分,秒
print(a.tm_mon)     #12 只输出月份
print(a.tm_mday)    #13 只输出几号
print(a.tm_wday)    #14 当前日期是本周中的第几天 (周一:0)
print(a.tm_yday)    #15 当前日期是本年中的第几天

print(datetime.datetime.now())  #16 输出当前系统的规范格式时间


输出结果依次为如下16行:
1524799294.4669478
Fri Apr 27 11:21:34 2018
Thu Jan  1 09:00:00 1970
1524799294.0
None
7.2934459635882e-07
time.struct_time(tm_year=2018, tm_mon=4, tm_mday=27, tm_hour=3, tm_min=21, tm_sec=37, tm_wday=4, tm_yday=117, tm_isdst=0)
time.struct_time(tm_year=2018, tm_mon=4, tm_mday=27, tm_hour=11, tm_min=21, tm_sec=37, tm_wday=4, tm_yday=117, tm_isdst=0)
2018-04-27 11:21:37
time.struct_time(tm_year=2018, tm_mon=4, tm_mday=27, tm_hour=10, tm_min=43, tm_sec=39, tm_wday=4, tm_yday=117, tm_isdst=-1)
2018
4
27
4
117
2018-04-27 11:21:37.479549
# ###########################################################################################
# python中时间日期格式化符号:

# %y 两位数的年份表示(00-99)
# %Y 四位数的年份表示(000-9999)
# %m 月份(01-12)
# %d 月内中的一天(0-31)
# %H 24小时制小时数(0-23)
# %I 12小时制小时数(01-12)
# %M 分钟数(00=59)
# %S 秒(00-59)
# %a 本地简化星期名称
# %A 本地完整星期名称
# %b 本地简化的月份名称
# %B 本地完整的月份名称
# %c 本地相应的日期表示和时间表示
# %j 年内的一天(001-366)
# %p 本地A.M.或P.M.的等价符
# %U 一年中的星期数(00-53)星期天为星期的开始
# %w 星期(0-6),星期天为星期的开始
# %W 一年中的星期数(00-53)星期一为星期的开始
# %x 本地相应的日期表示
# %X 本地相应的时间表示
# %Z 当前时区的名称
# %% %号自己
View Code

15.python日志处理之logging模块

用于便捷记录日志且线程安全的模块

import logging
 
 
logging.basicConfig(filename='log.log',
                    format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S %p',
                    level=10)
 
logging.debug('debug')
logging.info('info')
logging.warning('warning')
logging.error('error')
logging.critical('critical')
logging.log(10,'log')

对于level级别以下所示:

CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0

注:只有大于当前日志等级的操做才会被记录。

对于格式,有以下属性能够配置:

16.今日做业以及代码目录

第六章.python反射、重要模块以及正则表达式

1.ATM做业分析

2.python反射模块之getattr,hasattr,setattr,delattr

# python之反射概念:利用字符串的形式去对象(模块)中操做(查找/检查/删除/设置)成员(函数)
# 下面反射函数中m表明模块名,f表明与函数同名的字符串
# getattr(m,f):  用字符串f查找模块m ;
# hasattr(m,f):  判断字符串f是否再模块m中,函数返回True或False ;
# setattr(m,f,v) 给对象的属性赋值,若是此属性不存在,会先建立,而后再赋值 ;
# delattr(m,f):  delattr 函数用于删除属性。至关于del m.f() ; 若是属性不存在,会报错
###########################################################################################
# 建立文件名为commons.py,代码以下:
def login():
    print('login')
def logout():
    print('logout')
def home():
    print('home')
# -------------------------------------------------------------------------------------------
# 建立index.py文件
# import commons
# # 导入模块时,会先放在内存中;反射函数基于内存操做模块,从新reload模块,即可回复成员
#
def run():
    inp = input('请输入访问地址:')     # inp 表示输入的是字符串
    if hasattr(commons,inp):   # bool型,为真,执行下面函数
        func = getattr(commons,inp)   # 此处inp能够加入单个字符串形式的成员名,如:'login'
        func()              # 若是找到模块中的成员,则执行该成员函数
    else:
        print('404')


if __name__ == '__main__':
    run()
###########################################################################################
# 经过字符串查找任意模块及函数
# obj = __import__('commons')  # 表示导入commons模块,等价于 import commons
# obj.login()       # 导入后执行commons模块中的login()
import commons
def run():
    inp = input('请输入访问地址:')
    m,f = inp.split('/')    # 把输入的字符串用 m/f 形式分割为:模块名/函数名
    obj = __import__(m)     # m表示输入的字符串形式的模块名,若是导入一个库中全部模块,此处修改成(解释见下段代码):obj = __import__("lib."+m,fromlist=True)
    if hasattr(obj,f):
        func = getattr(obj,f)
        func()
    else:
        print('404')

if __name__ == '__main__':
    run()
###########################################################################################
# 假设全部模块在lib文件夹库中,需修改导入方式以下:
# 如下方法最经常使用,用一个主文件index导入一个库(文件夹里存储着不少模块文件)中的全部模块文件
obj = __import__("lib."+m,fromlist=True)
View Code

3.python模块中特殊变量

# 特殊全局变量:__file__, __doc__, __cached__, (__name__, __package__)最后两个必须掌握
print(vars(test1))       # 打印test1模块中的变量
print(test1.__dict__)    # 同上

print(__doc__)      # 获取当前文件中'''注释部分'''的文档,#号后的注释不获取
print(__cached__)   # python导入一个模块时,会生成一个*.pyc文件(字节码),__cached__指定pyc文件的路径
print(__file__)     # 打印当前py文件所在路径;若是跳到py所在目录下执行文件,只能取到py文件名
# -----------------------------------------------------------------------------------------
# print(__package__)  输出文件所在的包名
# 假设:s1导入s2,s2在bin目录下,那么在s1中代码以下:
from bin import s2
print(s2.__packge__)
输出结果:bin
# -----------------------------------------------------------------------------------------
# __name__ == __main__,只有执行当前文件时候,当前文件的特殊变量__name__=__main__
def fun():
    print('run')
if __name__ == "__main__":  # 此时 __name__ == "__main__"为真,因此执行下面函数;若是被另外文件调用fun(),则__name__ != "__main__",为假,不执行下面函数fun()
    fun()
###########################################################################################
import os
import sys
print(os.path.abspath(__file__))   # 永远取到的是文件的绝对路径,包含文件名
print(os.path.dirname(__file__))   # 返回原文件的上一级目录
ret = print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))   # 返回原文件路径的上两级目录
sys.path.append(ret)    # 若是原文件上两级的目录添加到sys.path路径中,这样py文件所在的上两级目录放在任何地方均可以执行
View Code

4.python之sys模块

用于提供对解释器相关的操做

sys.argv           命令行参数List,第一个元素是程序自己路径
sys.exit(n)        退出程序,正常退出时exit(0)
sys.version        获取Python解释程序的版本信息
sys.maxint         最大的Int值
sys.path           返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform       返回操做系统平台名称
sys.stdout.write('please:')
val = sys.stdin.readline()[:-1]
View Code

5.python之os模块

用于提供系统级别的操做

os.getcwd() 获取当前工做目录,即当前python脚本工做的目录路径
os.chdir("dirname")  改变当前脚本工做目录;至关于shell下cd
os.curdir  返回当前目录: ('.')
os.pardir  获取当前目录的父目录字符串名:('..')
os.makedirs('dirname1/dirname2')    可生成多层递归目录
os.removedirs('dirname1')    若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname')    生成单级目录;至关于shell中mkdir dirname
os.rmdir('dirname')    删除单级空目录,若目录不为空则没法删除,报错;至关于shell中rmdir dirname
os.listdir('dirname')    列出指定目录下的全部文件和子目录,包括隐藏文件,并以列表方式打印
os.remove()  删除一个文件
os.rename("oldname","newname")  重命名文件/目录
os.stat('path/filename')  获取文件/目录信息
os.sep    输出操做系统特定的路径分隔符,win下为"\\",Linux下为"/"
os.linesep    输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
os.pathsep    输出用于分割文件路径的字符串
os.name    输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.system("bash command")  运行shell命令,直接显示
os.environ  获取系统环境变量
os.path.abspath(path)  返回path规范化的绝对路径
os.path.split(path)  将path分割成目录和文件名二元组返回
os.path.dirname(path)  返回path的目录。其实就是os.path.split(path)的第一个元素
os.path.basename(path)  返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
os.path.exists(path)  若是path存在,返回True;若是path不存在,返回False
os.path.isabs(path)  若是path是绝对路径,返回True
os.path.isfile(path)  若是path是一个存在的文件,返回True。不然返回False
os.path.isdir(path)  若是path是一个存在的目录,则返回True。不然返回False
os.path.join(path1[, path2[, ...]])  将多个路径组合后返回,第一个绝对路径以前的参数将被忽略
os.path.getatime(path)  返回path所指向的文件或者目录的最后存取时间
os.path.getmtime(path)  返回path所指向的文件或者目录的最后修改时间
View Code
  • os模块中几个重要的操做函数
import os
import sys
print(os.path.abspath(__file__))   # 永远取到的是文件的绝对路径,包含文件名
print(os.path.dirname(__file__))   # 返回原文件的上一级目录
ret = print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))   # 返回原文件路径的上两级目录
sys.path.append(ret)    # 若是原文件上两级的目录添加到sys.path路径中,这样py文件所在的上两级目录放在任何地方均可以执行
###########################################################################################
import os

os.path.abspath(path='')        # 返回path规范化的绝对路径
os.path.dirname(path='')        # 返回path的目录。其实就是os.path.split(path)的第一个元素
os.path.join(path1[, path2[, ...]])   # 将多个路径组合后返回,第一个绝对路径以前的参数将被忽略

6.python之hashlib加密模块

用于加密相关的操做,代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法

import md5
hash = md5.new()
hash.update('admin')
print hash.hexdigest()
MD5—废弃
import sha

hash = sha.new()
hash.update('admin')
print hash.hexdigest()
SHA—废弃

hashlib用法:

import hashlib
 
# ######## md5 ########
 
hash = hashlib.md5()
hash.update('admin')
print hash.hexdigest()
 
# ######## sha1 ########
 
hash = hashlib.sha1()
hash.update('admin')
print hash.hexdigest()
 
# ######## sha256 ########
 
hash = hashlib.sha256()
hash.update('admin')
print hash.hexdigest()
 
 
# ######## sha384 ########
 
hash = hashlib.sha384()
hash.update('admin')
print hash.hexdigest()
 
# ######## sha512 ########
 
hash = hashlib.sha512()
hash.update('admin')
print hash.hexdigest()

以上加密算法虽然依然很是厉害,但时候存在缺陷,即:经过撞库能够反解。因此,有必要对加密算法中添加自定义key再来作加密。 

import hashlib
 
# ######## md5 ########
 
hash = hashlib.md5('898oaFs09f')
hash.update('admin')
print hash.hexdigest()

还不够吊?python 还有一个 hmac 模块,它内部对咱们建立 key 和 内容 再进行处理而后再加密  

import hmac
h = hmac.new('wueiqi')
h.update('hellowo')
print h.hexdigest()

到这儿就顶天牛逼了!!!

应用示例:

# hashlib    各类加密对象都保存在hashlib模块中,必须先导入,再使用
# MD5        不可逆,只能加密,不能解密
import hashlib
obj = hashlib.md5(bytes('abcdef',encoding='utf-8'))  # 对123加密后的值,用abcdef进行再次加密
# obj = obj.update('123')     # 适用与于Python 2.X
obj.update(bytes('123',encoding='utf-8'))    # 适用与于Python 3.X
result = obj.hexdigest()   # 获取加密后的值
print(result)
View Code

7.configparser模块

 configparser用于处理特定格式的文件,其本质上是利用open来操做文件。

# 建立特定格式文件xxxooo.txt

[section1]    # 节点
  k1 = 123      # 键值对
  k2 = raymond
  k3:v3         # 键值对 


[section2]    # 节点
  k1 = 456      # 键值对


[section3]
     |
     |
[sectionx]    # 第x个节点块
View Code
  • 获取全部节点
import configparser
 
config = configparser.ConfigParser()
config.read('xxxooo', encoding='utf-8')
ret = config.sections()
print(ret)
  • 获取指定节点下全部的键值对
import configparser
 
config = configparser.ConfigParser()
config.read('xxxooo', encoding='utf-8')
ret = config.items('section1')
print(ret)
  • 获取指定节点下全部的键
import configparser
 
config = configparser.ConfigParser()
config.read('xxxooo', encoding='utf-8')
ret = config.options('section1')
print(ret)
  • 获取指定节点下指定key的值
import configparser
 
config = configparser.ConfigParser()
config.read('xxxooo', encoding='utf-8')
 
 
v = config.get('section1', 'k1')
# v = config.getint('section1', 'k1')
# v = config.getfloat('section1', 'k1')
# v = config.getboolean('section1', 'k1')
 
print(v)
  • 检查、删除、添加节点
import configparser
 
config = configparser.ConfigParser()
config.read('xxxooo', encoding='utf-8')
 
 
# 检查
has_sec = config.has_section('section1')
print(has_sec)
 
# 添加节点
config.add_section("SEC_1")
config.write(open('xxxooo', 'w'))
 
# 删除节点
config.remove_section("SEC_1")
config.write(open('xxxooo', 'w'))
  • 检查、删除、设置指定组内的键值对
import configparser
 
config = configparser.ConfigParser()
config.read('xxxooo', encoding='utf-8')
 
# 检查
has_opt = config.has_option('section1', 'k1')
print(has_opt)
 
# 删除
config.remove_option('section1', 'k1')
config.write(open('xxxooo', 'w'))
 
# 设置
config.set('section1', 'k10', "123")
config.write(open('xxxooo', 'w'))

8.shutil模块以及压缩包处理 

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

  • shutil.copyfileobj(fsrc, fdst[, length])

  将文件内容拷贝到另外一个文件中 

import shutil
 
shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w'))
  • shutil.copyfile(src, dst)

  拷贝文件 

shutil.copyfile('f1.log', 'f2.log')
  • shutil.copymode(src, dst)

  仅拷贝权限。内容、组、用户均不变

shutil.copymode('f1.log', 'f2.log')
  • shutil.copystat(src, dst)

  仅拷贝状态的信息,包括:mode bits, atime, mtime, flags

shutil.copystat('f1.log', 'f2.log')
  • shutil.copy(src, dst)

  拷贝文件和权限 

import shutil
 
shutil.copy('f1.log', 'f2.log')
  • shutil.copy2(src, dst)

  拷贝文件和状态信息 

import shutil
 
shutil.copy2('f1.log', 'f2.log')
  • shutil.ignore_patterns(*patterns)
  • shutil.copytree(src, dst, symlinks=False, ignore=None)

  递归的去拷贝文件夹 

import shutil
 
shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
import shutil

shutil.copytree('f1', 'f2', symlinks=True, ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
  • shutil.rmtree(path[, ignore_errors[, onerror]])

  递归的去删除文件 

import shutil
 
shutil.rmtree('folder1')
  • shutil.move(src, dst)

  递归的去移动文件,它相似mv命令,其实就是重命名。 

import shutil
 
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对象 
#将 /Users/wupeiqi/Downloads/test 下的文件打包放置当前程序目录
import shutil
ret = shutil.make_archive("wwwwwwwwww", 'gztar', root_dir='/Users/wupeiqi/Downloads/test')
  
  
#将 /Users/wupeiqi/Downloads/test 下的文件打包放置 /Users/wupeiqi/目录
import shutil
ret = shutil.make_archive("/Users/wupeiqi/wwwwwwwwww", 'gztar', root_dir='/Users/wupeiqi/Downloads/test')

shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,示例以下: 

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()

zipfile解压缩
zipfile解压缩
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()

tarfile解压缩
tarfile解压缩

9.subprocess模块 

能够执行shell命令的相关模块和函数有: 

  • os.system
  • os.spawn*
  • os.popen*          --废弃
  • popen2.*           --废弃
  • commands.*      --废弃,3.x中被移除
import commands

result = commands.getoutput('cmd')
result = commands.getstatus('cmd')
result = commands.getstatusoutput('cmd')
View Code

 以上执行shell命令的相关的模块和函数的功能均在 subprocess 模块中实现,并提供了更丰富的功能。

call 

执行命令,返回状态码

ret = subprocess.call(["ls", "-l"], shell=False)    # 只获取状态码,不获取命令执行结果
ret = subprocess.call("ls -l", shell=True)

check_call

执行命令,若是执行状态码是 0 ,则返回0,不然抛异常

subprocess.check_call(["ls", "-l"])    

subprocess.check_call("exit 1", shell=True)

check_output

执行命令,若是状态码是 0 ,则返回命令执行结果,不然抛异常 

subprocess.check_output(["echo", "Hello World!"])
subprocess.check_output("exit 1", shell=True)

subprocess.check_output("ls -l",shell=True)  # 获取命令执行结果

subprocess.Popen(...)

用于执行复杂的系统命令

参数:

    • 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()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等 
import subprocess
ret1 = subprocess.Popen(["mkdir","t1"])
ret2 = subprocess.Popen("mkdir t2", shell=True)
执行普通命令

终端输入的命令分为两种:

  • 输入便可获得输出,如:ifconfig
  • 输入进行某环境,依赖再输入,如:python 
import subprocess
# 跳转到cwd目录下,执行mkdir命令
obj = subprocess.Popen("mkdir t3", shell=True, cwd='/home/dev',)   
View Code
import subprocess
#经过管道进行输入内容(stdin),输出内容(stdout)和捕捉错误内容(atderr)
obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)  
obj.stdin.write('print 1 \n ')     # 输入4行内容
obj.stdin.write('print 2 \n ')
obj.stdin.write('print 3 \n ')
obj.stdin.write('print 4 \n ')
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
View Code
import subprocess

obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
obj.stdin.write('print 1 \n ')
obj.stdin.write('print 2 \n ')
obj.stdin.write('print 3 \n ')
obj.stdin.write('print 4 \n ')

#如下语句同时捕捉输出管道和错误管道的内容,返回一个列表类型,存放输出和错误内容
out_error_list = obj.communicate() 
print out_error_list
View Code
import subprocess

obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)


# 把字符串内容放入python解释器解释成python可执行代码
out_error_list = obj.communicate('print "hello"') 
print out_error_list
View Code

10.python之正则表达式

经常使用正则表达式符号 

'.'     默认匹配除\n以外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行
'^'     匹配字符开头,若指定flags MULTILINE,这种也能够匹配上(r"^a","\nabc\neee",flags=re.MULTILINE)
'$'     匹配字符结尾,或e.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也能够
'*'     匹配*号前的字符0次或屡次,re.findall("ab*","cabb3abcbbac")  结果为['abb', 'ab', 'a']
'+'     匹配前一个字符1次或屡次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb']
'?'     匹配前一个字符1次或0次
'{m}'   匹配前一个字符m次
'{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb']
'|'     匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC'
'(...)' 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c
 
 
'\A'    只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的
'\Z'    匹配字符结尾,同$
'\d'    匹配数字0-9
'\D'    匹配非数字
'\w'    匹配[A-Za-z0-9]
'\W'    匹配非[A-Za-z0-9]
's'     匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 '\t'
 
'(?P<name>...)' 分组匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city") 结果{'province': '3714', 'city': '81', 'birthday': '1993'}

 最经常使用的匹配语法

re.match 从头开始匹配
re.search 匹配包含
re.findall 把全部匹配到的字符放到以列表中的元素返回
re.splitall 以匹配到的字符当作列表分隔符
re.sub      匹配字符并替换

 

反斜杠的困扰
与大多数编程语言相同,正则表达式里使用"\"做为转义字符,这就可能形成反斜杠困扰。假如你须要匹配文本中的字符"\",那么使用编程语言表示的正则表达式里将须要4个反斜杠"\\\\":前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。Python里的原生字符串很好地解决了这个问题,这个例子中的正则表达式可使用r"\\"表示。一样,匹配一个数字的"\\d"能够写成r"\d"。有了原生字符串,你不再用担忧是否是漏写了反斜杠,写出来的表达式也更直观。 

 

仅需轻轻知道的几个匹配模式

re.I(re.IGNORECASE): 忽略大小写(括号内是完整写法,下同)
M(MULTILINE): 多行模式,改变'^'和'$'的行为(参见上图)
S(DOTALL): 点任意匹配模式,改变'.'的行为

11.python之正则表达式之分组

12.XML模块

浏览器返回的字符串类型有如下三种:

  • HTML
  • JSON
  • XML      1. 可作页面展现; 2. 可作配置文件使用

 XML是实现不一样语言或程序之间进行数据交换的协议,XML文件格式以下:

<data>
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year>2023</year>
        <gdppc>141100</gdppc>
        <neighbor direction="E" name="Austria" />
        <neighbor direction="W" name="Switzerland" />
    </country>
    <country name="Singapore">
        <rank updated="yes">5</rank>
        <year>2026</year>
        <gdppc>59900</gdppc>
        <neighbor direction="N" name="Malaysia" />
    </country>
    <country name="Panama">
        <rank updated="yes">69</rank>
        <year>2026</year>
        <gdppc>13600</gdppc>
        <neighbor direction="W" name="Costa Rica" />
        <neighbor direction="E" name="Colombia" />
    </country>
</data>
XML文件格式

1. 解析XML 

from xml.etree import ElementTree as ET


# 打开文件,读取XML内容
str_xml = open('xo.xml', 'r').read()

# 将字符串解析成xml特殊对象,root代指xml文件的根节点
root = ET.XML(str_xml)
利用ElementTree.XML将字符串解析成xml对象
from xml.etree import ElementTree as ET

# 直接解析xml文件,把文件加载到特殊对象tree中
tree = ET.parse("xo.xml")

# 获取xml文件的根节点
root = tree.getroot()
View Code

2. 操做XML

XML格式类型是节点嵌套节点,对于每个节点均有如下功能,以便对当前节点进行操做: 

class Element:
    """An XML element.

    This class is the reference implementation of the Element interface.

    An element's length is its number of subelements.  That means if you
    want to check if an element is truly empty, you should check BOTH
    its length AND its text attribute.

    The element tag, attribute names, and attribute values can be either
    bytes or strings.

    *tag* is the element name.  *attrib* is an optional dictionary containing
    element attributes. *extra* are additional element attributes given as
    keyword arguments.

    Example form:
        <tag attrib>text<child/>...</tag>tail

    """

    当前节点的标签名
    tag = None
    """The element's name."""

    当前节点的属性

    attrib = None
    """Dictionary of the element's attributes."""

    当前节点的内容
    text = None
    """
    Text before first subelement. This is either a string or the value None.
    Note that if there is no text, this attribute may be either
    None or the empty string, depending on the parser.

    """

    tail = None
    """
    Text after this element's end tag, but before the next sibling element's
    start tag.  This is either a string or the value None.  Note that if there
    was no text, this attribute may be either None or an empty string,
    depending on the parser.

    """

    def __init__(self, tag, attrib={}, **extra):
        if not isinstance(attrib, dict):
            raise TypeError("attrib must be dict, not %s" % (
                attrib.__class__.__name__,))
        attrib = attrib.copy()
        attrib.update(extra)
        self.tag = tag
        self.attrib = attrib
        self._children = []

    def __repr__(self):
        return "<%s %r at %#x>" % (self.__class__.__name__, self.tag, id(self))

    def makeelement(self, tag, attrib):
        建立一个新节点
        """Create a new element with the same type.

        *tag* is a string containing the element name.
        *attrib* is a dictionary containing the element attributes.

        Do not call this method, use the SubElement factory function instead.

        """
        return self.__class__(tag, attrib)

    def copy(self):
        """Return copy of current element.

        This creates a shallow copy. Subelements will be shared with the
        original tree.

        """
        elem = self.makeelement(self.tag, self.attrib)
        elem.text = self.text
        elem.tail = self.tail
        elem[:] = self
        return elem

    def __len__(self):
        return len(self._children)

    def __bool__(self):
        warnings.warn(
            "The behavior of this method will change in future versions.  "
            "Use specific 'len(elem)' or 'elem is not None' test instead.",
            FutureWarning, stacklevel=2
            )
        return len(self._children) != 0 # emulate old behaviour, for now

    def __getitem__(self, index):
        return self._children[index]

    def __setitem__(self, index, element):
        # if isinstance(index, slice):
        #     for elt in element:
        #         assert iselement(elt)
        # else:
        #     assert iselement(element)
        self._children[index] = element

    def __delitem__(self, index):
        del self._children[index]

    def append(self, subelement):
        为当前节点追加一个子节点
        """Add *subelement* to the end of this element.

        The new element will appear in document order after the last existing
        subelement (or directly after the text, if it's the first subelement),
        but before the end tag for this element.

        """
        self._assert_is_element(subelement)
        self._children.append(subelement)

    def extend(self, elements):
        为当前节点扩展 n 个子节点
        """Append subelements from a sequence.

        *elements* is a sequence with zero or more elements.

        """
        for element in elements:
            self._assert_is_element(element)
        self._children.extend(elements)

    def insert(self, index, subelement):
        在当前节点的子节点中插入某个节点,即:为当前节点建立子节点,而后插入指定位置
        """Insert *subelement* at position *index*."""
        self._assert_is_element(subelement)
        self._children.insert(index, subelement)

    def _assert_is_element(self, e):
        # Need to refer to the actual Python implementation, not the
        # shadowing C implementation.
        if not isinstance(e, _Element_Py):
            raise TypeError('expected an Element, not %s' % type(e).__name__)

    def remove(self, subelement):
        在当前节点在子节点中删除某个节点
        """Remove matching subelement.

        Unlike the find methods, this method compares elements based on
        identity, NOT ON tag value or contents.  To remove subelements by
        other means, the easiest way is to use a list comprehension to
        select what elements to keep, and then use slice assignment to update
        the parent element.

        ValueError is raised if a matching element could not be found.

        """
        # assert iselement(element)
        self._children.remove(subelement)

    def getchildren(self):
        获取全部的子节点(废弃)
        """(Deprecated) Return all subelements.

        Elements are returned in document order.

        """
        warnings.warn(
            "This method will be removed in future versions.  "
            "Use 'list(elem)' or iteration over elem instead.",
            DeprecationWarning, stacklevel=2
            )
        return self._children

    def find(self, path, namespaces=None):
        获取第一个寻找到的子节点
        """Find first matching element by tag name or path.

        *path* is a string having either an element tag or an XPath,
        *namespaces* is an optional mapping from namespace prefix to full name.

        Return the first matching element, or None if no element was found.

        """
        return ElementPath.find(self, path, namespaces)

    def findtext(self, path, default=None, namespaces=None):
        获取第一个寻找到的子节点的内容
        """Find text for first matching element by tag name or path.

        *path* is a string having either an element tag or an XPath,
        *default* is the value to return if the element was not found,
        *namespaces* is an optional mapping from namespace prefix to full name.

        Return text content of first matching element, or default value if
        none was found.  Note that if an element is found having no text
        content, the empty string is returned.

        """
        return ElementPath.findtext(self, path, default, namespaces)

    def findall(self, path, namespaces=None):
        获取全部的子节点
        """Find all matching subelements by tag name or path.

        *path* is a string having either an element tag or an XPath,
        *namespaces* is an optional mapping from namespace prefix to full name.

        Returns list containing all matching elements in document order.

        """
        return ElementPath.findall(self, path, namespaces)

    def iterfind(self, path, namespaces=None):
        获取全部指定的节点,并建立一个迭代器(能够被for循环)
        """Find all matching subelements by tag name or path.

        *path* is a string having either an element tag or an XPath,
        *namespaces* is an optional mapping from namespace prefix to full name.

        Return an iterable yielding all matching elements in document order.

        """
        return ElementPath.iterfind(self, path, namespaces)

    def clear(self):
        清空节点
        """Reset element.

        This function removes all subelements, clears all attributes, and sets
        the text and tail attributes to None.

        """
        self.attrib.clear()
        self._children = []
        self.text = self.tail = None

    def get(self, key, default=None):
        获取当前节点的属性值
        """Get element attribute.

        Equivalent to attrib.get, but some implementations may handle this a
        bit more efficiently.  *key* is what attribute to look for, and
        *default* is what to return if the attribute was not found.

        Returns a string containing the attribute value, or the default if
        attribute was not found.

        """
        return self.attrib.get(key, default)

    def set(self, key, value):
        为当前节点设置属性值
        """Set element attribute.

        Equivalent to attrib[key] = value, but some implementations may handle
        this a bit more efficiently.  *key* is what attribute to set, and
        *value* is the attribute value to set it to.

        """
        self.attrib[key] = value

    def keys(self):
        获取当前节点的全部属性的 key

        """Get list of attribute names.

        Names are returned in an arbitrary order, just like an ordinary
        Python dict.  Equivalent to attrib.keys()

        """
        return self.attrib.keys()

    def items(self):
        获取当前节点的全部属性值,每一个属性都是一个键值对
        """Get element attributes as a sequence.

        The attributes are returned in arbitrary order.  Equivalent to
        attrib.items().

        Return a list of (name, value) tuples.

        """
        return self.attrib.items()

    def iter(self, tag=None):
        在当前节点的子孙中根据节点名称寻找全部指定的节点,并返回一个迭代器(能够被for循环)。
        """Create tree iterator.

        The iterator loops over the element and all subelements in document
        order, returning all elements with a matching tag.

        If the tree structure is modified during iteration, new or removed
        elements may or may not be included.  To get a stable set, use the
        list() function on the iterator, and loop over the resulting list.

        *tag* is what tags to look for (default is to return all elements)

        Return an iterator containing all the matching elements.

        """
        if tag == "*":
            tag = None
        if tag is None or self.tag == tag:
            yield self
        for e in self._children:
            yield from e.iter(tag)

    # compatibility
    def getiterator(self, tag=None):
        # Change for a DeprecationWarning in 1.4
        warnings.warn(
            "This method will be removed in future versions.  "
            "Use 'elem.iter()' or 'list(elem.iter())' instead.",
            PendingDeprecationWarning, stacklevel=2
        )
        return list(self.iter(tag))

    def itertext(self):
        在当前节点的子孙中根据节点名称寻找全部指定的节点的内容,并返回一个迭代器(能够被for循环)。
        """Create text iterator.

        The iterator loops over the element and all subelements in document
        order, returning all inner text.

        """
        tag = self.tag
        if not isinstance(tag, str) and tag is not None:
            return
        if self.text:
            yield self.text
        for e in self:
            yield from e.itertext()
            if e.tail:
                yield e.tail
节点功能一览表 

因为 每一个节点 都具备以上的方法,而且在上一步骤中解析时均获得了root(xml文件的根节点),so   能够利用以上方法进行操做xml文件。

a. 遍历XML文档的全部内容

from xml.etree import ElementTree as ET

############ 解析方式一 ############
"""
# 打开文件,读取XML内容
str_xml = open('xo.xml', 'r').read()

# 将字符串解析成xml特殊对象,root代指xml文件的根节点
root = ET.XML(str_xml)
"""
############ 解析方式二 ############

# 直接解析xml文件
tree = ET.parse("xo.xml")

# 获取xml文件的根节点
root = tree.getroot()


### 操做

# 顶层标签
print(root.tag)


# 遍历XML文档的第二层
for child in root:
    # 第二层节点的标签名称和标签属性
    print(child.tag, child.attrib)
    # 遍历XML文档的第三层
    for i in child:
        # 第二层节点的标签名称和内容
        print(i.tag,i.text)
View Code

b、遍历XML中指定的节点 

from xml.etree import ElementTree as ET

############ 解析方式一 ############
"""
# 打开文件,读取XML内容
str_xml = open('xo.xml', 'r').read()

# 将字符串解析成xml特殊对象,root代指xml文件的根节点
root = ET.XML(str_xml)
"""
############ 解析方式二 ############

# 直接解析xml文件
tree = ET.parse("xo.xml")

# 获取xml文件的根节点
root = tree.getroot()


### 操做

# 顶层标签
print(root.tag)


# 遍历XML中全部的year节点
for node in root.iter('year'):
    # 节点的标签名称和内容
    print(node.tag, node.text)
View Code

c、修改节点内容 

因为修改的节点时,均是在内存中进行,其不会影响文件中的内容。因此,若是想要修改,则须要从新将内存中的内容写到文件。

from xml.etree import ElementTree as ET

############ 解析方式一 ############

# 打开文件,读取XML内容
str_xml = open('xo.xml', 'r').read()

# 将字符串解析成xml特殊对象,root代指xml文件的根节点
root = ET.XML(str_xml)

############ 操做 ############

# 顶层标签
print(root.tag)

# 循环全部的year节点
for node in root.iter('year'):
    # 将year节点中的内容自增一
    new_year = int(node.text) + 1
    node.text = str(new_year)

    # 设置属性
    node.set('name', 'alex')
    node.set('age', '18')
    # 删除属性
    del node.attrib['name']


############ 保存文件 ############
tree = ET.ElementTree(root)
tree.write("newnew.xml", encoding='utf-8')
解析字符串方式,修改,保存
from xml.etree import ElementTree as ET

############ 解析方式二 ############

# 直接解析xml文件
tree = ET.parse("xo.xml")

# 获取xml文件的根节点
root = tree.getroot()

############ 操做 ############

# 顶层标签
print(root.tag)

# 循环全部的year节点
for node in root.iter('year'):
    # 将year节点中的内容自增一
    new_year = int(node.text) + 1
    node.text = str(new_year)

    # 设置属性
    node.set('name', 'alex')
    node.set('age', '18')
    # 删除属性
    del node.attrib['name']


############ 保存文件 ############
tree.write("newnew.xml", encoding='utf-8')
解析文件方式,修改,保存

d、删除节点

from xml.etree import ElementTree as ET

############ 解析字符串方式打开 ############

# 打开文件,读取XML内容
str_xml = open('xo.xml', 'r').read()

# 将字符串解析成xml特殊对象,root代指xml文件的根节点
root = ET.XML(str_xml)

############ 操做 ############

# 顶层标签
print(root.tag)

# 遍历data下的全部country节点
for country in root.findall('country'):
    # 获取每个country节点下rank节点的内容
    rank = int(country.find('rank').text)

    if rank > 50:
        # 删除指定country节点
        root.remove(country)

############ 保存文件 ############
tree = ET.ElementTree(root)
tree.write("newnew.xml", encoding='utf-8')
解析字符串方式打开,删除,保存
from xml.etree import ElementTree as ET

############ 解析文件方式 ############

# 直接解析xml文件
tree = ET.parse("xo.xml")

# 获取xml文件的根节点
root = tree.getroot()

############ 操做 ############

# 顶层标签
print(root.tag)

# 遍历data下的全部country节点
for country in root.findall('country'):
    # 获取每个country节点下rank节点的内容
    rank = int(country.find('rank').text)

    if rank > 50:
        # 删除指定country节点
        root.remove(country)

############ 保存文件 ############
tree.write("newnew.xml", encoding='utf-8')
解析文件方式打开,删除,保存  

3. 建立XML文档

from xml.etree import ElementTree as ET


# 建立根节点
root = ET.Element("famliy")


# 建立节点大儿子
son1 = ET.Element('son', {'name': '儿1'})
# 建立小儿子
son2 = ET.Element('son', {"name": '儿2'})

# 在大儿子中建立两个孙子
grandson1 = ET.Element('grandson', {'name': '儿11'})
grandson2 = ET.Element('grandson', {'name': '儿12'})
son1.append(grandson1)
son1.append(grandson2)


# 把儿子添加到根节点中
root.append(son1)
root.append(son1)

tree = ET.ElementTree(root)
tree.write('oooo.xml',encoding='utf-8', short_empty_elements=False)
建立方式1
from xml.etree import ElementTree as ET

# 建立根节点
root = ET.Element("famliy")


# 建立大儿子
# son1 = ET.Element('son', {'name': '儿1'})
son1 = root.makeelement('son', {'name': '儿1'})
# 建立小儿子
# son2 = ET.Element('son', {"name": '儿2'})
son2 = root.makeelement('son', {"name": '儿2'})

# 在大儿子中建立两个孙子
# grandson1 = ET.Element('grandson', {'name': '儿11'})
grandson1 = son1.makeelement('grandson', {'name': '儿11'})
# grandson2 = ET.Element('grandson', {'name': '儿12'})
grandson2 = son1.makeelement('grandson', {'name': '儿12'})

son1.append(grandson1)
son1.append(grandson2)


# 把儿子添加到根节点中
root.append(son1)
root.append(son1)

tree = ET.ElementTree(root)
tree.write('oooo.xml',encoding='utf-8', short_empty_elements=False)
建立方式2
from xml.etree import ElementTree as ET


# 建立根节点
root = ET.Element("famliy")


# 建立节点大儿子
son1 = ET.SubElement(root, "son", attrib={'name': '儿1'})
# 建立小儿子
son2 = ET.SubElement(root, "son", attrib={"name": "儿2"})

# 在大儿子中建立一个孙子
grandson1 = ET.SubElement(son1, "age", attrib={'name': '儿11'})
grandson1.text = '孙子'


et = ET.ElementTree(root)  #生成文档对象
et.write("test.xml", encoding="utf-8", xml_declaration=True, short_empty_elements=False)
建立方式3

因为原生保存的XML时默认无缩进,若是想要设置缩进的话, 须要修改保存方式:

from xml.etree import ElementTree as ET
from xml.dom import minidom


def prettify(elem):
    """将节点转换成字符串,并添加缩进。
    """
    rough_string = ET.tostring(elem, 'utf-8')
    reparsed = minidom.parseString(rough_string)
    return reparsed.toprettyxml(indent="\t")

# 建立根节点
root = ET.Element("famliy")


# 建立大儿子
# son1 = ET.Element('son', {'name': '儿1'})
son1 = root.makeelement('son', {'name': '儿1'})
# 建立小儿子
# son2 = ET.Element('son', {"name": '儿2'})
son2 = root.makeelement('son', {"name": '儿2'})

# 在大儿子中建立两个孙子
# grandson1 = ET.Element('grandson', {'name': '儿11'})
grandson1 = son1.makeelement('grandson', {'name': '儿11'})
# grandson2 = ET.Element('grandson', {'name': '儿12'})
grandson2 = son1.makeelement('grandson', {'name': '儿12'})

son1.append(grandson1)
son1.append(grandson2)


# 把儿子添加到根节点中
root.append(son1)
root.append(son1)


raw_str = prettify(root)

f = open("xxxoo.xml",'w',encoding='utf-8')
f.write(raw_str)
f.close()
View Code

13.本周做业

相关文章
相关标签/搜索