八、函数、闭包、装饰器

一、函数对象

 

一、函数对象:把函数的内存地址当作一种变量值去使用
  1、引用
     def func1():
     print('from func')

     #func1=函数的内址

     func2=func1
    func2()
  2、可以当作参数传给另外的函数

  3、可以当作一个函数的返回值

  4、可以当作容器类型的元素

二、名称空间与作用域
  1. 什么是名称空间namespaces

  存放名字与值内存地址绑定关系的地方

  2. 为何要有名称空间

  3. 如何用名称空间

  内置名称空间

  全局名称空间

   局部名称空间

  4. 总结结论:

   1. 查找名字的顺序是从当前位置往外查找

   2. 名称空间的嵌套关系是在函数定义阶段就固定死的,与调用位置无关

二、闭包

1. 什么是闭包函数
  闭函数: 该函数一定是定义在函数内的函数

  包函数: 该内部函数包含对外层函数作用域名字的引用
  def outter():
  x=111
  def inner():
    print(x)
  return inner

  f=outter()

  x=22222
  f()

2. 为何要用闭包函数

3. 如何用

4、为函数体传值的方案一: 直接以参数的形式传入

 为函数体传值的方案二:闭包传值

三、装饰器

1. 什么是装饰器
  装饰器指的是为被装饰对象添加新功能的工具
  装饰器本身可以是任意可调用对象
  被装饰对象本身也可以是任意可调用对象


2. 为何要用装饰器
  开放封闭原则:对修改封闭,对扩展开发

  装饰器的实现原则:
    1. 不能修改被装饰对象的源代码
    2. 不能修改被装饰对象的调用方式

  装饰器的目的:
    就是在遵循原则1和2的前提为被装饰对象添加新功能

3. 如何用

eg:

def outter(func):
# func=index
def wrapper(*args, **kwargs): # 被装饰的函数可带参
start_time = time.time()
func(*args, **kwargs)
stop_time = time.time()
res = stop_time - start_time
return res

return wrapper


@outter # index=outter(index) #outter(index) = wrapper #wrapper = 添加的功能 + index
def index():
time.sleep(1)
print('welcome index page')


@outter
def home(name):
time.sleep(2)
print('welcome home page')
print(name)


res1 = index() # index=outter(index)=wrapper的内存地址 res1=wrapper()
print(res1) # 获取wrapper()函数的返回值是res
res2 = home('egon')
print(res2)

4、叠加多个装饰器
  1. 加载顺序(outter函数的调用顺序):自下而上
  2. 执行顺序(wrapper函数的执行顺序):自上而下


def outter1(func1): #func1=wrapper2的内存地址
print('加载了outter1')
def wrapper1(*args,**kwargs):
print('执行了wrapper1')
res1=func1(*args,**kwargs)
return res1
return wrapper1

def outter2(func2): #func2=wrapper3的内存地址
print('加载了outter2')
def wrapper2(*args,**kwargs):
print('执行了wrapper2')
res2=func2(*args,**kwargs)
return res2
return wrapper2

def outter3(func3): # func3=最原始的那个index的内存地址
print('加载了outter3')
def wrapper3(*args,**kwargs):
print('执行了wrapper3')
res3=func3(*args,**kwargs)
return res3
return wrapper3



@outter1 # outter1(wrapper2的内存地址)======>index=wrapper1的内存地址
@outter2 # outter2(wrapper3的内存地址)======>wrapper2的内存地址
@outter3 # outter3(最原始的那个index的内存地址)===>wrapper3的内存地址
def index():
print('from index')

print('======================================================')
index()

5、有参装饰器
import time

current_user={'user':None}

def outter(func):
def wrapper(*args,**kwargs):
if current_user['user'] is not None:
res=func(*args,**kwargs)
return res

user=input('username>>>: ').strip()
pwd=input('password>>>: ').strip()
if user == 'egon' and pwd == '123':
print('login successfull')
current_user['user']=user
res=func(*args,**kwargs)
return res
else:
print('user or password error')
return wrapper


@outter
def index():
time.sleep(1)
print('from index')

@outter
def home(name):
print('welcome %s' %name)

index()
home('egon')

6、三元表达式
def max2(x,y):
if x > y:
return x
else:
return y

res=max2(10,20)

x=10
y=20

# res=x if x > y else y
# print(res)


res='OK' if False else 'No'
print(res)
7、生成式
列表生成式
l=[]
for i in range(10):
if i > 4:
l.append(i**2)



l=[i**2 for i in range(10) if i > 4]
print(l)


names=['egon','alex_sb','kevin_sb','hxx_sb','cxx_sb']
sbs=[]
for name in names:
if name.endswith('sb'):
sbs.append(name)

sbs=[name.upper() for name in names if name.endswith('sb')]



print([name.upper() for name in names])
print([name for name in names if name.endswith('sb')])


字典生成式
res={i:i**2 for i in range(10) if i > 3}
print(res)


print({i for i in 'hello'})

8、匿名函数
# def func():
# print('from func')
#
#
# func()
# func()
# func()
# 匿名函数就是只定义了一个函数的内存地址,主要用于临时使用一次的场景
# func=lambda x,y:x+y
# print(func)
# print(func(1,2))

# res=(lambda x,y:x+y)(1,2)
# print(res)


# print(max([10,11,-3,23]))
salaries={
'egon':3000,
'alex':100000000,
'wupeiqi':10000,
'yuanhao':2000
}
# def func(k):
# return salaries[k]

# print(max(salaries,key=lambda k:salaries[k]))
# print(min(salaries,key=func))
# for循环的结果 比较依据
# 'egon' 3000
# 'alex' 100000000
# 'wupeiqi' 10000
# 'yuanhao' 2000

# l=[4,2,3]
# l_new=sorted(l,reverse=True)
# print(l_new)


print(sorted(salaries,key=lambda k:salaries[k],reverse=True))











 
 
 

 

 
 



原文地址:https://www.cnblogs.com/lanlan999/p/10040426.html