python_day04 函数嵌套 名称空间和作用域 闭包 装饰器 迭代器 生成器 列表解析 三元表达式 生成器表达式

本节课重要知识点内容如下:

函数嵌套

名称空间和作用域

闭包

装饰器

迭代器

生成器

列表解析

三元表达式

生成器表达式

1、函数嵌套

函数的嵌套调用:在调用一个函数的过程中,又调用了其他函数
函数的嵌套定义:在一个函数的内部,又定义另外一个函数
def bar():
print('from nbar')
def foo():
print('from foo')
bar()
foo()
def max2(x,y):
if x > y:
return x
else:
return y
def max4(a,b,c,d):
res1=max2(a,b)
res2=max2(res1,c)
res3=max2(res2,d)
return res3
print(max4(1,2,3,-1))
def f2():
print('from f2')
def f1():
x=1
# def f2()
# print('from f2')
f2()
f1()

名称空间和作用域

名称空间:存放名字的地方,准确的说名称空间是存放名字与变量值绑定关系的地方
内置名称空间:在python解释器启动时产生,存放一些python内置的名字
全局名称空间:在执行文件时产生,存放文件级别定义的名字
局部名称空间:在执行文件的过程中,如果调用了函数,则会产生该函数的局部名称空间。用来存放该函数内定义的名字,该名字在函数调用时生效,在函数调用结束后失效
加载顺序:内置---》全局---》局部
优先掌握一:名字的查找顺序是:局部-》全局-》内置
 x=1
def func():
y=2
def f1():pass
print
import os
class Foo:
pass
if x==1:z=3
del x
# max=1
def foo():
max=2
# print(max)
foo()
print(max)
x=0
def f1():
x=1
def f2():
x=2
def f3():
x=3
print(x)
f3()
f2()
print('=f1========',x)
f1()

def func1():
print('from func1')
def func1():
print('=====?>')
func1()
作用域:作用的范围,
全局作用域:全局存活,全局有效:globals()
局部作用域:临时存活,局部有效:locals()
global nonlocal掌握
优先掌握二:作用域关系,在函数定义时就已经固定,于调用位置无关,在调用函数时,必须必须必须回到函数原来定义的位置去找作用域关系
max=1111111
def f1():
def f2():
def f3():
def f4():
# print(x)
print(max)
f4()
f3()
f2()
f1()
x=11111111111111111111111111111111111111111111
def f1():
x=1
y=2
def f2():pass
# print(locals())
print(globals())
f1()
print(locals() is globals())
print(locals())
print(dir(globals()['__builtins__']))
# global nonlocal掌握
x=1
def f1():
global x #局部避免改全局名字。#x是不可变类型
x=2
f1()
print(x)
l=[]
def f2():
l.append('f2') #list是可变类型,不需要global关键字也会改全局值
f2()
print(l)

x=0
def f1():
# x=1
def f2():
# x=2
def f3():
# global x
nonlocal x #nonlocal更改函数的上一级函数名称。nonlocal只能在局部改
x=3
f3()
# print(x)
f2()
print(x)
f1()
print(x)
x=1
def f1():
def f2():
print(x)
return f2
func=f1()

print(func)
func()
x=10000000
func()

def foo(func):
x=300000000
func() #f2()
foo(f1())
x=10000000000000000000000
foo(f1())

闭包

大前提:作用域关系,在函数定义时就已经固定,于调用位置无关,在调用函数时,必须必须必须回到函数原来定义的位置去找作用域关系闭包函数:
1. 定义在函数内部的函数
2. 包含对外部作用域名字的引用,而不是对全局作用域名字的引用
那么该内部函数就称为闭包函数
闭包函数的应用:惰性计算
x=1
def f1():
x=11111111111
def f2():
print(x)
return f2
func=f1()

x=1000
func()
def foo():
x=12312312312312312312312312312312312313123
func()
foo()
def deco():
x=123123123123
def wrapper():
print(x)
return wrapper
func=deco()
func()

# 闭包函数的应用:惰性计算
# import requests #pip3 install requests
def get(url):
# return requests.get(url).text
return url
print(get('https://www.python.org')
def index(url):
# url='https://www.python.org'
def get():
# return requests.get(url).text
print(url)
return get
python_web=index('https://www.python.org')
baidu_web=index('https://www.baidu.com')
python_web()
baidu_web()
name='egon'
def index(url):
x=1
y=2
def wrapper():
x
y
# return requests.get(url).text
print(name)
return wrapper
python_web=index('https://www.python.org')
print(python_web.__closure__)
print(python_web.__closure__[0].cell_contents)
print(python_web.__closure__[1].cell_contents)
print(python_web.__closure__[2].cell_contents)

 装饰器

1 开放封闭原则:对扩展是开放的,对修改是封闭
2 装饰器:装饰它人的工具,
装饰器本身可以是任意可调用对象,被装饰的对象本身也可以是任意可调用对象
2.1 装饰器的遵循的原则:1 不修改被装饰对象的源代码 2 不修改被调用对象的调用方式
2.2 装饰器的目的是:在遵循1和2原则的前提,为其他新功能函数添加
@装饰器名,必须写在被装饰对象的正上方,并且是单独一行
补充一:wraps将原函数注释信息等加载到装饰函数中
补充二:一个函数头顶上可以多个装饰器
import time
def timmer(func):
# func=index
def wrapper():
start=time.time()
func()
stop=time.time()
print('run time is %s' %(stop-start))
return wrapper
@timmer # index=timmer(index)
def index():
time.sleep(3)
print('welcome to index')
@timmer # home=timmer(home)
def home():
time.sleep(2)
print('welcome to home page')
index()
home()
# 补充一:wraps将原函数注释信息等加载到装饰函数中
import time
from functools import wraps
def timmer(func):
@wraps(func)
def wrapper(*args,**kwargs):
start=time.time()
res=func(*args,**kwargs)
stop=time.time()
print('run time is %s' %(stop-start))
return res
return wrapper
@timmer # index=timmer(index)
def index():
'''这是index函数'''
time.sleep(3)
print('welcome to index')
return 123
print(index.__doc__)
print(help(index))

# 补充二:一个函数头顶上可以多个装饰器
import time
from functools import wraps
current_user={'user':None}
def timmer(func):
@wraps(func)
def wrapper(*args,**kwargs):
start=time.time()
res=func(*args,**kwargs)
stop=time.time()
print('run time is %s' %(stop-start))
return res
return wrapper
def auth(auth_type='file'):
def deco(func):
def wrapper(*args, **kwargs):
if auth_type == 'file':
if current_user['user']:
return func(*args, **kwargs)
name = input('name: ').strip()
password = input('password: ').strip()

with open('db.txt', encoding='utf-8') as f:
user_dic = eval(f.read())
if name in user_dic and password == user_dic[name]:
res = func(*args, **kwargs)
current_user['user'] = name
return res
else:
print('user or password error')
elif auth_type == 'mysql':
print('mysql')

elif auth_type == 'ldap':
print('ldap')
else:
print('not valid auth_type')
return wrapper
return deco
@timmer #index=timmer(wrapper)
@auth() # @deco #index=deco(index) #wrapper
def index():
'''这是index函数'''
time.sleep(3)
print('welcome to index')
return 123
# print(index.__doc__)
# print(help(index))
index()
#有返回值的装饰器函数
import time
def timmer(func):
def wrapper(*args,**kwargs):
start=time.time()
res=func(*args,**kwargs)
stop=time.time()
print('run time is %s' %(stop-start))
return res
return wrapper
@timmer # index=timmer(index)
def index():
time.sleep(3)
print('welcome to index')
return 123
@timmer # home=timmer(home)
def home(name):
time.sleep(2)
print('welcome %s to home page' %name)
res=index() #res=wrapper()
print(res)
res1=home('egon') #wrapper('egon')
print(res1)
#无参装饰器版本
current_user={'user':None}
def auth(func):
def wrapper(*args,**kwargs):
if current_user['user']:
return func(*args,**kwargs)
name=input('name: ').strip()
password=input('password: ').strip()
with open('db.txt', encoding='utf-8') as f:
user_dic = eval(f.read())
if name in user_dic and password == user_dic[name]:
res=func(*args,**kwargs)
current_user['user']=name
return res
else:
print('user or password error')
return wrapper
@auth #index=auth(index) index=wrapper
def index():
print('from index')
index()
@auth
def home(name):
print('welcome %s' %name)
index() #wrapper()
home('egon')


#有参装饰器版本
current_user={'user':None}
def auth(auth_type='file'):
def deco(func):
def wrapper(*args, **kwargs):
if auth_type == 'file':
if current_user['user']:
return func(*args, **kwargs)
name = input('name: ').strip()
password = input('password: ').strip()

with open('db.txt', encoding='utf-8') as f:
user_dic = eval(f.read())
if name in user_dic and password == user_dic[name]:
res = func(*args, **kwargs)
current_user['user'] = name
return res
else:
print('user or password error')
elif auth_type == 'mysql':
print('mysql')

elif auth_type == 'ldap':
print('ldap')
else:
print('not valid auth_type')
return wrapper
return deco
@auth(auth_type='mysql') #@deco #index=deco(index)
def index():
print('from index')
@auth(auth_type='file')
def home(name):
print('welcome %s' %name)
index() #wrapper()
home('egon')

迭代器

迭代:是一个重复的过程,每一次重复,都是基于上一次的结果而来
迭代器:
可迭代对象iterable:凡是对象下有__iter__方法:对象.__iter__,该对象就是可迭代对象
迭代器对象:可迭代对象执行内置的__iter__方法,得到的结果就是迭代器对象
什么是迭代器对象:
1 有__iter__,执行得到仍然是迭代本身
2 有__next__
迭代器对象的优点
1:提供了一种统一的(不依赖于索引的)迭代方式
2:迭代器本身,比起其他数据类型更省内存
迭代器对象的缺点
1:一次性,只能往后走,不能回退,不如索引取值灵活
2:无法预知什么时候取值结束,即无法预知长度
补充:判断可迭代对象与迭代器对象(了解)
print(isinstance(set1,Iterable))
print(isinstance(f,Iterable))
while True: #单纯的重复
print('你瞅啥')
l=['a','b','c','d']
count=0
while count < len(l):
print(l[count])
count+=1
dic={'name':'egon','sex':'m',"age":18} #上述按照索引的取值方式,不适于没有索引的数据类型
#可迭代对象
s='hello'
l=['a','b','c','d']
t=('a','b','c','d')
dic={'name':'egon','sex':'m',"age":18}
set1={1,2,3}
f=open('db.txt')
s.__iter__()
l.__iter__()
t.__iter__()
dic.__iter__()
set1.__iter__()
f.__iter__()
# 迭代器对象:可迭代对象执行内置的__iter__方法,得到的结果就是迭代器对象
dic={'name':'egon','sex':'m',"age":18}
i=dic.__iter__()
print(i) #iterator迭代器
i.__next__() #next(i)
print(next(i))
print(next(i))
print(next(i))
print(next(i)) #StopIteration
l=['a','b','c','d']
i=l.__iter__()
print(next(i))
print(next(i))
print(next(i))
print(next(i))
print(next(i)) #StopIteration
#不依赖于索引的取值方式
l=['a','b','c','d']
dic={'name':'egon','sex':'m',"age":18}
iter_l=iter(l)
iter_dic=iter(dic)
while True:
try:
# print(next(iter_l))
k=next(iter_dic)
print(k,dic[k])
except StopIteration:
break

l=['a','b','c','d']
i=iter(l)
dic={'a':1,'b':2}
x=dic.keys()
print(x)
i=x.__iter__()
with open('a.txt') as f:
print(next(f))
print(next(f))
print(next(f))
f.read()
#for循环原理
l=['a','b','c','d']
for item in l: #iter_l=l.__iter__()
print(item)
for item in {1,2,3,4}:
print(item)
with open('a.txt') as f:
# for line in f: #i=f.__iter__()
# print(line)
print(f is f.__iter__())
#补充:判断可迭代对象与迭代器对象(了解)
from collections import Iterable,Iterator
s='hello'
l=['a','b','c','d']
t=('a','b','c','d')
dic={'name':'egon','sex':'m',"age":18}
set1={1,2,3}
f=open('a.txt')
print(isinstance(s,Iterable))
print(isinstance(l,Iterable))
print(isinstance(t,Iterable))
print(isinstance(dic,Iterable))
print(isinstance(set1,Iterable))
print(isinstance(f,Iterable))
print(isinstance(s,Iterator))
print(isinstance(l,Iterator))
print(isinstance(t,Iterator))
print(isinstance(dic,Iterator))
print(isinstance(set1,Iterator))
print(isinstance(f,Iterator))

生成器

生成器:在函数内部包含yield关键,那么该函数执行的结果是生成器
生成器就是迭代器
yield的功能:
1 把函数的结果做生迭代器(以一种优雅的方式封装好__iter__,__next__)
2 函数暂停与再继续运行的状态是由yield
raise StopIteration #产生一个异常
yield与return的比较?
相同:都有返回值的功能
不同:return只能返回一次值,而yield可以返回多次值
生成器表达式
def func():
print('first')
yield 11111111
print('second')
yield 2222222
print('third')
yield 33333333
print('fourth')
g=func()
print(g) #generator
from collections import Iterator
print(isinstance(g,Iterator))
print(next(g))
print('======>')
print(next(g))
print('======>')
print(next(g))
print('======>')
print(next(g)) #StopIteration
for i in g: #i=iter(g)
print(i)
#无限数字生成器
def func(n):
print('我开动啦')
while True:
yield n
n+=1
g=func(0)
print(next(g))
print(next(g))
print(next(g))
for i in g:
print(i)
for i in range(10000):
print(i)
def my_range(start,stop):
while True:
if start == stop:
raise StopIteration #产生一个异常
yield start #2
start+=1 #3
g=my_range(1,3)
print(next(g))
print(next(g))
print(next(g))
for i in my_range(1,3):
print(i)
# python3 tail.py -f access.log | grep 'error'
import time
def tail(filepath):
with open(filepath, 'r') as f:
f.seek(0, 2)
while True:
line = f.readline()
if line:
yield line
else:
time.sleep(0.2)
def grep(pattern,lines):
for line in lines:
if pattern in line:
print(line,end='')
grep('error',tail('access.log'))
#追加内容
with open('access.log','a') as f:
f.write('22222error ')

列表解析

l=['egg%s' %i for i in range(10)  if i >=5]
l=[]
for i in range(10):
if i >=5:
l.append('egg%s' %i)
print(l)
# 列表解析
for i0 in ...:
if 条件1:
for i1 in ...:
if 条件2:
for i2 in ...:
if 条件3:
pass
l=['egg%s' %i for i in range(10) if i >=5]
print(l)

nums=[1,2,3,4,5,6]
nums_new=[item**2 for item in nums if item > 3]
print(nums_new)

nums_new=[]
for item in nums:
nums_new.append(item**2)
print(nums_new)

names=['alex_sb','wupeiqi_sb','egon','yuanhao_sb']
names_new=[name for name in names if name.endswith('sb')]
print(names_new)

三元表达式

res=x if x > 3 else 'no'
def foo(x):
if x > 3:
return 'ok'
else:
return 'no'
x=10
res=x if x > 3 else 'no'
print(res)

def max2(x,y):
return x if x > y else y
print(max2(1,3))

name='egon'
print('SB' if name == 'alex' else 'shuai')

生成器表达式

#生成器表达式
g=('egg%s' %i for i in range(1000))
print(g)
print(next(g))
print(next(g))
print(next(g)

with open('a.txt',encoding='utf-8') as f:
# res=max((len(line) for line in f))
res=max(len(line) for line in f)
print(res)
print(max([1,2,3,4,5,6]))
#生成器应用
res=sum(i for i in range(3))
print(res)

with open('db.txt',encoding='utf-8') as f:
l=(float(line.split()[1])*int(line.split()[2]) for line in f)
print(sum(l))

# [{'name': 'apple', 'price': 333, 'count': 3}, ]
with open('db.txt',encoding='utf-8') as f:
info=[{'name':line.split()[0],
'price':float(line.split()[1]),
'count':int(line.split()[2])} for line in f if float(line.split()[1]) >= 30000]
print(info)
原文地址:https://www.cnblogs.com/liweijing/p/7228328.html