[英]How to implement instance-dependent functionality using parent class decorator?
I would like to implement a parent class decorator in my child class whose functionality depends on the state of the child class instance. 我想在子类中实现父类装饰器,该子类的功能取决于子类实例的状态。 I've tried coming at this problem from three different angles, none of which have worked: 我尝试从三个不同的角度来解决这个问题,但没有一个起作用:
If give_feedback
is a static method, there's no self
within the method. 如果give_feedback
是静态方法,则该方法内没有self
。 But if it's an instance method, there's no self
within the namespace in which it's applied. 但是,如果它是一个实例方法,则在应用它的名称空间中就不会存在self
。
class Interface:
def __init__(self, quiet=False):
self.quiet = quiet
def echo(self, text):
if not self.quiet:
print(text)
def give_feedback(self, func):
def wrapper(*args):
print('Calling give_feedback.')
self.echo(func(*args))
return wrapper
class App(Interface):
@Interface.give_feedback # self not defined here.
def app_func(self, num):
feedback = 'Success with {num}'.format(num=num)
return feedback
if __name__ == '__main__':
a = App()
a.app_func(3)
Can't access the object from within __call__
. 无法从__call__
内访问对象。
class Interface:
# ...
class give_feedback:
def __init__(self, func):
self.func = func
def __call__(self, *args):
print(
'Calling {func}'.format(func=self.func)
)
instance = get_obj_instance(self.func) # What is this?
return instance.echo(self.func(instance, *args))
class App(Interface):
# ...
if __name__ == '__main__':
# ...
Can access the object, but no arguments. 可以访问对象,但没有参数。
class Interface:
# ...
class give_feedback:
# ...
def __get__(self, instance, owner):
print(
'Getting {func} from {inst} of {ownr}'.format(
func=self.func, inst=instance, ownr=owner
)
)
num = 2 # How to get num???
return instance.echo(self.func(instance, num))
class App(Interface):
# ...
if __name__ == '__main__':
a = App()
a.app_func # No ability to pass parameters.
Is there a good way to do this? 有什么好方法吗?
Why not combine the 2nd and 3rd methods? 为什么不结合第二种方法和第三种方法? Use __get__
to get the class instance, and __call__
to decorate with echo
. 使用__get__
获取类实例,并使用__call__
用echo
装饰。 Rather than returning app_func
, return a new object that holds the instance and has the desired __call__
behavior. 而不是返回app_func
,而是返回一个保存实例并具有所需__call__
行为的新对象。
class Interface:
def __init__(self, quiet=False):
self.quiet = quiet
def echo(self, text):
if not self.quiet:
print(text)
class give_feedback:
def __init__(self, func):
self.func = func
def __get__(self, instance, owner):
return self.InstHolder(instance, self.func)
class InstHolder:
def __init__(self, inst, func):
self.inst = inst
self.func = func
def __call__(self, *args):
return self.inst.echo(self.func(self.inst, *args))
class App(Interface):
@Interface.give_feedback
def app_func(self, num):
feedback = 'Success with {num}'.format(num=num)
return feedback
if __name__ == '__main__':
a = App()
a.app_func(3)
a.quiet = True
a.app_func(4)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.