我尝试在调用类时向类添加方法。 例如:
class X(callable):
def __init__(self):
pass
def __call__(self, *args, **kwargs):
method_called = self.get_method_name()
if method_called not in self.__dict__:
self.__dict__[method_called] = self.generic_function
super().__call__(self, *args, **kwargs)
def generic_function(self):
print("I'm So Generic")
def a(self):
print('a')
def get_method_name(self):
#get the name of the method trying to be called
method_name = ?????
return method_name
def main():
x = X()
#should create a method nonexistant_method that acts like generic_function
x.nonexistant_method()
main()
我意识到这可能是一件奇怪的事情,但它是我为一些研究所建立的工具的一部分。这可能吗?或者在__call __?
中有更好的地方来实现这一点谢谢!
答案 0 :(得分:4)
__call__
用于调用对象本身,例如x()
。 x.nonexistant_method()
(原文如此)从不调用x
的{{1}}方法;它会调用__call__
的{{1}}(如果存在该方法)。
我认为在这种情况下你想要的是nonexistant_method
。当访问不存在的属性时,将调用__call__
。在这种情况下,您只想返回__getattr__
。
__getattr__
答案 1 :(得分:0)
善意是完全正确的,你可能想要__getattr__
。
这是一个示例类,它的工作方式我认为你希望你的工作方式:
class X:
def make_missing_method(self, name):
def missing_method(*args, **kwargs):
print("Self object:", self)
print("Method name:", name)
print("Method args:", [args, kwargs])
return missing_method
def __getattr__(self, name):
return self.make_missing_method(name)
这可能令人困惑,但它非常简单。
首先要注意的是,python函数是对象,可以像其他任何东西一样传递。
我们通过创建make_missing_method
来利用这一点,X.make_missing_method('foo')
只是一个函数,它返回一个函数。 (这称为closure)。
我们可以致电x = X()
f = x.make_missing_method('foo')
print(type(f)) # <class 'function'>
并验证:
.
正如kindall所指出的,当您尝试访问不存在的实例属性(使用__getattr__
表示法)时,将使用您尝试作为参数访问的名称调用x = X()
x.foo()
。
我们可以将这两件事结合起来,创建一个允许您在实例上调用以前未定义的方法的类,并让它按预期运行。
因此,鉴于上述课程,我们可以写:
foo
输出:
Self object: <__main__.X object at 0x00000000021E0BE0> Method name: foo Method args: [(), {}]
请注意,上面的X
课程中未定义missing_method
,但missing_method
仍被恰当地调用。从self
内部,我们可以访问调用实例(通过name
),尝试的方法的名称(通过x = X()
x.bar(1, 2, third="three")
)和传递的参数。
要查看操作中的参数,您可以写:
bar
输出:
Self object: <__main__.X object at 0x00000000021E0BE0> Method name: bar Method args: [(1, 2), {'third': 'three'}]
同样,x.bar(...)
未明确定义为方法,但调用{{1}}的工作原理就像它一样。