4

我有以下课程:

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)

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

4

3 回答 3

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']
于 2012-06-21T21:57:58.433 回答
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__')]}
于 2012-06-21T22:05:58.440 回答
1

__getattribute__应该排除__dict__,也许也可以_log_从记录中排除。或者,你可以做类似的事情

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

(未经测试!)

于 2012-06-21T21:57:30.210 回答