获取在 __call__ 内部调用的 python 3.x 方法的名称
Get the name of the python 3.x method that was called inside of __call__
我试图在 class 调用时添加一个方法。
例如:
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__?
更好的地方来完成这个
谢谢!
__call__
用于调用对象本身时,如 x()
。 x.nonexistant_method()
(sic) 从不调用 x
的 __call__
方法;它会调用 nonexistant_method
的 __call__
(如果该方法存在)。
我想在这种情况下您想要的是 __getattr__
。当访问不存在的属性时,将调用 __getattr__
。在这种情况下,您只想 return 您的 generic_function
.
def __getattr__(self, name):
return self.generic_function
kindall 完全正确,您可能想要 __getattr__
.
这是一个示例 class,它的工作方式与我认为您希望的工作方式相同:
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
,它只是一个函数 ,returns 是一个函数 。 (这被称为 closure)。
我们可以调用 X.make_missing_method('foo')
并验证这一点:
x = X()
f = x.make_missing_method('foo')
print(type(f)) # <class 'function'>
正如 kindall 所指出的,当您尝试访问不存在的实例属性时(使用 .
表示法),__getattr__
会使用您尝试访问的名称作为参数。
我们可以将这两件事结合起来,创建一个 class 允许您在实例上调用以前未定义的方法,并使其按预期运行。
所以根据上面的class,我们可以写成:
x = X()
x.foo()
输出:
Self object: <__main__.X object at 0x00000000021E0BE0>
Method name: foo
Method args: [(), {}]
注意上面的X
class中没有定义foo
,但是missing_method
还是被恰当地调用了。从 missing_method
内部,我们可以访问调用实例(通过 self
)、尝试的方法名称(通过 name
)和传递的参数。
要查看实际参数,您可以这样写:
x = X()
x.bar(1, 2, third="three")
输出:
Self object: <__main__.X object at 0x00000000021E0BE0>
Method name: bar
Method args: [(1, 2), {'third': 'three'}]
同样,bar
没有明确定义为方法,但调用 x.bar(...)
就像它是一样。
我试图在 class 调用时添加一个方法。 例如:
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__?
更好的地方来完成这个谢谢!
__call__
用于调用对象本身时,如 x()
。 x.nonexistant_method()
(sic) 从不调用 x
的 __call__
方法;它会调用 nonexistant_method
的 __call__
(如果该方法存在)。
我想在这种情况下您想要的是 __getattr__
。当访问不存在的属性时,将调用 __getattr__
。在这种情况下,您只想 return 您的 generic_function
.
def __getattr__(self, name):
return self.generic_function
kindall 完全正确,您可能想要 __getattr__
.
这是一个示例 class,它的工作方式与我认为您希望的工作方式相同:
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
,它只是一个函数 ,returns 是一个函数 。 (这被称为 closure)。
我们可以调用 X.make_missing_method('foo')
并验证这一点:
x = X()
f = x.make_missing_method('foo')
print(type(f)) # <class 'function'>
正如 kindall 所指出的,当您尝试访问不存在的实例属性时(使用 .
表示法),__getattr__
会使用您尝试访问的名称作为参数。
我们可以将这两件事结合起来,创建一个 class 允许您在实例上调用以前未定义的方法,并使其按预期运行。
所以根据上面的class,我们可以写成:
x = X()
x.foo()
输出:
Self object: <__main__.X object at 0x00000000021E0BE0> Method name: foo Method args: [(), {}]
注意上面的X
class中没有定义foo
,但是missing_method
还是被恰当地调用了。从 missing_method
内部,我们可以访问调用实例(通过 self
)、尝试的方法名称(通过 name
)和传递的参数。
要查看实际参数,您可以这样写:
x = X()
x.bar(1, 2, third="three")
输出:
Self object: <__main__.X object at 0x00000000021E0BE0> Method name: bar Method args: [(1, 2), {'third': 'three'}]
同样,bar
没有明确定义为方法,但调用 x.bar(...)
就像它是一样。