Discuss / Python / 对装饰器还是不理解

对装饰器还是不理解

Topic source
def log(func):
   # def wraper():
    print('%s %s:'%("ehllo",func.__name__))
    return func
    #return wraper

@log
def now():
    print(datetime.now())

这样运行结果也是可以的啊!??为什么要写wraper这个包裹函数??还有后面的带参数的装饰器,为什么还要三重包裹函数,希望廖老师解答下!

同问

如果是加参数呢?你执行看看。

加参数一样可以不要最里面那个包裹函数啊!

def log(text):
    def decorator(func):
        print('%s %s():'%(text,func.__name__))
        return func

    return decorator

这样也可以啊!

还有不明白的是如果按照我上面所写的,返回的应该只是个函数名,不应该执行啊,为什么运行的效果是func函数执行了??

yooke_11916

#5 Created at ... [Delete] [Delete and Lock User]

你使用这个log装饰器两次就知道区别了,比如:

@log
def f1():
    print('exec f1()')

@log
def f2():
    print('exec f2()')

f1()
f2()

同样是不知道为什么加一个包裹函数,廖老师现身吧

KiArser

#7 Created at ... [Delete] [Delete and Lock User]

我说下我的想法

@log
def now():
...

这里实际是相当于 now = log(now)

def log(func):
   # def wraper():
    print('%s %s:'%("ehllo",func.__name__))
    return func      # return old func not log(func)
    #return wraper

不加包裹函数,log()的返回函数仍然是原来的now 并且虽然返回值是个函数名,但是因为print函数自身是执行的,所以就输出结果了。

补充一下,不加wrapper的话,你试试直接这么调用

now

得到的结果是:

hello now

再比如你希望把now赋值给一个变量:

f1 = now

但是它已经执行log函数的逻辑代码,这就是为什么加上一个wrapper的原因

Nemo尼谟

#9 Created at ... [Delete] [Delete and Lock User]

这个我也是想了很久,说一下我的理解 举个例子:

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

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

myfunc()
myfunc()

自己看一下两次调用结果

然后再加入包裹函数

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

    return _deco

@deco
def myfunc():
    print(" myfunc() called.")
    return 'ok'

myfunc()
myfunc()

这次的结果就正常多了

仔细思考一下 就能知道加包裹函数的意义了

如果你给一个带参数的

def f(x):
    pass

加装饰器的话,你会发现调用的时候参数是使用不了的


  • 1
  • 2

Reply