我有以下课程:
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__
方法会陷入无限递归状态。我理解为什么会这样,但我的问题是,我该如何访问日志?
答案 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
(未经测试!)