【问题标题】:basic question for python decorator mechanismpython装饰器机制的基本问题
【发布时间】:2021-09-10 12:58:34
【问题描述】:

我是 Python 的新手。当我学习装饰和类。有些东西我完全不明白

当我们看一个装饰器的例子时:

class Log_dec(object):

    def __init__(self, func):
        self.func = func
    def __call__(self, args):
        print('do something before function')
        Result=self.func(args)
        print(Result)
        print('do something after function')
@Log_dec
def myFunc(name):
    return 'My Name is %s'%name
myFunc('Haha')

结果是:

do something before function
My Name is Haha
do something after function

如果我们与另一个例子进行比较:

class Log_dec(object):

    def __init__(self, func):
        self.func = func
    def __call__(self, args):
        print('do something before function')
        Result=self.func(args)
        print(Result)
        print('do something after function')
    def __CallTwice__(self,a_default_variable):
        print('do something different')
        Result_2=self.func(a_default_variable)
        print(Result_2)

@Log_dec
def myFunc(name):
    return 'My Name is %s'%name
myFunc('Haha')

结果还是:

do something before function
My Name is Haha
do something after function

似乎当我们执行myFunc('Haha')时,函数myFunc进入__init__中的func,而字符串Haha进入__call__中的args

我的问题是,为什么字符串Haha 不进入a_defult_variable 中的__CallTwice__ ???这让我很困惑。

或者让我们说,为什么函数myFunc 不进入__CallTwice__ 中的a_default_variable。因为我认为显然def __init__(self, func):def __CallTwice__(self,a_default_variable): 具有相同的格式 是吗?

【问题讨论】:

  • 忽略@ 语法。会发生什么是now = log(now)。所以now 现在是wrapper 函数。这有帮助吗?
  • 如果'now'是'wrapper',为什么我们使用'return func(*args,**kw)'而不是'return wrapper(*args,**kw)'?跨度>
  • @lululu 无限递归,然后原函数log会被完全忽略,这不是装饰器的作用。
  • wrapper 的任务是使用任意参数调用func(这里:func=now),然后做一些额外的事情(这里:print 一些东西)。如果你在return func(*args,**kw) 的位置使用return wrapper(*args,**kw),你将有无限递归,wrapper 永远调用自己。
  • 我想你已经注意到了:stackoverflow.com/questions/739654/…?

标签: python decorator


【解决方案1】:

这个答案只是用自记录名称重写你的例子,没有@-syntax。

def create_new_function_from_existing_function(old_function): # def log
    def new_function(*some_positional_arguments, **some_keyword_arguments): # define wrapped function
        print('call %s:' % old_function.__name__)
        return old_function(*some_positional_arguments, **some_keyword_arguments)
    return new_function # return wrapped function

def now(x, y):
    print('2021-9-3 value=', x + y)

now = create_new_function_from_existing_function(now) # @log ...

【讨论】:

    猜你喜欢
    • 2022-01-18
    • 1970-01-01
    • 1970-01-01
    • 2017-09-20
    • 1970-01-01
    • 2021-07-07
    • 2018-03-04
    • 2016-03-23
    • 1970-01-01
    相关资源
    最近更新 更多