Python:如何从__getattribute__方法访问属性

时间:2012-06-21 21:46:04

标签: python infinite-loop getattribute

我有以下课程:

class StrLogger(str):
    def __init__(self, *args):
        self._log_ = []
        str.__init__(self, *args)
    def __getattribute__(self, attr):
        self._log_.append((self.__name__, attr))
        return str.__getattribute__(self, attr)

我可以使用StrLogger初始化slog = StrLogger('foo'),我可以从str访问其所有继承的方法,并且运行没有问题。问题是,当我尝试使用slog._log_slog.__dict__['_log_']检索日志时,__getattribute__方法会陷入无限递归状态。我理解为什么会这样,但我的问题是,我该如何访问日志?

3 个答案:

答案 0 :(得分:3)

我可以想到一种方式。无论何时需要绕过自定义属性访问,都要使用object.__getattribute__(或任何超类)。

class C(object):
    def __init__(self):
        self._log = []
    def __getattribute__(self, attr):
        _log = object.__getattribute__(self, '_log')
        _log.append(attr)
        return object.__getattribute__(self, attr)

>>> a = C()
>>> a.x = 1
>>> a.x
1
>>> a._log
['x', '_log']

答案 1 :(得分:2)

以下略有修改的类有效:

class StrLogger(str):
    def __init__(self, *args):
        self._log_ = []
        str.__init__(self, *args)

    def __getattribute__(self, attr):
        log = str.__getattribute__(self, '_log_')
        cls = str.__getattribute__(self, '__class__')
        name = cls.__name__
        log.append((name, attr))
        return str.__getattribute__(self, attr)

s = StrLogger('abc')
print(s.title())
print(s.lower())
print(s.upper())
print(s.__dict__)

运行它会导致

Abc
abc
ABC
{'_log_': [('StrLogger', 'title'), ('StrLogger', 'lower'), ('StrLogger', 'upper'), ('StrLogger', '__dict__')]}

答案 2 :(得分:1)

您的__getattribute__应该排除__dict__,也可以排除_log_。或者,您可以执行类似

的操作
slog = StrLogger('foo')
thelog = slog._log_
do_stuff_with(slog)
print thelog

(未经测试!)