Python基础 2
一、函数
1、参数
def func(形参, *args, 关键字参, **kwargs)
pass
2、作用域
global:声明一个变量是全局变量。
nonlocal:声明一个变量是局部变量,用在函数嵌套中,内层函数用来声明一个变量是局部中离它最近的同名局部变量。如果声明的这个变量在局部中没有则报错,或者声明的这个变量在局部已经被声明为全局变量也报错。
3、命名空间
命名空间就是变量名和值的对应关系,分为内置、全局和局部,变量会分别保存在这三个地方。
函数里的变量只有在函数被执行时才会开辟命名空间,当函数执行完毕后又被清除,外部无法调用。
4、闭包
定义:在内层函数使用外层函数的变量
作用:1、保护变量不被全局中其他的函数改变。如果直接一层函数,并且使用全局变量,那这个变量很可能被其他函数修改,导致需要的变量值不对。2、常驻内存,使得局部的变量不被清除,为装饰器做铺垫。
def func1(): a = 111 def func2(): return a return func2 func = func1() f = func() print(f)
5、匿名函数
匿名函数一般搭配内置函数一起使用。
lambda x:x+1
6、内置函数
(1) sorted
sorted用来给可迭代对象排序,有三个参数:iterable可迭代对象、key排序规则、reverse是否倒序。
sorted是创建列表将排序好的数据都放到新的列表,原数据并不改变,而列表的.sort()方法是修改原列表。
sorted不管传入的是什么数据类型,返回的都是列表,如果传入的是一个字符串,会将每个字符排序放入列表,如果传入的是一个字典,会将字典的键排序。
l = ["aaaaa", "aaa", "a", "aaas"] print(sorted(l, key=lambda x:x.count("a"), reverse=False)) # 将列表按照含a的个数从小到大排序 d = [{"name": "小黑", "age": 3}, {"name": "小红", "age": 2}, {"name": "小明", "age": 1}] print(sorted(d, key=lambda x:x["age"]))
(2) filter
filter用来对可迭代对象做过滤,有两个参数:function 规则、iterable 可迭代对象。
按照规则如果返回真则保留,返回假就不要。最后返回的是一个迭代器,需要用list()转换成列表。
l = [1, 2, 3, 4, 5, 6, 7, 8, 9] print(list(filter(lambda x: x % 2 == 0, l))) # 得到一个只有偶数的列表
(3) map
map对每个数据做一些操作,需要两个参数:func 规则、iterable可迭代对象。
l = [1, 2, 3, 4, 5, 6, 7, 8, 9] print(list(map(lambda x: x + 1, l))) #得到一个每个数都加1的列表
(4) zip
zip把传入的一个或多个可迭代对象中,索引值相同的元素打包成一个元祖,最后返回一个迭代器。
l1 = [1, 2, 3] l2 = [3, 2, 1] print(list(zip(l1, l2))) >>>[(1, 3), (2, 2), (3, 1)]
(5) isinstance 和 issubclass
isinstance(obj, cls) 判断对象是否属于某个类型,包含继承关系。
issubclass(son, father) 判断一个类是否是一个类的子类。
二、装饰器
装饰器就是在不改变函数代码的前提下给函数添加新的功能。
1、装饰器的基本格式
def wrapper(func): def inner(*args,**kwargs): print("111") ret = func(*args,**kwargs) print("222") return ret return inner @wrapper def test(): a = 1 return a
2、装饰器的wraps
实际上@wrapper就是执行了test = wrapper(test),使得我们调用的test函数变成了wrapper函数,导致函数的信息也变成了wrapper的,比如函数的名字,给装饰器内层的函数添加一个@wraper可以让函数的信息维持原来的样子。
from functools import wraper def wrapper(func): @wraper def inner(*args,**kwargs): print("111") ret = func(*args,**kwargs) print("222") return ret return inner @wrapper def test(): a = 1 return a
3、带参数的装饰器
def outer(a): def wrapper(func): def inner(*args,**kwargs): xxxxx return return inner return wrapper @outer(xx)
4、多个装饰器装饰一个函数
@wrapper1
@wrapper2
def xxxxx
这样会先执行1里func前的代码,再执行2中func前的代码,再执行func,再执行2中func后的代码,在执行1func后的代码。
三、迭代器
迭代器可以让不同的数据类型有相同的遍历方式。
只要含有__iter__方法的都是可迭代对象——可迭代协议
只要含有__next__和__iter__方法就是迭代器——迭代器协议
迭代器定义:实现了无参数的__next__方法,返回序列的下一个元素,如果没有元素了则抛出StopIteration异常,且实现了__iter__方法,返回迭代器本身,所以迭代器也可以迭代。
当使用for循环遍历一个列表(可迭代对象时)时,会执行列表的__iter__方法,将列表转换成一个迭代器,之后通过迭代器的__next__方法依次取值。
注意:可迭代对象一定不能是迭代器,因为迭代器只能遍历一次,如果可迭代对象本身也是一个迭代器(实现了__next__方法),那么遍历一次后就没用了,所以必须在每次需要遍历时生成一个新的迭代器去遍历。
四、生成器
定义:只要有yield关键字的函数,就是生成器函数。
生成器本质是迭代器,是迭代器的一种。
生成器函数在调用时不执行内部语句,只有在.__next__方法时,才执行到第一个yield为止,在下一次执行__next__方法时,执行到第二个yield。
注意,生成器里的值只能取一次。
特点:1、省内存,存的是代码,不是数据。2、惰性机制。3、只能向前,不能反复。
def func(): yield 1 yield 2 yield 3 yield 4 >>> 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(): print(111) yield "111" print(func().__next__)
g = (i for i in range(10))
二、next和send
# 生成器可以通过__next__方法取值 def func(): yield 1 yield 2 yield 3 g = func() print(g.__next__()) print(g.__next__()) print(g.__next__())
# 生成器还可以通过send取值,并且send可以给上一个yield赋值 # 因为send是给上一个yield赋值,所以第一次只能用__next__ def func(): print("开始") a = yiled "1" print("a:",a) b = yiled "2" print("b:",b) c = yiled "3" print("c:",c) yiled "结束" g = func() print(g.__next__()) # 开始 1 pritn(g.send("这是a")) # a:这是a 2 pritn(g.send("这是b")) # b:这是b 3 pritn(g.send("这是c")) # c:这是c 结束
三、惰性机制
生成器的惰性机制让生成器只有在取值的时候才会执行,否则生成器中保存的只是代码,没有数据。
def add(a,b): return a + b def gen(): for i in range(4): yield i g = gen() for n in [2, 10]: g = add(n,i) for i in g # 这里生成器g并没有取值,所以并不执行这段代码,只是把这段代码完整的代入下一次循环,n没有机会等于2,只会等于10 print(list(g)) # 这里g被取值了,实际上现在等于执行的是 [add(n, i) for i in (add(n,i) for i in g)],这时的n都是10
四、各种推导式
[i for i in range(10)] # 列表推导式 {i:i+1 for i in range(10)} # 字典推导式 {i for i in range(10)} # 集合推导式
a if a > b else b # 三元运算符
用生成器自定义一个range函数:
def nrange(num): n = 0 while n < num: yield n n += 1 return for i in nrange(10): print(i) #得到 0,1,2,3,4,5,6,7,8,9
五、其他基础知识
1、globals()函数
globals函数可以返回一个字典,字典的键是当前模块中所有的全局变量、函数、类的名字,值就是相应的对象,可以使用globals()函数寻找当前模块中名字符合某些条件的类、函数或变量
[globals()[key] for key in globals() if key == 'xxxx']
2、策略模式
策略模式是在有很多种选择的处理方法时,通过一个通用接口来调度不同的“策略”,如购物结算时的折扣方式,可以将不同的优惠策略封装成不同的方法,用一个统一的入口取调用这些方法。