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)

で初期化できStrLoggerslog = StrLogger('foo')継承されたすべてのメソッドにアクセスできstr、問題なく実行されます。slog._log_問題は、またはのいずれかでログを取得しようとすると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 に答える