获取在__call__中调用的python 3.x方法的名称

时间:2015-03-30 04:21:07

标签: python reflection

我尝试在调用类时向类添加方法。 例如:

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 __?

中有更好的地方来实现这一点

谢谢!

2 个答案:

答案 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}}的工作原理就像它一样。