为什么有必要将 self 作为方法装饰器的参数?
Why is it necessary to place self as a parameter for method decorators?
对于模块级函数,此代码成立:
def dec(f):
def wrap(*args, **kwargs):
f(*args, **kwargs)
return wrap
@dec
def foo(arg1):
pass
然而,当修饰方法时,突然间您必须有一个参数来捕获实例。
def dec(f):
def wrap(self, *args, **kwargs):
f(self, *args, **kwargs)
return wrap
class Test:
def __init__(self):
pass
@dec
def foo(self, arg1):
pass
为什么会这样? self
有什么特别之处以至于 *args
无法捕捉到它?毕竟这不只是另一个位置参数吗?
另外,它 (self
) 是如何传递到内部 wrap
函数中的?
对于第一种情况,它只是等同于foo = dec(foo)
。根据我对闭包的了解,在 foo
作为参数传递给装饰器之前。它创建了一个包含 __closure__
的外壳,因此它能够保留传递给 foo
.
的任何参数
为什么说到方法,显然 self
似乎不属于 __closure__
?
我觉得Python的作者本人说得最好:
http://neopythonic.blogspot.com/2008/10/why-explicit-self-has-to-stay.html
主要有两点:
There's a pretty good argument to make that requiring explicit 'self' in the parameter list reinforces the theoretical equivalency between these two ways of calling a method.
和
Another argument for keeping explicit 'self' in the parameter list is the ability to dynamically modify a class by poking a function into it, which creates a corresponding method.
Why is that the case? What's so special about self
that *args
isn't able to catch it?
这个问题基于一个有缺陷的前提。事实上,*args
可以包含 self
,无论是否使用装饰器。以下两个示例说明了这一点。
没有装饰器:
class Test(object):
def foo(self, *args):
return (self,) + args
def bar(*args): # for the purposes of illustration
return args
t = Test()
print(t.foo(42))
print(t.bar(42))
有装饰器:
def dec(f):
def wrap(*args, **kwargs):
return f(*args, **kwargs)
return wrap
class Test(object):
@dec
def foo(self, arg1):
return (self, arg1)
t = Test()
print(t.foo(42))
对于模块级函数,此代码成立:
def dec(f):
def wrap(*args, **kwargs):
f(*args, **kwargs)
return wrap
@dec
def foo(arg1):
pass
然而,当修饰方法时,突然间您必须有一个参数来捕获实例。
def dec(f):
def wrap(self, *args, **kwargs):
f(self, *args, **kwargs)
return wrap
class Test:
def __init__(self):
pass
@dec
def foo(self, arg1):
pass
为什么会这样? self
有什么特别之处以至于 *args
无法捕捉到它?毕竟这不只是另一个位置参数吗?
另外,它 (self
) 是如何传递到内部 wrap
函数中的?
对于第一种情况,它只是等同于foo = dec(foo)
。根据我对闭包的了解,在 foo
作为参数传递给装饰器之前。它创建了一个包含 __closure__
的外壳,因此它能够保留传递给 foo
.
为什么说到方法,显然 self
似乎不属于 __closure__
?
我觉得Python的作者本人说得最好:
http://neopythonic.blogspot.com/2008/10/why-explicit-self-has-to-stay.html
主要有两点:
There's a pretty good argument to make that requiring explicit 'self' in the parameter list reinforces the theoretical equivalency between these two ways of calling a method.
和
Another argument for keeping explicit 'self' in the parameter list is the ability to dynamically modify a class by poking a function into it, which creates a corresponding method.
Why is that the case? What's so special about
self
that*args
isn't able to catch it?
这个问题基于一个有缺陷的前提。事实上,*args
可以包含 self
,无论是否使用装饰器。以下两个示例说明了这一点。
没有装饰器:
class Test(object):
def foo(self, *args):
return (self,) + args
def bar(*args): # for the purposes of illustration
return args
t = Test()
print(t.foo(42))
print(t.bar(42))
有装饰器:
def dec(f):
def wrap(*args, **kwargs):
return f(*args, **kwargs)
return wrap
class Test(object):
@dec
def foo(self, arg1):
return (self, arg1)
t = Test()
print(t.foo(42))