我试图为类中的每个函数创建一个方法,每次调用函数时都会调用该方法。这个类是另一个类的子类(在我的特定例子中,它是list
的子类)。
class Foo(another_class):
def __init__(self, bar):
self.bar = bar
super().__init__(self.bar)
def function_to_be_called(self):
self.bar += 1
def function(self):
# do stuff
foo = Foo(0)
foo.function()
foo.inherited_function()
print(foo.bar) # should be 2, since function and inherited_function were called
我发现an answer建议覆盖__getattribute__
魔术方法,但这样做会导致无限递归(因为调用的函数需要首先使用__getattribute__
找到),或者产生非常奇怪的行为。
我的第一次尝试(导致RecursionError
):
class Foo(another_class):
def __init__(self, bar):
self.bar = bar
super().__init__(self.bar)
def function_to_be_called(self):
self.bar += 1
def function(self):
# do stuff
def __getattribute__(self, attr):
method = another_class.__getattribute__(self, attr)
self.function_to_be_called() # this required __getattribute__ to be called to find function_to_be_called, causing an infinite loop
# even if self.function_to_be_called() is replaced with the self.bar += 1, it still causes an infinite loop as __getattribute__ is called to find bar
return method
我的第二次尝试还包括答案中的if callable(method)
,并将function_to_be_called
的内容移动到if语句中,而不是调用函数(p.s.我将酒吧改为列表,因为这是我的初衷,也是我发现奇怪行为的原因):
# Assume that another_class has an append method
class Foo(another_class):
def __init__(self, bar):
self.bar = bar
super().__init__(self.bar)
def function(self):
print(self.bar)
def __getattribute__(self, attr):
method = another_class.__getattribute__(self, attr)
if callable(method):
self.bar.sort() # doing something to bar, for example sorting it
return method
foo = Foo([3, 1, 2])
print(foo) # [3, 1, 2], although the expected result is [1, 2, 3]. it does not actually seem to be sorting it
foo.append(1)
print(foo) # [3, 1, 2, 1], although the expected result is [1, 1, 2, 3]
foo.function() # [1, 2, 3], the other 1 that was appended dissappears randomly (edit: I tried this again, with the actual class that I am using this in, and it seems to work for some reason), and it is sorted for some reason this time
1条答案
按热度按时间f45qwnt81#
您可以调用
super().__getattribute__
方法(在本例中解析为object.__getattribute__
方法)来避免递归:该输出:
Demo:在线试用!