确定__getattr__是否为方法或属性调用

Rob*_*den 8 python getattr

有没有办法使用__getattr__确定方法和属性调用之间的区别?

即:

class Bar(object):
    def __getattr__(self, name):
        if THIS_IS_A_METHOD_CALL:
            # Handle method call
            def method(**kwargs):
                return 'foo'
            return method
        else:
            # Handle attribute call
            return 'bar'

foo=Bar()
print(foo.test_method()) # foo
print(foo.test_attribute) # bar
Run Code Online (Sandbox Code Playgroud)

这些方法不是本地的,因此无法使用getattr/callable来确定它.我也理解方法是属性,并且可能没有解决方案.只是希望有一个.

Mar*_*ers 9

根本无法告诉对象在__getattr__钩子中的使用方式.例如,您可以在不调用方法的情况下访问方法,将它们存储在变量中,然后调用它们.

使用__call__方法返回一个对象,它将在调用时调用:

class CallableValue(object):
    def __init__(self, name):
        self.name = name
    def __call__(self, *args, **kwargs):
        print "Lo, {} was called!".format(self.name)

class Bar(object):
    def __getattr__(self, name):
        return CallableValue(name)
Run Code Online (Sandbox Code Playgroud)

但是这个实例与字符串或列表同时不是一回事.

演示:

>>> class CallableValue(object):
...     def __init__(self, name):
...         self.name = name
...     def __call__(self, *args, **kwargs):
...         print "Lo, {} was called!".format(self.name)
... 
>>> class Bar(object):
...     def __getattr__(self, name):
...         return CallableValue(name)
... 
>>> b = Bar()
>>> something = b.test_method
>>> something
<__main__.CallableValue object at 0x10ac3c290>
>>> something()
Lo, test_method was called!
Run Code Online (Sandbox Code Playgroud)