1.assert的使用

python 模板等号后边的值 python中的等号怎么理解_迭代

         os.path.isfile():判断某一对象(需提供绝对路径)是否为文件

2.configparser的使用

python 模板等号后边的值 python中的等号怎么理解_默认参数_02

python 模板等号后边的值 python中的等号怎么理解_迭代_03

2)示例
import configparser  # 导入模块
config = configparser.ConfigParser()  # 创建对象
config.read("user.ini", encoding="utf-8")  # 读取配置文件, # 查看
secs = config.sections()  # 获取所有的节点名称
print(secs)
# ['section1', 'section2']
options = config.options('section1')  # 获取指定节点的所有key
print(options)
# ['name', 'age']
item_list = config.items('section1')  # 获取指定节点的键值对
print(item_list)
# [('name', 'wang'), ('age', '18')]
val = config.get('section1', 'name')  # 获取指定节点的指定key的value
print(val)
#  wang
val = config.getint('section1', 'age')  # 获取节点section1的age属性,属性需要是int型,否则ValueError
print(val)
# 18

3 for loop 与 可迭代对象 

 

python 模板等号后边的值 python中的等号怎么理解_生成器_04

 在我们常写的for循环中 in 后面的xx就是可迭代对象

python 模板等号后边的值 python中的等号怎么理解_迭代_05

 总结iterable 就类似一个数据仓库,iterator就是里面的搬运工,iterator很清楚知道自己搬运完这个数据之后,接下来搬运的数据在iterable的哪个位置

python 模板等号后边的值 python中的等号怎么理解_python_06

4.生成器

 

python 模板等号后边的值 python中的等号怎么理解_python_07

图片中 def gen(num) ,这里的gen叫做生成器函数,g = gen(5) 这里的g叫做生成器对象。当python发现一个函数中有yield关键字时,就不会把这个函数看成普通的函数,而是当作生成器函数。在调用生成器函数时得到一个生成器对象,就是调用gen(5)时,不会返回值而是得到一个生成器对象赋给g,此时yield与return都不是生成器函数的返回值,只有对生成器对象g使用next()函数时,它才真正的运行它的函数本体,因此当你运行next(g)时,它会将yield num(此时num=5)先返回回去,但这个函数还没运行完,相当于按了一个暂停键,当下一次再使用next(g)时,才会继续往下执行yield num 后面的代码。

当 g = gen(5)时,此时只是将num=5 赋值好,g只是一个生成器对象,当运行next(g)时,先判断num=5是否大于0,如果是,则现将5返回,然后函数暂停在这里,对for i in g: 会call next(g),于是num= num-1=4,此时依然在while loop中,将4返回,由于for循环是不断call next(g) 因此进行若干次后,num = 0退出循环 这时候运行return,但是由于是在生成器函数中,return == raise StopIteration注意return 不管后面有没有跟值,它们都不会在用next时将值返回回去,只有yield的值才能够被 next()返回回去

  1. 函数中的*args和**kwargs是个什么东西

在Python代码中,经常见到函数中有*args**kwargs写法,它们都起到了可选参数(optional arguments)的作用

在了解*args和**kwargs的作用之前,首先要理解***在Python中的使用。*和**主要有三方面的用途,(一)是对可迭代对象进行拆分,(二)可变变量的赋值,(三)函数的可选参数标志

(1)对可迭代对象进行拆分,主要用在函数参数语境中。可迭代对象指的是实现了__iter()__方法的对象,典型的可迭代对象:tuple,list,dict,set,str

以print函数为例,以下5个表达式是完全等价的

print("a", "b", "c")                
	print(*("a", "b", "c"))             # 元组 
	print(*["a", "b", "c"])             # 列表
	print(*{"a": 1, "b": 2, "c": 3})    # 注意:对字典拆解时只拆解key
	print(*"abc")                       # 注意:字符串也是可迭代对象

# 这几个print打印出来的都是“a b c
# 但是要注意的是,集合不太一样,因为集合是无序的,所以print(*{"a", "b", "c"})的时候"a", "b", "c"可能是乱序的

除了函数参数语境,赋值语境下也可以对可迭代对象进行拆分

a = *range(3),
b = *range(3), 3
c = [*range(3)]
d = {*range(3)}
e = {*{'y': 1}}     # 只对key进行拆解
f = {**{'y': 1}}    # 对key和value都进行了拆解


print(a)  # output: (0,1,2)
print(b)  # output: (0,1,2,3)
print(c)  # output: [0,1,2]
print(d)  # output: {0,1,2}
print(e)  # output: {'y'}
print(f)  # output: {'y':1}

但是这种赋值用法只能在元组、列表、集合和字典内部使用,其他地方就会报错,比如

a = *range(3),   # 这么写默认是在元组内部,即等效于a = (*range(3), )
a = *range(3)    # 这么写就会报错

3)函数的可选参数标志

是单星号*标记的就是可选的位置参数(positional arguments),如果是双星号标记的就是可选的关键词参数(keyword arguments),如

def function(a, *args, **kwargs):
    print(a) # 1
    print(args)# (2,3),是个元组
    print(kwargs)# {‘c’ = 4},是个集合

# function(1, 2, 3, c=4)  这里默认是将2,3变成元组赋给了args,将c= 4变成{’c’=4}赋给kwargs,另外c就变成字符串了,也就是说等号前面的变量名就会变成字符串

# 或者这样调用 function(1,*(2,3),**{‘c’:4}) 此时调用时,必须将元组和字典前面加上*与**

在Python中默认的函数参数顺序是:必选参数、默认参数、*args和**kwargs,如

def self_defined_function(name, purpose="Demo", *args, **kwargs):
    # name是必选参数
    # purpose是默认参数

    print("Name: ", name)
    print("Purpose: ", purpose)
    denominator = kwargs.pop("denominator", 1)
    print(sum(args) / denominator)

# 这里"Demo"不能少
self_defined_function("A self-defined function", "Demo", 1, 2, 3, denominator=3)

在这种写法中,你会发现"Demo"不能少,如果少了"Demo",purpose就变成了1。同时你又不能下面这样写,因为这样不符合传参的规范

# 不能这样写,这不符合传参的规范
# 因为定义了purpose="Demo",它就成了关键字参数,而关键字参数必须放在最后

self_defined_function("A self-defined function", purpose="Demo", 1, 2, 3, denominator=3)

因此在Python3中放松了对顺序的限制[2]只要**kwargs放在最后就行,剩下三个(必选参数、默认参数、*args)的顺序不做严格规定,因此上述问题就可以得到解决

def self_defined_function(name, *args, purpose="Demo", **kwargs):
    # name是必选参数
    # purpose是默认参数

    print("Name: ", name)
    print("Purpose: ", purpose)
    denominator = kwargs.pop("denominator", 1)
    print(sum(args) / denominator)

# 默认参数purpose终于不需要专门定义了
self_defined_function("A self-defined function", 1, 2, 3, denominator=3)  

#将可选参数*args放在默认参数前边就解决上面的问题了

将可选参数*args放在默认参数前边就解决上面的问题了

总结:*args(args是元组类型,*只是告诉编译器它在函数中是可选参数)**kwargs(kwargs是字典类型)**是告诉编译器kwargs是在函数中做关键字参数

 

6. for zip并行遍历

        python中内置的zip函数可以让我们使用for来同时进行多个序列的遍历 

L1 = [1,2,3,4]
L2 = [5,6,7,8]
lis = list(zip(L1,L2))
print(lis)
>>>[(1,5),(2,6),(3,7),(4,8)]
for (x,y) in zip(L1,L2): 
   print(x,y,"=",x+y)
	# zip()函数返回的对象,既实现了__iter__又实现了__next__方法,
    # 所以zip既能够用到for i in xx中(xx可迭代对象)又能够使用next(zip())操作

zip可接受任何类型的序列(可迭代对象),包括文件类型。但需要注意的是,zip()中的两个参数都必须是相同的序列对象,要么都是列表,要么都是字符串等(就是zip中的多个迭代对象必须是一类的,要么都是str、要么都是list、要么都是dict…

       zip可以有两个以上的参数(可以有多个参数)

当两个序列的参数长度不同时,zip以最短的序列来截断