当前位置:  开发笔记 > 编程语言 > 正文

是否可以在运行时替换函数/方法装饰器?[python]

如何解决《是否可以在运行时替换函数/方法装饰器?[python]》经验,为你挑选了2个好方法。

如果我有一个功能:

@aDecorator
def myfunc1():
  # do something here

if __name__ = "__main__":
  # this will call the function and will use the decorator @aDecorator
  myfunc1() 
  # now I want the @aDecorator to be replaced with the decorator @otherDecorator
  # so that when this code executes, the function no longer goes through
  # @aDecorator, but instead through @otherDecorator. How can I do this?
  myfunc1()

是否可以在运行时替换装饰器?



1> DNS..:

正如Miya所提到的,在解释器获得该函数声明之前,您可以在任何点上用另一个函数替换装饰器.但是,一旦将装饰器应用于该函数,我认为没有办法用另一个动态替换装饰器.例如:

@aDecorator
def myfunc1():
    pass

# Oops! I didn't want that decorator after all!

myfunc1 = bDecorator(myfunc1)

不起作用,因为myfunc1不再是你最初定义的函数; 它已被包裹.这里最好的方法是手动应用装饰器,oldskool-style,即:

def myfunc1():
    pass

myfunc2 = aDecorator(myfunc1)
myfunc3 = bDecorator(myfunc1)

编辑:或者,要更清楚一点,

def _tempFunc():
    pass

myfunc1 = aDecorator(_tempFunc)
myfunc1()
myfunc1 = bDecorator(_tempFunc)
myfunc1()



2> Paolo Tedesc..:

我不知道是否有一种方法可以在应用装饰器后"替换"它,但我想可能没有,因为该功能已被更改.

无论如何,您可能会在运行时根据某些条件应用装饰器:

#!/usr/bin/env python

class PrintCallInfo:
    def __init__(self,f):
        self.f = f
    def __call__(self,*args,**kwargs):
        print "-->",self.f.__name__,args,kwargs
        r = self.f(*args,**kwargs)
        print "<--",self.f.__name__,"returned: ",r
        return r

# the condition to modify the function...
some_condition=True

def my_decorator(f):
    if (some_condition): # modify the function
        return PrintCallInfo(f)
    else: # leave it as it is
        return f

@my_decorator
def foo():
    print "foo"

@my_decorator
def bar(s):
    print "hello",s
    return s

@my_decorator
def foobar(x=1,y=2):
    print x,y
    return x + y

foo()
bar("world")
foobar(y=5)

推荐阅读
mobiledu2402851203
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有