>>> l = LoggingLazyDB() >>> l.bar logging: called __getattr__(bar) 'attr for bar' >>> l.foo logging: called __getattr__(foo) 'attr for foo' >>> l.__dict__ {'bar': 'attr for bar', 'db': None, 'foo': 'attr for foo'} >>> l.bar 'attr for bar' >>> l.foo 'attr for foo'
def__getattribute__(self, attr): print('logging: call __getattribute__(%s) at %s' % (attr, time.ctime())) try: value = super().__getattribute__(attr) print('attribute in __dict__ return here') return value except AttributeError: value = 'value created at %s' % time.ctime() setattr(self, attr, value) return value
在交互式下使用该类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
>>> t = TimingDB() >>> t.db logging: call __getattribute__(db) at Thu Jan 18 08:22:49 2018 attribute in __dict__ return here 'db' >>> t.foo logging: call __getattribute__(foo) at Thu Jan 18 08:22:54 2018 'value created at Thu Jan 18 08:22:54 2018' >>> t.foo logging: call __getattribute__(foo) at Thu Jan 18 08:22:57 2018 attribute in __dict__ return here 'value created at Thu Jan 18 08:22:54 2018' >>> t.__dict__ logging: call __getattribute__(__dict__) at Thu Jan 18 08:23:03 2018 attribute in __dict__ return here {'foo': 'value created at Thu Jan 18 08:22:54 2018', 'db': 'db'}
>>> t = TimingDB() >>> t.__dict__ logging: call __getattribute__(__dict__) at Thu Jan 18 08:30:43 2018 attribute in __dict__ return here {'db': 'db'} >>> hasattr(t, 'abc') logging: call __getattribute__(abc) at Thu Jan 18 08:30:50 2018 True >>> getattr(t, 'feng') logging: call __getattribute__(feng) at Thu Jan 18 08:31:05 2018 'value created at Thu Jan 18 08:31:05 2018'
>>> r = RecursionDB() >>> r.abc called __getattribute__(abc) called __getattribute__(_db) called __getattribute__(_db) called __getattribute__(_db) called __getattribute__(_db) called __getattribute__(_db) called __getattribute__(_db) called __getattribute__(_db) . . . File "~\python-3.5.2\lib\idlelib\PyShell.py", line 1344, in write return self.shell.write(s, self.tags) RecursionError: maximum recursion depth exceeded while calling a Python object