2

有没有办法拦截属性调用链?

我的意思是:

myobj.attr1.attr2.{...}.attrN

我可以以某种方式拦截 myobj 中的整个链吗?

我想到的是一个可以'attr1.{...}.attrN'立即访问整个链的函数,例如作为字符串。有没有办法建立这个?

到目前为止,我有一个相当老套的解决方案,其中getatrr创建新对象,其getattr也创建新对象,因此整个属性链被记录为字符串(全名如下)。但我根本不喜欢这种解决方案,因为它有几个缺点,尤其是在酸洗和错误处理方面。

class NameCollector(object):
    ''' A helper class that resolves natural naming
    '''
    def __init__(self,myobj,name='',parent_name=''):

        self._myobj=myobj

        if name == '':
            self._fullname = ''
        elif parent_name == '':
            self._fullname = name
        else:
            self._fullname = parent_name + '.' + name

    def __getattr__(self,name):

        new_collector = NameCollector(self._myobj,name,self._fullname, self._regexp)
        if name in self._myobj._leaves:
            return self._myobj._do_stuff_with_chained_attribute_names(new_collector)

        return new_collector

非常感谢,罗伯特

4

1 回答 1

0

一种解决方案可能是在第一次访问时创建一个新对象a.b,然后每次后续访问,只需更新对象的内部结构(例如值列表),并添加一个__str__and__repr__方法。

class NameCollector(object):
    def __init__(self, parent, attr):
        self.parent = parent
        self.structure = [attr]
    def __getattr__(self, attr):
        if attr in self.__dict__: return attr
        self.structure.append(attr)
        return self
    def __str__(self):
        retval = ""
        for item in self.structure:
            retval += str(getattr(self.parent, item)) + "."
        return retval[:-1] # Remove the last '.'
class Foo(object):
    def __getattr__(self, attr): return NameCollector(self, attr)
于 2013-07-09T20:24:08.607 回答