提问人:feiyang472 提问时间:4/17/2023 更新时间:4/18/2023 访问量:50
使用 Python __call__魔术方法在类中复制“def”
use python __call__ magic method to replicate `def` within class
问:
假设我们有一个充当装饰器的类
class Foo:
def __init__(self, func):
self.func = func
self.variable1 = 1
self.variable2 = 2
def __call__(self, *args, **kwargs):
return self.func(*args, **kwargs)
它不能轻易地用于实例方法
class Bar:
@Foo
def dance(self):
return 0
Bar().dance() # TypeError: missing 1 required positional argument: 'self'
是否可以使行为像内置的 boundmethod,但也允许它具有其他变量,例如?dance()
Bar().dance.variable1
一个相关的问题:我们知道未修饰的具有指向对象的属性。是否可以利用 in ?Bar().__dance__
__self__
Bar
__self__
variable1
答:
2赞
chepner
4/18/2023
#1
Foo
需要是一个描述符,其方法类似于 定义的方法。改编自 https://docs.python.org/3/howto/descriptor.html#functions-and-methods:__get__
function
class Foo:
def __init__(self, func):
self.func = func
self.variable1 = 1
self.variable2 = 2
def __call__(self, *args, **kwargs):
return self.func(*args, **kwargs)
def __get__(self, obj, objtype):
if obj is None:
return self
return types.MethodType(self, obj)
您提到的属性是 返回的值的属性,而不是 的属性。(这是因为计算结果不是函数,而是方法的返回值。__self__
MethodType
__get__
dance
Bar().dance
dance
__get__
不使用类作为装饰器,而是使用函数(已经是描述符)可能更简单。
def Foo(f):
def _(*args, **kwargs):
return f(*args, **kwargs)
return _
评论
self
variable1
@property
variable1
Foo
MethodType(Foo(dance))
__self__
Bar
variable1
Foo
variable1
__self__
self