一、基础准备
1.函数嵌套
函数嵌套定义
函数嵌套调用
1 #函数的嵌套定义:在一个函数的内部,又定义另外一个函数
2 deff1():3 print('f1')4 deff2():5 print('f2')6 f2()7 f1()8 f2() #会报错,why?->名称空间和作用域有关
View Code
2.名称空间和作用域
什么是名称空间?
存放名字与变量值绑定关系的地方
名称空间的分类
内置名称空间:在python解释器启动时产生,存放一些python内置的名字
1 max=1
2 print(globals())3 print(globals()['__builtins__'])4 print(dir(globals()['__builtins__'])). #dir查看模块的方法
5 '''{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.sourcefileloader object at>, '__spec__': None, '__annotations__': {}, '__builtins__': , '__file__': '/Users/yanlingzhao/Desktop/python/day4/day4/test.py', '__cached__': None, 'max': 1}6 7 ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FileExistsError', 'FileNotFoundError', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'ModuleNotFoundError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError', 'RecursionError', 'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopAsyncIteration', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', '__build_class__', '__debug__', '__doc__', '__import__', '__loader__', '__name__', '__package__', '__spec__', 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']8 '''
View Code
全局名称空间:在执行文件时产生,存放文件级别定义的名字(除了内置名称空间和函数内定义的变量之外的变量)
1 x=1
2 deffunc():3 y=2
4 def f1():pass
5 print
6 classFoo:7 deff(self):8 print('test f')9 if x==1:z=3
10 print(globals()) #查看全局名称空间中的存储内容
11 '''{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.sourcefileloader object at>, '__spec__': None, '__annotations__': {}, '__builtins__': , '__file__': 'E:/study/code/day4/day4/test.py', '__cached__': None, 'x': 1, 'func': , 'Foo': , 'z': 3}12 '''
View Code
局部名称空间
#局部名称空间:在执行文件的过程中,如果调用了函数,则会产生该函数的局部名称空间
#用来存放该函数内定义的名字,该名字在函数调用时生效,在函数调用结束后失效
1 x=1
2 deffunc():3 y=2
4 def f1():pass
5 print(locals()) #查看局部名称空间内容
6 func()7 '''{'f1': .f1 at 0x00000000026DD9D8>, 'y': 2}8 '''
9
10 classFoo:11 deff(self):12 print(locals())13 '''没有调用函数f,所有不会打印局部名称空间内容'''
View Code
名称空间的加载和查找顺序
#加载顺序:内置---》全局---》局部
#优先掌握一:名字的查找顺序是:局部-》全局-》内置
作用域
#作用域:作用的范围,
#全局作用域:全局存活,全局有效:globals()
#局部作用域:临时存活,局部有效:locals()
1 max=1 #全局作用域,函数内部和文件级别都可以访问
2 deffoo():3 max=2 #局部作用域,只能在函数内部访问
4 print(max)5 foo()6 print(max)7 '''28 1''' #先找全局max=1的名称空间
9 '''''' #注释掉max=1时找到内置变量
View Code
1 x=11111111111111111111111111111111111111111111
2 deff1():3 x=1
4 y=2
5 def f2():pass
6 print(locals()) #局部
7 print(globals()) #全局
8
9 f1()10 print(locals() is globals()) #在文件级别全局就等于局部,从本层开始寻找命名空间
11 print(dir(globals()['__builtins__']))
View Code
改变作用域规则的两个关键词global和nonlocal
1 #改变作用域规则的两个关键词:global nonlocal
2 x=1
3 deff1():4 global x #使用全局变量
5 x=2
6 print(globals())7 print(locals())8 f1()9 print(x)10 '''{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.sourcefileloader object at>, '__spec__': None, '__annotations__': {}, '__builtins__': , '__file__': '/Users/yanlingzhao/Desktop/python/day4/day4/test.py', '__cached__': None, 'x': 2, 'f1': }11 {}12 213 '''
14
15
16
17 l=[]18 deff2():19 l.append('f2') #列表是可变类型,所以可以在局部改变全局的值
20
21 f2()22 print(l)23
24
25 #nonlocal可以改变上一层的局部变量
26 x=027 deff1():28 x=1
29 deff2():30 x=2
31 deff3():32 nonlocal x33 x=3
34 print('f3:%s'%x)35 f3()36 print('f2:%s'%x)37 f2()38 print('f3:%s'%x)39 f1()40 '''f3:341 f2:342 f3:1'''
View Code
函数调用时,必须去函数定义的位置去找作用域关系(作用域关系,在函数定义时已经固定了,与函数调用位置无关)
1 x=1
2 deff1():3 deff2():4 print(x)5 returnf26
7 func=f1()8 x=10000000
9
10 deffoo(func):11 x=300000000
12 func() #f2()
13 foo(func)14 x=10000000000000000000000
View Code
3.闭包函数
函数对象-》打破函数层级调用关系(函数可以作为参数使用)
作用域->在函数定义时,已经决定了作用域跟调用无关
------》》
闭包函数:1.定义在函数内部的函数
2.包含对外部作用域名字的引用
3.而不是对全局作用域名字的引用
则该内部函数被称作闭包函数
1 #闭包函数的应用
2 importrequests3 defindex(url):4 #url = 'www.baidu.com'
5 x=1
6 defwrapper():7 print(x)8 returnrequests.get(url).text9 returnwrapper10 baidu_web=index('http://www.baidu.com') #包裹了百度url的wrapper闭包函数
11 netease_web=index('http://www.163.com') #包裹了网易url的wrapper闭包函数
12 print(baidu_web()) #执行闭包函数
13 print(netease_web())14
15 print(baidu_web.__closure__[0].cell_contents) #输出结果'''http://www.baidu.com'''
16 print(baidu_web.__closure__[1].cell_contents) #输出结果'''1'''
View Code
二、装饰器
1.开放封闭原则:对扩展是开放的,对修改是封闭的
2.什么是装饰器:装饰它人的工具;装饰器本身可以是任意可调用对象,被装饰的对象本身也可以是任意可调用对象
3.装饰器遵循的原则:1)不修改被装饰对象的源代码 2)不修改被装饰对象的调用方式
4.装饰器的目的:在遵循装饰器原则的前提下,为其增加新功能
5.装饰器使用规则:@装饰器名,必须写在装饰器对象的正上方,并且单独一行
代码演示:
1 #!_*_coding=utf-8_*_
2 importtime3
4 deftimmer(fuc):5 def wrapper(*args,**kwargs):6 start=time.time()7 time.sleep(0.3)8 res=fuc(*args,**kwargs)9 end=time.time()10 print('total time:%s'%(end-start))11 returnres12 returnwrapper13
14 @timmer #index=timmer(index)
15 defindex():16 print('wellcome to index')17 x=1
18 returnx19 @timmer #home=timmer(home)
20 defhome(name):21 print('wellcome to home:%s'%name)22
23 print(index())24 print(home('zyl'))25 '''
26 wellcome to index27 total time:0.30383801460328 129 wellcome to home:zyl30 total time:0.30042600631731 None'''
View Code
6.装饰器分类:无参装饰器和有参装饰器
无参装饰器实例:
账户认证装饰器
1 #!_*_coding=utf-8_*_
2
3 '''
4 {'zyl':'123'}5 '''
6 current_user={'user':None}7 defauth(fuc):8 def wrapper(*args,**kwargs):9 if current_user['user']:10 return fuc(*args,**kwargs)11 name = input('name:').strip()12 password = input('password:').strip()13 with open('db.txt', 'r', encoding='utf-8') as f:14 user_dic =eval(f.read())15 if name in user_dic and password ==user_dic[name]:16 res = fuc(*args, **kwargs)17 current_user['user'] =name18 else:19 print('name and pw error')20
21
22
23 returnres24 returnwrapper25
26 @auth27 defindex():28 print('wellcome to my index')29
30 @auth31 defhome(account):32 print('to the account:%s'%account)33
34 index()35 home('text')
View Code
有参装饰器:
1 #!_*_coding=utf-8_*_
2
3 '''
4 {'zyl':'123'}5 '''
6 current_user={'user':None}7 def auth(auth_type='file'):8 defdeco(fuc):9 def wrapper(*args, **kwargs):10 if auth_type == 'file':11 if current_user['user']:12 return fuc(*args, **kwargs)13 name = input('name:').strip()14 password = input('password:').strip()15 with open('db.txt', 'r', encoding='utf-8') as f:16 user_dic =eval(f.read())17 if name in user_dic and password ==user_dic[name]:18 res = fuc(*args, **kwargs)19 current_user['user'] =name20 returnres21 else:22 print('name and pw error')23
24 elif auth_type == 'mysql':25 print('mysql')26 else:27 print('not valid auth_type')28 returnwrapper29 returndeco30
31 @auth('mysql') #@deco
32 defindex():33 print('wellcome to my index')34
35 @auth()36 defhome(account):37 print('to the account:%s'%account)38
39 index()40 home('text')41 '''mysql42 name: zyl43 password: 12344 to the account:text45 '''
继承函数注释内容
from functools import wraps
@wraps(fuc)放到最里面函数定义的上面
1 #补充一:wraps
2
3 importtime4 from functools importwraps5
6 deftimmer(func):7 @wraps(func)8 def wrapper(*args,**kwargs):9 start=time.time()10 res=func(*args,**kwargs)11 stop=time.time()12 print('run time is %s' %(stop-start))13 returnres14 returnwrapper15
16
17 @timmer #index=timmer(index)
18 defindex():19 '''这是index函数'''
20 time.sleep(3)21 print('welcome to index')22 return 123
23
24 print(index.__doc__)25 print(help(index))
View Code
多层个继承
1 #补充二:一个函数头顶上可以多个装饰器
2 importtime3 from functools importwraps4 current_user={'user':None}5
6 deftimmer(func):7 @wraps(func)8 def wrapper(*args,**kwargs):9 start=time.time()10 res=func(*args,**kwargs)11 stop=time.time()12 print('run time is %s' %(stop-start))13 returnres14 returnwrapper15 def auth(auth_type='file'):16 defdeco(func):17 def wrapper(*args, **kwargs):18 if auth_type == 'file':19 if current_user['user']:20 return func(*args, **kwargs)21 name = input('name:').strip()22 password = input('password:').strip()23
24 with open('db.txt', encoding='utf-8') as f:25 user_dic =eval(f.read())26 if name in user_dic and password ==user_dic[name]:27 res = func(*args, **kwargs)28 current_user['user'] =name29 returnres30 else:31 print('user or password error')32 elif auth_type == 'mysql':33 print('mysql')34
35 elif auth_type == 'ldap':36 print('ldap')37 else:38 print('not valid auth_type')39 returnwrapper40 returndeco41
42
43
44 @timmer #index=timmer(wrapper)
45 @auth() #@deco #index=deco(index) #wrapper
46 defindex():47 '''这是index函数'''
48 time.sleep(3)49 print('welcome to index')50 return 123
51
52 #print(index.__doc__)
53 #print(help(index))
54
55 index()
View Code
三、迭代器
1 #迭代:是一个重复的过程,每一次重复,都是基于上一次的结果而来
2 #while True: #单纯的重复
3 #print('你瞅啥')
4
5 #l=['a','b','c','d']
6 #count=0
7 #while count < len(l):
8 #print(l[count])
9 #count+=1
10
11 dic={'name':'egon','sex':'m',"age":18} #上述按照索引的取值方式,不适于没有索引的数据类型
12
13 #迭代器:
14 #可迭代对象iterable:凡是对象下有__iter__方法:对象.__iter__,该对象就是可迭代对象
15 #s='hello'
16 #l=['a','b','c','d']
17 #t=('a','b','c','d')
18 #dic={'name':'egon','sex':'m',"age":18}
19 #set1={1,2,3}
20 #f=open('db.txt')
21
22 #s.__iter__()
23 #l.__iter__()
24 #t.__iter__()
25 #dic.__iter__()
26 #set1.__iter__()
27 #f.__iter__()
28
29
30 #迭代器对象:可迭代对象执行内置的__iter__方法,得到的结果就是迭代器对象
31
32 #dic={'name':'egon','sex':'m',"age":18}
33 #34 #i=dic.__iter__()
35 ## print(i) #iterator迭代器
36 #37 ## i.__next__() #next(i)
38 #print(next(i))
39 #print(next(i))
40 #print(next(i))
41 #print(next(i)) #StopIteration
42 #43 #l=['a','b','c','d']
44 #45 #i=l.__iter__()
46 #print(next(i))
47 #print(next(i))
48 #print(next(i))
49 #print(next(i))
50 #print(next(i)) #StopIteration
51
52
53
54
55 #不依赖于索引的取值方式
56 #l=['a','b','c','d']
57 #dic={'name':'egon','sex':'m',"age":18}
58 #iter_l=iter(l)
59 #iter_dic=iter(dic)
60 #while True:
61 #try:
62 ## print(next(iter_l))
63 #k=next(iter_dic)
64 #print(k,dic[k])
65 #except StopIteration:
66 #break
67
68
69 #什么是迭代器对象:
70 #1 有__iter__,执行得到仍然是迭代本身
71 #2 有__next__
72
73
74 #迭代器对象的优点
75 #1:提供了一种统一的(不依赖于索引的)迭代方式
76 #2:迭代器本身,比起其他数据类型更省内存
77 #l=['a','b','c','d']
78 #i=iter(l)
79
80 #dic={'a':1,'b':2}
81 #x=dic.keys()
82 #print(x)
83 #i=x.__iter__()
84 #85 #with open('a.txt') as f:
86 ## print(next(f))
87 ## print(next(f))
88 ## print(next(f))
89 #f.read()
90
91
92 #迭代器对象的缺点
93 #1:一次性,只能往后走,不能回退,不如索引取值灵活
94 #2:无法预知什么时候取值结束,即无法预知长度
95 #l=['a','b','c','d']
96 #i=iter(l)
97 #print(next(i))
98 #print(next(i))
99 #print(next(i))
100
101
102 #for循环原理
103
104 #105 #l=['a','b','c','d']
106 #for item in l: #iter_l=l.__iter__()
107 #print(item)
108
109
110 #for item in {1,2,3,4}:
111 #print(item)
112
113
114 #with open('a.txt') as f:
115 ## for line in f: #i=f.__iter__()
116 ## print(line)
117 #print(f is f.__iter__())
118
119
120
121
122
123 #补充:判断可迭代对象与迭代器对象(了解)
124
125 from collections importIterable,Iterator126 s='hello'
127 l=['a','b','c','d']128 t=('a','b','c','d')129 dic={'name':'egon','sex':'m',"age":18}130 set1={1,2,3}131 f=open('a.txt')132
133
134 #print(isinstance(s,Iterable))
135 #print(isinstance(l,Iterable))
136 #print(isinstance(t,Iterable))
137 #print(isinstance(dic,Iterable))
138 #print(isinstance(set1,Iterable))
139 #print(isinstance(f,Iterable))
140
141 print(isinstance(s,Iterator))142 print(isinstance(l,Iterator))143 print(isinstance(t,Iterator))144 print(isinstance(dic,Iterator))145 print(isinstance(set1,Iterator))146 print(isinstance(f,Iterator))
View Code