末学者笔记--Python函数二玄
Python函数:二玄
一.名称空间和作用域
1.内置名称空间:
(python启动时就有)python解释器内置的名字,print,max,min
Print其实是python内置的函数。
1. 全局名称空间:
(执行python文件时启动)定投定义的变量,如在Python界面直接定义的变量:a = 3 ,即为全局变量。
2. 局部名称空间:
(调用函数时启动,调用结束失效)函数内部定义的变量
如:
在函数内的定义的一个变量即为局部变量。
总结:
三者的加载顺序
内置--->全局--->局部
三者的访问顺序
局部--->全局--->内置
二.装饰器
1.什么是装饰器?
在不修改源代码和调用方式的基础上给函数增加新的功能,即为装饰器,多个装饰器可以装饰在同一个函数上。
2.无参装饰器
def add(he):
def wrpper():
he() #he=message
print('这是一个笑话')
return wrpper
@add #@add达到的效果:message=add(message)=wrpper 这是其id内存地址
def message():
print('有2棵树就有4只鸟')
message()
》》
有2棵树就有4只鸟
这是一个笑话
》》
3.有参装饰器:
def add(he):
def wrpper(x,y):
he(x,y) #he=message
print('这是一个笑话')
return wrpper
@add #message=add(message)=wrpper 这是其id内存地址
def message(x,y):
print('有%s棵树就有%s只鸟' % (x,y))
message(2,4)
》》
有2棵树就有4只鸟
这是一个笑话
》》
4.带参数的装饰器:
def default_engine(engine=None):
def auth(func):
def deco(*args, **kwargs):
user = input('user:')
password = input('password:')
if engine == 'mysql':
if user == 'root' and password == 'root':
res = func(*args, **kwargs)
return res
else:
print('用户名或密码错误')
else:
print('没有这个引擎')
return deco
return auth
@default_engine(engine='mysql')
def index():
print('welcome to home page')
# res = default_engine(engine='mysql')
# index = res(index)
index()
三.迭代器
1.什么是迭代器?
迭代是一个重复的过程,即每一次重复为一次迭代,并且每次迭代的结果都是下一次迭代的初始值
while True: #只是单纯的重复,因此不是迭代
print('===>')
l = [1,2,3]
count = 0
while count<len(l): #首先是重复动作,其次上一次的结果是下一次的初始值,因此,是迭代
print(l[count])
count+=1
2.为什么要有迭代器?及可迭代对象和迭代器对象
(1)为何要有迭代器?
对于序列类型:字符串、列表、元组,我们可以使用索引的方式迭代取出其包含的元素。但对于字典、集合、文件等类型是没有索引的,若还想取出其内部包含的元素,则必须找出一种不依赖于索引的迭代方式,这就是迭代器。
(2)什么是可迭代对象?
可迭代对象指的是内置有__iter__方法的对象,即obj.__iter__,如下:
'world'.__iter__
(4,5,6).__iter__
[1,2,3].__iter__
{'a':1}.__iter__
{'a','b'}.__iter__
open('a.txt').__iter__
(3)什么是迭代器对象?
可迭代对象执行obj.__iter__()得到的结果就是迭代器对象
而迭代器对象指的是即内置有__iter__又内置有__next__方法的对象
(4)文件类型是迭代器对象
open('a.txt').__iter__()
open('a.txt').__next__()
(5)总结:
迭代器对象一定是可迭代对象,而可迭代对象不一定是迭代器对象
四:生成器
1.什么是生成器?
只要函数里有yield关键字,那么函数名()得到的结果就是生成器,并且不会执行函数内部代码。
# 生成器就是迭代器
2.return和yield区别:
# return只能返回一个值
# yield可以返回多个值,同一时间只能存储一个值;缺点:没有索引,不能后退取值
return的方式:
def test():
l = []
for i in range(10):
l.append(i)
return l
print(test()[4])
Yield方式:
def test():
l = ['a','b','c']
for i in l:
yield i
for i in test():
print(i)
》》
a
b
c
》》
【特殊】:
def test():
l = ['a','b','c']
for i in l:
yield i
print(next(test()))
print(next(test()))
print(next(test()))
print('==============')
a = test() #生成器的算法是:每次直接调用如‘print(next(test()))’,都会刷新迭代数位,即从新取值;赋予给一个变量即可免去算法刷新
print(next(a))
print(next(a))
print(next(a))
》》
a
a
a
==============
a
b
c
》》
五:匿名函数
1. 定义
匿名函数的定义:lambda,自带return;
匿名函数通常只调用一次,之后不再使用。
2. 格式:
lambda x,y: x+y
其整体是一个函数内存地址,即(lambda x,y: x+y)(a,b)为调用函数
直接输出:
print((lambda x,y:x+y)(1,2))
》》
3
》》
3.lambda的使用场景
【#max sorted map filter zip】
info = {
'li':2000,
'zhao':35000,
'wu': 34000,
'du': 40000
}
(1)# max:取最大值
print(max(info,key=lambda k:info[k])) #max 本身做了一个循环比较;
》》
du
》》
解释:max本身开始循环info字典的key值,将key值赋予给匿名函数的参数‘k’,匿名函数代入‘k’值后返回info字典的对应value值,此时max再进行大小比较,取出最大value值,但输出的是其对应的key值。
(2)# sorted:排序
print(sorted(info,key=lambda k:info[k]))
print(sorted(info,key=lambda k:info[k],reverse=True)) #反向排序
》》
['li', 'wu', 'zhao', 'du']
['du', 'zhao', 'wu', 'li']
》》
原理:同max的原理,
(3)# map:映射
names = ['zhao','wu','du']
#想在每个元素后面加一个‘nb’,通常如下:
l1 = []
for name in names:
res = '%s_nb' % name
l1.append(res)
print(l1)
》》
['zhao_nb', 'wu_nb', 'du_nb']
》》
但使用匿名函数更简单:
print(list(map(lambda name:'%s_nb' % name,names)))
结果一样,同理map映射也是变成迭代器对象
res = map(lambda name:'%s_nb' % name,names)
print(res.__next__())
print(res.__next__())
print(res.__next__())
》》
zhao_nb
wu_nb
du_nb
》》
(4)# filter:过滤
names = ['zhao_nb', 'wu_nb', 'du_nb','li']
print(list(filter(lambda i: i.endswith('nb'),names)))
print(list(filter(lambda i: not i.endswith('nb'),names)))
》》
['zhao_nb', 'wu_nb', 'du_nb']
['li']
》》
【补】 # zip:拉链
l1 = [1,2,3,4]
l2 = ['a','b','c']
print(list(zip(l1,l2)))
res = zip(l1,l2) #很明显zip后是个迭代器对象
print(next(res))
print(next(res))
print(next(res))
》》
[(1, 'a'), (2, 'b'), (3, 'c')]
(1, 'a')
(2, 'b')
(3, 'c')
》》
将列表对应元素连成一个元组,元素个数不对应则去除多余元素。
=======================================分割线===================================