2019-12-19(303)

10.9 装饰器

在代码运行期间,在不改变原函数定义的基础上,动态给该函数增加功能的方式,称之为装饰器。

装饰器的作用就是为已经存在的对象添加额外的功能。

装饰器其实也是一个函数,一个用来包装函数的函数,返回一个修改之后的函数对象,将其重新赋值给原来的标识符,并永久丧失对原始函数对象的访问。

10.9.1 变量相关-作用域

outerVar="this is a global variable"

def test():

   innerVar="this is a local variable"

   print("local variable:")

   print(locals()) #locals()返回test函数内部本地作用域的变量

   print("global variable:")

   print(globals())

  

test()  


local variable:

{'innerVar': 'this is a local variable'}

global variable:

{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000216DA597588>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'd:\\2019\\py2.py', '__cached__': None, 'outerVar': 'this is a global variable', 'test': <function test at 0x00000216DA6380D8>}

10.9.2 变量相关-变量解析规则

如果在当前作用域中没有找到匹配的变量,会依次向上在闭合作用域中进行查找,所以在函数中直接访问全局变量也是可以的。

outerVar="this is a global variable"

def test():

   innerVar="this is a local variable"

   print(outerVar)

   print(n)

  

n=10

test() 


C:\Users\39621>python d:\2019\py2.py

this is a global variable

10

10.9.3 变量相关-变量生存空间

全局变量的生存周期是在整个程序执行期间有效,局部变量只在当前作用域中有效,一旦这个作用域不存在了,比如函数执行退出了,那么局部变量的生存周期就结束了。

outerVar="this is a global variable"

def test():

   innerVar="this is a local variable"

   print(innerVar)

  

test()  

print(innerVar)


this is a local variable

Traceback (most recent call last):

  File "d:\2019\py2.py", line 9, in <module>

   print(innerVar)

NameError: name 'innerVar' is not defined

10.9.4 变量相关-嵌套函数

函数就是对象,可以把函数像参数一样传递给其他函数或者从函数中返回函数。

def outer():

   name="outerVar"

   def inner():

       print(name)

   return inner()

  

outer()


C:\Users\39621>python d:\2019\py2.py

outerVar

10.9.5 变量相关-函数作为变量

def add(x,y):

   return x+y

 

def sub(x,y):

   return x-y

  

def apply(func,x,y):

   return func(x,y)

  

print(apply(add,1,2))

print(apply(sub,3,1))


C:\Users\39621>python d:\2019\py2.py

3

2

10.9.6 闭包

def outer():

   name="python"

   def inner():

       print(name)

   return inner

 

outer() 

outer()() #-->inner()

print(outer().__closure__)

Ø 如果一个函数定义在另一个函数的作用域内,并引用了外层函数的变量,则该函数称为闭包。外层函数中被引用的变量叫做该函数的环境变量。环境变量和这个函数一起构成了闭包。

Ø 左例中,inner()就是一个闭包,本身是一个函数,并访问name。

Ø outer().__closure__查看闭包变量

Ø 每次outer(),inner函数都会被重新定义,每次的name都一样。修改一下则会不一样,见下例:


def outer(name):

   def inner():

       print(name)

   return inner

 

res1=outer("python") 

res2=outer("java")

res1()

print(res1.__closure__)

res2()

print(res2.__closure__)


C:\Users\39621>python d:\2019\py2.py

python

(<cell at 0x000001AEFA706048: str object at 0x000001AEFA71AC70>,)

java

(<cell at 0x000001AEFA7060D8: str object at 0x000001AEF8B152F0>,)

10.9.7 装饰器

装饰器其实就是一个闭包,把一个函数当作参数后返回一个替代版函数。

def log(func):

   def wrapper():

       print(func.__name__)

       return func()

   return wrapper

  

@log

def now():

   print(time.strftime("%H:%M:%S",time.localtime()))

 

def myfunc():

   print("calling myfunc()")

 

def deco(func):

   print("before calling myfunc()")

   func()

   print("after calling myfunc()")

   return func

 

deco(myfunc)


C:\Users\39621>python d:\2019\py2.py

before calling myfunc()

calling myfunc()

after calling myfunc()
def myfunc():

   print("calling myfunc()")

 

def deco(func):

   print("before calling myfunc()")

   func()

   print("after calling myfunc()")

   return func

 

f=deco(myfunc) 

f()

f()

before calling myfunc()

calling myfunc()

after calling myfunc()

calling myfunc()

calling myfunc()

def deco(func):

   print("before calling myfunc()")

   func()
   

   print("after calling myfunc()")

   return func

  

@deco

def myfunc():

   print("calling myfunc()")

before calling myfunc()

calling myfunc()

after calling myfunc()

def deco(func):

   print("before calling myfunc()")

   func()

   print("after calling myfunc()")

   return func

  

@deco

def myfunc():

   print("calling myfunc()")

  

myfunc()

myfunc()

before calling myfunc()

calling myfunc()

after calling myfunc()

calling myfunc()

calling myfunc()

def deco(func):

   def _deco():

       print("before calling myfunc()")

       func()

       print("after calling myfunc()")

   return _deco

  

@deco

def myfunc():

   print("calling myfunc()")

  

myfunc()

myfunc()

before calling myfunc()

calling myfunc()

after calling myfunc()

before calling myfunc()

calling myfunc()

after calling myfunc()

def deco(func):

   def _deco(a,b):

       print("before calling myfunc()")

       res=func(a,b)

       print("after calling myfunc()")

       print("res:",res)

       return res

   return _deco

  

@deco

def myfunc(a,b):

   print("calling myfunc()")

   print("a+b=",a+b)

   return a+b

  

myfunc(1,2)

myfunc(3,4)

before calling myfunc()

calling myfunc()

a+b= 3

after calling myfunc()

res: 3

before calling myfunc()

calling myfunc()

a+b= 7

after calling myfunc()

res: 7

def deco(func):

   def _deco(*args,**kwargs):

       print("before calling %s" %func.__name__)

       res=func(*args,**kwargs)

       print("after calling %s" %func.__name__)

       print("res:",res)

       return res

   return _deco

  

@deco

def myfunc1(a,b):

   print("calling myfunc()1")

   print("a+b=",a+b)

   return a+b

  

@deco

def myfunc2(a,b,c):

   print("calling myfunc()2")

   print("a+b+c=",a+b+c)

   return a+b+c

  

@deco

def myfunc3(a,b):

   print("calling myfunc()3")

   print("a+b=",a+b)

   return a+b

  

myfunc1(1,2)

myfunc2(1,2,3)

myfunc3(a=3,b=4)

before calling myfunc1

calling myfunc1()

a+b= 3

after calling myfunc1

res: 3

before calling myfunc2

calling myfunc2()

a+b+c= 6

after calling myfunc2

res: 6

before calling myfunc3

calling myfunc3()

a+b= 7

after calling myfunc3

res: 7

def deco(arg):

   def _deco(func):

       def __deco():

            print("before calling %s,[%s]" %(func.__name__,arg))

            func()

            print("after calling %s,[%s]" %(func.__name__,arg))

       return __deco

   return _deco

  

 

@deco("mymodule")

def myfunc1():

   print("calling myfunc1()")

  

  

@deco("module2")

def myfunc2():

   print("calling myfunc2()")

  

myfunc1()

myfunc2()

before calling myfunc1,[mymodule]

calling myfunc1()

after calling myfunc1,[mymodule]

before calling myfunc2,[module2]

calling myfunc2()

after calling myfunc2,[module2]
def deco(arg):

   def _deco(func):

       def __deco(*args,**kwargs):

            print("before calling %s,[%s]" %(func.__name__,arg))

            res=func(*args,**kwargs)

            print("res=",res)

            print("after calling %s,[%s]" %(func.__name__,arg))

       return __deco

   return _deco

  

 

@deco("mymodule")

def myfunc1(a,b):

   print("calling myfunc1()")

   print("a+b=",a+b)

   return a+b

  

@deco("module2")

def myfunc2(a,b):

   print("calling myfunc2()")

   print("a+b=",a+b)

   return a+b

  

  

myfunc1(1,2)

myfunc2(a=3,b=4)

before calling myfunc1,[mymodule]

calling myfunc1()

a+b= 3

res= 3

after calling myfunc1,[mymodule]

before calling myfunc2,[module2]

calling myfunc2()

a+b= 7

res= 7

after calling myfunc2,[module2]
class locker:

   def __init__(self):

       print("locker.__init__() should be not called")

      

   @staticmethod

   def acquire():

       print("locker.acquire() called")

  

   @staticmethod

   def release():

        print("locker.release() called")

      

def deco(cls):

   def _deco(func):

       def __deco():

            print(func.__name__,cls)

            cls.acquire()

            return func()

       return __deco

   return _deco

  

@deco(locker)

def myfunc():

   print("myfunc() called")

  

myfunc()

myfunc() 

myfunc <class '__main__.locker'>

locker.acquire() called

myfunc() called

myfunc <class '__main__.locker'>

locker.acquire() called

myfunc() called

class mylocker:

   def __init__(self):

       print("mylocker.__init__() called")

      

   @staticmethod

   def acquire():

       print("mylocker.acquire() called")

  

   @staticmethod

   def unlock():

       print("mylocker.unlock() called")

      

class lockerex(mylocker):

   @staticmethod

   def acquire():

       print("lockerex.acquire() called")

  

   @staticmethod

   def unlock():

       print("lockerex.unlock() called")

      

def deco(cls):

   def _deco(func):

       def __deco(*args,**kwargs):

            print(func.__name__,cls)

            cls.acquire()

            try:

                return func(*args,**kwargs)

            finally:

                cls.unlock()

       return __deco

   return _deco

  

#以下为另一个文件py3.py

from py2 import *

 

class example:

   @lockhelper(mylocker)

   def myfunc(self):

       print("myfunc() called")

      

   @lockhelper(mylocker)

   @lockhelper(lockerex)

   def myfunc2(self,a,b):

       print("myfunc2() called")

       return a+b

 

if __name__=="__main__":

   a=example()

   a.myfunc()

   print(a.myfunc())

   print(a.myfunc2(1,2))
   

C:\Users\39621>python d:\2019\py3.py

myfunc <class 'py2.mylocker'>

mylocker.acquire() called

myfunc() called

mylocker.unlock() called

myfunc <class 'py2.mylocker'>

mylocker.acquire() called

myfunc() called

mylocker.unlock() called

None

__deco <class 'py2.mylocker'>

mylocker.acquire() called

myfunc2 <class 'py2.lockerex'>

lockerex.acquire() called

myfunc2() called

lockerex.unlock() called

mylocker.unlock() called

3
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值