如何捕获Python类中不存在的嵌套变量的查找?

ghi*_*man 3 python

我试图劫持对我的班级的任何调用,并将它们传递给我在课堂上选择的方法.

我的班级到目前为止:

class Klass(object):
    def __getattribute__(self, name):
        if name == '_dummy_func':
            return object.__getattribute__(self, name)
        return object.__getattribute__(self, 'dummy_func')

    def _dummy_func(self):
        print 'dummy func called!'
Run Code Online (Sandbox Code Playgroud)

我这样做时有效:

cls = Klass()
cls.foo()
Run Code Online (Sandbox Code Playgroud)

但尝试这样做时会摔倒:

cls = Klass()
cls.foo.bar()
Run Code Online (Sandbox Code Playgroud)

因为dummy_func没有属性bar.

我试着__getattribute__()通过检查是否name这里描述的函数来捕获这种嵌套行为,但它是一个字符串而不是实际变量.

有没有办法从里面抓住这个Klass

Nik*_* B. 5

不返回虚函数,只返回一个可通过该方法调用的虚拟对象,__call__并依次定义__getattr__在请求属性时返回另一个虚拟对象:

class Dummy(object):
  def __init__(self, klass, path):
    self.klass = klass
    self.path = path

  def __getattr__(self, attr):
    return Dummy(self.klass, self.path + [attr])

  def __call__(self, *args, **kw):
    self.klass._dummy_func(self.path, *args, **kw)

class Klass(object):
  def __getattr__(self, attr):
    return Dummy(self, [attr])

  def _dummy_func(self, path, *args, **kw):
    print "Dummy function %s called with %d arguments!" \
                      % ('.'.join(path), len(args))

Klass().foo.bar.func(1, 2)  
# => "Dummy function foo.bar.func called with 2 arguments!"
Run Code Online (Sandbox Code Playgroud)

您现在可以根据给定的完整路径应用逻辑_dummy_func.您甚至可以获得提供的参数和关键字.

  • 我很惊讶.当我第一次看到你的代码时,我认为这是错综复杂和不必要的,因为我的代码更简单; 现在我看到你使用`Dummy`作为查找链的内存,当Python最终决定调用它时,只需将内存传递回原始的`Klass`对象.美丽.我把帽子给你. (2认同)