第一节:函数
函数嵌套:在调用一个函数的过程中又调用了其他函数
x = 1000
def f1():
#x=1
print('------>f1 ',x)
def f2():
x = 2
print('---->f2 ',x)
def f3():
x=3
print('-->f3 ',x)
f3()
f2()
f1()
名称空间与作用域
名称空间:Python所有有关命名的操作都是在操作名称空间,例如变量名,函数名
1、内置名称空间:Python解释器提供好的功能,解释器启动跟着一起启动,是全局作用域
2、全局名称空间:Python中顶行写的,不在函数内部定义的,都是全局名称空间,在运行的时候会产生名称空间,是全局作用域
3、局部名称空间:在一个小范围定义,只能当前范围及其子空间内运行,例如在函数内部定义的,是局部作用域
python的作用域规则里面,创建变量一定会一定会在当前作用域里创建一个变量,但是访问或者修改变量时会先在当前作用域查找变量,没有找到匹配变量的话会依次向上在闭合的作用域里面进行查看找。
闭包函数:内部函数的代码包含对外部作用域的引用,但一定不是对全局作用域的引用,闭包函数一定有__closure__方法
第二节、装饰器
装饰器其实就是一个闭包,把一个函数当做参数然后返回一个替代版函数
def login(func):
def foo(*args,**kwargs):
username = input('username:')
password = input('password:')
with open('db.txt',encoding='utf-8') as f:
dic=eval(f.read())
if username in dic and password == dic[username]:
print(("{na} successfully login ").format(na=username))
else:
print("failed login")
res=func(*args,**kwargs)
return res
return foo
@login
def foo(username,password):
print(username,password)
@login
def aaa():
print("welcome!!!")
login("you","hao")
aaa()
第三节、生成器:一边循环一边计算的机制,成为生成器
1.列表生成式:使代码更简洁
print ([i*2 for i in range(10)])
相当于 :
a = []
for i in range(10):
a.append(i * 2)
print(a)
第一种方法:把列表生成式的[]改成()
example:
g=((i*2 for i in range(10)))
print(g)
g[8]直接打印不了
生成器只有在调用时才会生成相应的数据(可以用next方法)
生成器只记住当前位置,不记住前面不记住后面,不能返回前面
只有一个next方法
example:# g.__next__()
g=((i*2 for i in range(10)))
print(g.__next__())
print(g.__next__())
会打印出0、2
第二种方法:函数
斐波那契数列:除第一个第二个数字外,其他任意一个数都可以由前两个相加得到
example:
def fib(max):
n,a,b=0,0,1
while n<max:
print(b)
a,b=b,a+b
n=n+1
return ‘done'
fib(10)
要变成生成器:把print(b)变成yield b
def fib(max):
n,a,b=0,0,1
while n<max:
yield b
a,b=b,a+b
n=n+1
return ‘done'
f=fib(10)
print (f.__next__())
print (f.__next__())
example2:
def fib(max):
n,a,b=0,0,1
while n<max:
yield b
a,b=b,a+b
n=n+1
return ‘done'
f=fib(100)
print (f.__next__())
print (f.__next__())
print (f.__next__())
for i in f:
print(i)
可以全部打印出来
2.yield实现多线程
example:
import time
def consumer(name):
print("%s 准备吃包子啦!" %name)
while True:
baozi = yield
print("包子[%s]来了,被[%s]吃了!" %(baozi,name))
def producer(name):
c = consumer('A')
c2 = consumer('B')
c.__next__()
c2.__next__()
print("老子开始准备做包子啦!")
for i in range(10):
time.sleep(1)
print("做了2个包子!")
c.send(i)
c2.send(i)
producer(‘a’)#执行
yield保存了函数的中断状态
send可以把值传给yield
第四节、迭代器
直接作用于for循环的数据类型有以下几种:
一类是集合数据类型,如list、tuple、dict、set、str等;
一类是generator,包括生成器和带yield的generator function。
这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。
可以使用isinstance()判断一个对象是否是Iterable对象:(可迭代对象)
>>> from collections import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True
>>> isinstance('abc', Iterable)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False
*可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。
可以使用isinstance()判断一个对象是否是Iterator对象:(迭代器)
>>> from collections import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False
生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。
把list、dict、str等Iterable变成Iterator可以使用iter()函数:
>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True
example:
# 首先获得Iterator对象:
it = iter([1, 2, 3, 4, 5])
# 循环:
while True:
try:
# 获得下一个值:
x = next(it)
except StopIteration:
# 遇到StopIteration就退出循环
break