闭包,装饰器,property

其实装饰器它就是一个闭包。装饰器实现的是,返回一个内嵌的函数以及函数所需要的外部变量,给函数增加特定的功能。

什么是闭包?(https://www.bilibili.com/video/av49346682

如果一个函数定义在另一个函数的作用域内,并且引用了外层函数的变量,则该函数称为闭包。

闭包例子:

def outer(name):
def inner():
print(name)
return inner # 返回一个inner函数对象,其实不加括号的函数inner就是一个地址

res = outer('python')
res()

装饰器:

使用装饰函数在函数执行前和执行后分别附加额外功能:

def deco(func):
print("before myfunc() called.")
func()
print("after myfunc() called.")
return func

def myfunc():
print("myfunc() called.")

a = deco(myfunc)
a()

使用语法@来装饰函数:

def deco(func):
print("before myfunc() called.")
func()
print("after myfunc() called.")
return func

@deco # @deco的作用就相当于执行deco(myfunc)
def myfunc():
print("myfunc() called.")

myfunc()

装饰器的实现:

使用内嵌函数(闭包)来确保每次新函数(myfunc函数)执行的时候,装饰器(deco函数)的功能都会被调用:

装饰器的作用就是:在执行myfunc函数的时候,都会执行装饰器(deco函数)里边的功能

def deco(func):
  def _deco():
  print("before myfunc() called.")
  func()
  print("after myfunc() called.")
return _deco

@deco # @deco的作用就相当于执行myfunc = deco(myfunc)
def myfunc():
print("myfunc() called.")

myfunc()

'''
myfunc = deco(myfunc)干了啥呢?

  1.调用deco(myfunc)

  2.返回闭包:_deco+外部变量myfunc

  3.闭包赋值给myfunc

  4.提醒myfunc变成了闭包函数对象

 '''

对带参数函数进行装饰:

def deco(func):
  def _deco(a, b):
  print("before myfunc() called.")
  ret = func(a, b)
  print("after myfunc() called. result: %s"%(ret))
     return ret
return _deco

@deco # @deco的作用就相当于执行myfunc = deco(myfunc)
def myfunc(a, b):
print("myfunc(%s, %s) called."%(a, b))
   return a + b

myfunc(1, 2)
myfunc(3, 4)

对参数数量不确定的函数进行装饰:

def deco(func):
    def _deco(*args, **kwargs):
        print("before %s called."%func.__name__)
        ret = func(*args, **kwargs)
        print("after %s called. result: %s"%(func.__name__, ret))
        return ret
    return _deco

@deco # @deco的作用就相当于执行myfunc = deco(myfunc)
def myfunc(a, b):
    print("myfunc(%s, %s) called."%(a, b))
    return a + b

@deco # @deco的作用就相当于执行myfunc = deco(myfunc2)
def myfunc2(a, b, c):
    print("myfunc2(%s, %s, %s) called."%(a, b, c))
    return a + b + c

myfunc(1, 2)
myfunc(3, 4)
myfunc2(1, 2, 3)
myfunc2(4, 5, 6)

property,让像使用属性一样调用函数。

property属性的两种实现方式:

①装饰器,即在方法上应用装饰器

类中属性有三种访问方式,分别对应了三个被@property、@方法名.setter、@方法名.deleter修饰的方法

class Goods():
def __init__(self):
self.money = 2
@property
def price(self):
print('@property')
return self.money

@price.setter
def price(self, value):
print('@price.setter')
self.money = value

@price.deleter
def price(self):
print('@price.deleter')
del self.money

g = Goods()
print(g.price) # 自动执行@property修饰的price方法,并获取方法的返回值
g.price = 3 # 自动执行@price.setter修饰的price方法,并将3赋值给该方法的参数
print(g.price)
del g.price # 自动执行price.deleter修饰的price方法
print(g.price)

②类属性,即在类中定义值为property对象的类属性

class Goods():
def __init__(self):
self.money = 2

def get_price(self):
print('getter')
return self.money

def set_price(self, value):
print('setter')
self.money = value

def del_price(self):
print('deleter')
del self.money

PRICE = property(get_price, set_price, del_price, 'description...')

g = Goods()
print(g.PRICE) # 自动调用第一个参数中定义的方法:get_price
g.PRICE = 3
print(g.PRICE) # 自动调用第二个参数中定义的方法:set_price
del g.PRICE # 自动调用第三个参数中定义的方法:del_price
print(g.PRICE)



原文地址:https://www.cnblogs.com/wisir/p/12424072.html