這裏是我的簡單類(錯誤):實施了自己的__getattr__;得到了意外的錯誤
$ ipython
Python 2.7.6 (default, Oct 26 2016, 20:30:19)
Type "copyright", "credits" or "license" for more information.
IPython 5.1.0 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.
In [1]: import numpy as np
In [2]: class Foo(object):
...: def __init__(self):
...: self.one = 1
...: self.dct = dict(a='aaa', b='bbb')
...:
...: @property
...: def two(self):
...: # import ipdb; ipdb.set_trace()
...: np.ann # This was the spelling error I had
...: return 2
...:
...: def __getattr__(self, key):
...: """
...: Provide convenient access to values that are
...: somewhat inconvient to access, eg
...:
...: >>> foo = Foo()
...: >>> foo.dct['a'] # this obviously works
...: 'aaa'
...: >>> foo.a # but this is easier
...: 'aaa'
...:
...: In reality I have something a bit more complicated than
...: a simple dictionary (`self.dct = dict(...)`)
...:
...: """
...: print('__getattr__ with "{}"'.format(key))
...: try:
...: return self.dct[key]
...: except KeyError:
...: raise AttributeError("Can't find '{}'".format(key))
...:
使用它......
In [3]: foo = Foo()
In [4]: foo.one
Out[4]: 1
In [5]: foo.dct['a']
Out[5]: 'aaa'
In [6]: foo.a
__getattr__ with "a"
Out[6]: 'aaa'
In [7]: foo.two
__getattr__ with "two"
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-9-29e77587894c> in <module>()
----> 1 foo.two
<ipython-input-4-955e08b9c001> in __getattr__(self, key)
12 return self.dct[key]
13 except KeyError:
---> 14 raise AttributeError("Can't find '{}'".format(key))
15
AttributeError: Can't find 'two'
爲什麼拼寫錯誤np.ann
調用foo.__getattr__
和我自己的raise AttributeError
與結束了key == 'two'
??
我已經通過了代碼(通過取消註釋set_trace()
行),但沒有真正理解它。這裏的輸出是有用的。
In [15]: foo.two
> <ipython-input-13-915f93b88a22>(8)two()
7 import ipdb; ipdb.set_trace()
----> 8 np.ann
9 return 2
ipdb> n
AttributeError: "'module' object has no attribute 'ann'"
> <ipython-input-13-915f93b88a22>(8)two()
7 import ipdb; ipdb.set_trace()
----> 8 np.ann
9 return 2
ipdb> n
--Return--
None
> <ipython-input-13-915f93b88a22>(8)two()
7 import ipdb; ipdb.set_trace()
----> 8 np.ann
9 return 2
ipdb> n
--Call--
> <ipython-input-13-915f93b88a22>(10)__getattr__()
9 return 2
---> 10 def __getattr__(self, key):
11 print('__getattr__ with "{}"'.format(key))
ipdb> n
> <ipython-input-13-915f93b88a22>(11)__getattr__()
10 def __getattr__(self, key):
---> 11 print('__getattr__ with "{}"'.format(key))
12 try:
ipdb> n
__getattr__ with "two"
> <ipython-input-13-915f93b88a22>(12)__getattr__()
11 print('__getattr__ with "{}"'.format(key))
---> 12 try:
13 return self.dct[key]
ipdb> n
> <ipython-input-13-915f93b88a22>(13)__getattr__()
12 try:
---> 13 return self.dct[key]
14 except KeyError:
ipdb> n
KeyError: ('two',)
> <ipython-input-13-915f93b88a22>(13)__getattr__()
12 try:
---> 13 return self.dct[key]
14 except KeyError:
ipdb> n
> <ipython-input-13-915f93b88a22>(14)__getattr__()
13 return self.dct[key]
---> 14 except KeyError:
15 raise AttributeError("Can't find '{}'".format(key))
ipdb> n
> <ipython-input-13-915f93b88a22>(15)__getattr__()
14 except KeyError:
---> 15 raise AttributeError("Can't find '{}'".format(key))
16
ipdb> n
AttributeError: Attribut... 'two'",)
> <ipython-input-13-915f93b88a22>(15)__getattr__()
14 except KeyError:
---> 15 raise AttributeError("Can't find '{}'".format(key))
16
ipdb> n
--Return--
None
> <ipython-input-13-915f93b88a22>(15)__getattr__()
14 except KeyError:
---> 15 raise AttributeError("Can't find '{}'".format(key))
16
ipdb> n
AttributeError: Attribut... 'two'",)
> <ipython-input-15-29e77587894c>(1)<module>()
----> 1 foo.two
ipdb> n
--Return--
None
> <ipython-input-15-29e77587894c>(1)<module>()
----> 1 foo.two
ipdb> n
AttributeError: Attribut... 'two'",)
> /home/venv/local/lib/python2.7/site-packages/IPython/core/interactiveshell.py(2881)run_code()
2880 #rprint('Running code', repr(code_obj)) # dbg
-> 2881 exec(code_obj, self.user_global_ns, self.user_ns)
2882 finally:
如果我註釋掉@property
線,那麼錯誤的行爲與預期,這使我相信,這事做與裝飾...:
In [19]: foo.two
Out[19]: <bound method Foo.two of <__main__.Foo object at 0x7fc248156450>>
In [20]: foo.two()
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-20-25d037a9762c> in <module>()
----> 1 foo.two()
<ipython-input-16-9999eb93c349> in two(self)
6 def two(self):
7 # import ipdb; ipdb.set_trace()
----> 8 np.ann
9 return 2
10 def __getattr__(self, key):
AttributeError: 'module' object has no attribute 'ann'