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

1.内置函数补充1

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

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

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新加的切片功能

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

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

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

  代码详解:

# 以下代码段在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

    运行步骤:

#单行运行步骤:
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') # 第七步 (调用本来函数功能)

  返回值和参数:

# 完整装饰器函数调用,可接收任意参数
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)

7.实例:用户管理程序

8.今日作业

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

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

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

3.多层装饰器原理

4.python字符串格式化

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

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

百分号方式:

%[(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中百分号格式化是不存在自动将整数转换成二进制表示的方式

常用格式化:

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

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

8.python函数递归

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

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":"","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":""},"status":,"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":"","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":""},"status":,"desc":"OK"}
{'data': {'yesterday': {'date': '25日星期三', 'high': '高温 25℃', 'fx': '南风', 'low': '低温 11℃', 'fl': '<![CDATA[3-4级]]>', 'type': '多云'}, 'city': '北京', 'aqi': '', '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': ''}, 'status': , 'desc': 'OK'}
###########################################################################################
# 将文件内容序列化和反序列化:dump(),load()
import json
li =[,,]
json.dump(li,open('db1','w')) # 把li列表转为字符串,再写入db文件中 ret = json.load(open('db1','r')) # 先读db文件,然后再把文件中字符串数据反序列化为列表
print(ret,type(ret)) 输出结果:
[, , ] <class 'list'>
###########################################################################################
# python 序列化之pickle,只提供python使用
import pickle
li = [,,]
r = pickle.dumps(li) # 序列化为python特定的格式
print(r) 输出结果:
b'\x80\x03]q\x00(K\x0bK\x16K!e.'
---------------------------------------------------------------------------------
ret = pickle.loads(r) # 把特定的格式反序列化为原来的列表
print(ret) 输出结果:
[, , ]
###########################################################################################
import pickle
li = [,,,]
pickle.dump(li,open('db2','wb')) # pickle序列化列表数据类型到文件,必须以字节码写入
# 写入文件内容是python特定格式:�]q (KKK!K,e.
r = pickle.load(open('db2','rb')) # 把文件乱码内容还原为列表数据
print(r) 输出结果:
[, , , ]

总结:

  • 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":"","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":""},"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":"","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":""},"status":1000,"desc":"OK"}
{'data': {'yesterday': {'date': '25日星期三', 'high': '高温 25℃', 'fx': '南风', 'low': '低温 11℃', 'fl': '<![CDATA[3-4级]]>', 'type': '多云'}, 'city': '北京', 'aqi': '', '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': ''}, 'status': 1000, 'desc': 'OK'}

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

import time
import datetime print(time.time()) # 时间戳 (UNIX官方发布时间1970-- :: 距离当前时间段的秒数) *****
print(time.ctime()) # 打印当前时间
print(time.ctime()) # 把时间戳转为具体日期
print(time.mktime(time.localtime())) # 把当前时间转为距1970年的时间戳
print(time.sleep()) # CPU停止工作3秒 *****
print(time.clock()) # 计算CPU执行时间
print(time.gmtime()) # 结构化时间(元组格式),以世界UTC标准时间为标准输出,北京与UTC时间相差8小时。UTC=:,北京=:
print(time.localtime()) # 输出本地当地当前时间,与本地PC时间相同 *****
print(time.strftime('%Y-%m-%d %H:%M:%S')) # 字符串格式化输出时间 *****
print(time.strptime('2018-04-27 10:43:39','%Y-%m-%d %H:%M:%S')) # 把字符串格式化时间转为结构化时间 *****
a = time.strptime('2018-04-27 10:43:39','%Y-%m-%d %H:%M:%S')
print(a.tm_year) # 可单独取出日期和时间的年、月、日 和 时,分,秒
print(a.tm_mon) # 只输出月份
print(a.tm_mday) # 只输出几号
print(a.tm_wday) # 当前日期是本周中的第几天 (周一:)
print(a.tm_yday) # 当前日期是本年中的第几天 print(datetime.datetime.now()) # 输出当前系统的规范格式时间 输出结果依次为以下16行:
1524799294.4669478
Fri Apr ::
Thu Jan ::
1524799294.0
None
7.2934459635882e-07
time.struct_time(tm_year=, tm_mon=, tm_mday=, tm_hour=, tm_min=, tm_sec=, tm_wday=, tm_yday=, tm_isdst=)
time.struct_time(tm_year=, tm_mon=, tm_mday=, tm_hour=, tm_min=, tm_sec=, tm_wday=, tm_yday=, tm_isdst=)
-- ::
time.struct_time(tm_year=, tm_mon=, tm_mday=, tm_hour=, tm_min=, tm_sec=, tm_wday=, tm_yday=, tm_isdst=-) -- ::37.479549
# ###########################################################################################
# python中时间日期格式化符号: # %y 两位数的年份表示(-)
# %Y 四位数的年份表示(-)
# %m 月份(-)
# %d 月内中的一天(-)
# %H 24小时制小时数(-)
# %I 12小时制小时数(-)
# %M 分钟数(=)
# %S 秒(-)
# %a 本地简化星期名称
# %A 本地完整星期名称
# %b 本地简化的月份名称
# %B 本地完整的月份名称
# %c 本地相应的日期表示和时间表示
# %j 年内的一天(-)
# %p 本地A.M.或P.M.的等价符
# %U 一年中的星期数(-)星期天为星期的开始
# %w 星期(-),星期天为星期的开始
# %W 一年中的星期数(-)星期一为星期的开始
# %x 本地相应的日期表示
# %X 本地相应的时间表示
# %Z 当前时区的名称
# %% %号本身

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('') 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('') if __name__ == '__main__':
run()
###########################################################################################
# 假设所有模块在lib文件夹库中,需修改导入方式如下:
# 以下方法最常用,用一个主文件index导入一个库(文件夹里存储着很多模块文件)中的所有模块文件
obj = __import__("lib."+m,fromlist=True)

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文件所在的上两级目录放在任何地方都可以执行

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]

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所指向的文件或者目录的最后修改时间
  • 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('',encoding='utf-8')) # 适用与于Python 3.X
result = obj.hexdigest() # 获取加密后的值
print(result)

7.configparser模块

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

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

[section1]    # 节点
k1 = 123 # 键值对
k2 = raymond
k3:v3 # 键值对 [section2] # 节点
k1 = 456 # 键值对 [section3]
|
|
[sectionx] # 第x个节点块
  • 获取所有节点
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')

以上执行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',)
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
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
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

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

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)

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)

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', '')
# 删除属性
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', '')
# 删除属性
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()

13.本周作业

二. python函数与模块的更多相关文章

  1. 洗礼灵魂,修炼python(11)--python函数,模块

    前面的章节你如果看懂了,基本算是入门了七八了,不过如果你以为python就这么点东西,你觉得很简单啊,那你就错了,真正的东西在后面,前面我说的几大核心其实也不是多么高深多么厉害的,那些东西是基础很常用 ...

  2. python函数,模块及eclipse使用

    一.eclipse的使用 1.作用 (1)最好用的IDE (2)可调式debug (3)查看可执行过程 (4)可查看源代码 2.安装eclipse及配置 目录安装Pythonpython for ec ...

  3. python函数,模块及eclipse配置python开发环境

    一.eclipse的使用 1.作用 (1)最好用的IDE (2)可调式debug (3)查看可执行过程 (4)可查看源代码 2.安装eclipse及配置 目录安装Pythonpython for ec ...

  4. Python函数-导入模块的顺序及原理

    引入 当python导入模块,执行import语句时,到底进行了什么操作?按照python的文档,她执行了如下的操作: 第一步,创建一个新的module对象(它可能包含多个module) 第二步,把这 ...

  5. Python 函数和模块

    200 ? "200px" : this.width)!important;} --> 介绍 在python中也存在函数的概念,标准的函数我们可以叫内置函数,这类函数可以直接 ...

  6. Python——函数,模块,简单文件读写

    函数(function)定义原则: 最大化代码重用,最小化代码冗余,流程符合思维逻辑,少用递归; 函数的定义方法: def function_name(param_1, param_2): ..... ...

  7. python函数与模块(装饰器,文件处理,迭代器等)

    os模块 os.system('命令') 利用python调用系统命令,命令可以是以列表或者元组内的元素形式* res import os res=os.system('ipconfig') prin ...

  8. python函数、模块、包

    一.函数 定义函数: def fun_name(para_list): coding def fun_name(para_list): coding return xxx 使用函数,fun_name( ...

  9. Python——函数,模块,简单文件读写(python programming)

    函数(function)定义原则: 最大化代码重用,最小化代码冗余,流程符合思维逻辑,少用递归; 函数的定义方法: def function_name(param_1, param_2): ..... ...

随机推荐

  1. 2012 Noip提高组 Day1

    1262. [NOIP2012] Vigenère 密码 ★   输入文件:vigenere.in   输出文件:vigenere.out   简单对比时间限制:1 s   内存限制:128 MB [ ...

  2. 2019最好用的自动化测试工具Top 10,果断收藏!

    经常有人在公众号留言或是后台问我,做自动化测试用哪个工具好,或是学哪门编程语言好呢? 这个时候总是无奈的说: 你应该学习Python 或是Java. 你应该掌握Selenium. 又或者你需要学会jm ...

  3. __next__,__iter__实现迭代器,斐波那契数列

    迭代器__next__,__iter__ 基于__next__和__iter__方法实现的迭代器 class Foo: def __init__(self,n): self.n = n def __i ...

  4. jQuery插件pagination.js源码解读

    pagination的github地址:https://github.com/gbirke/jquery_pagination 公司用的是1.2的版本,所以我就读1.2的了. jQuery.fn.pa ...

  5. 20 个案例教你在 Java 8 中如何处理日期和时间?

    前言 前面一篇文章写了<SimpleDateFormat 如何安全的使用?>, 里面介绍了 SimpleDateFormat 如何处理日期/时间,以及如何保证线程安全,及其介绍了在 Jav ...

  6. springMVC 与 struts+hibernate+spring优缺点

    springMVC: Spring 框架是高度可配置的,而且包含多种视图技术,例如 JavaServer Pages(JSP)技术.Velocity.Tiles.iText 和POI.Spring M ...

  7. cookie和session基础以及在Django中应用

    看了会视频,终于搞懂了~ 1.cookie cookie:保存状态 cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地:当浏览器再次访问时,浏览器会自动带上cookie,这样服务器 ...

  8. 《深入理解JavaScript闭包和原型》笔记

    By XFE-堪玉 以下知识来源于对王福朋所写<深入理解javascript原型和闭包>的理解和整理 一切都是对象[引用类型],对象都是通过函数创建的[Funcion类型] 对象是属性的集 ...

  9. dialog样式的activity设置activity的title为隐藏属性

    View view= this.findViewById(android.R.id.title);view.setVisibility(View.GONE);

  10. nagios的一些东西

    make install 用来安装nagios的主程序,cgi和html文件 make install-init 在/etc/rc.d/init.d目录下创建nagios启动脚本 make insta ...