子类化内置类型
Python 2.2之后內置類型開始可以子類化了
但是,CPython中的內置類型不會調用用戶重寫的類的特殊方法。
PyPy的文檔中描述了這個問題。subclasses-of-built-in-types
正式情況下,CPython 并沒有官方規定內置類型的子類中重寫的方法是否會被隱式調用。基本上,這些用戶重寫的方法不會被同一對象的其他內置方法調用。例如,在dict的子類中重寫的 `__getitem__()` 方法不會被內置的 `get()` 方法調用。以上情況在CPython和PyPy中都是一致的。在內置函數或方法是否會調用另一個對象的重寫方法而不是self上,兩者會出現差異。PyPy經常會在Cpython不調用的情況下調用。 兩個例子:
ex1:
class D(dict):def __getitem__(self, key):return "%r from D" % (key,)class A(object):passa = A()
a.__dict__ = D()
a.foo = "a's own foo"
print a.foo
# CPython => a's own foo
# PyPy => 'foo' from D ex2:
glob = D(foo="base item")
loc = {}
exec "print foo" in glob, loc
# CPython => base item
# PyPy => 'foo' from D 原生類型的這種行為違背了面向對象編程的一個基本原則:始終應該從實例(self)所屬的類開始搜索方法,即使在超類實現的類中調用也是如此。(不過 __missing__ 方法是個特例。)
在CPython的實現結構中,內建方法大部分會忽略用戶重寫的特殊方法,所以產生了UserDict,UserString,UserList來解決這個問題。
In : class NewDict(dict):
...: def __getitem__(self, key):
...: return 42
...:
In : d = NewDict(a=1)
In : d
Out: {'a': 42}
In : d2 = {}
In : d2.update(d) #CPython中的update會忽略NewDict中的__getitem__方法
In : d2
Out: {'a': 1} 因此用戶如果自己定義的類應該繼承collections模塊中的類。而不是子類化內置類。
*《流暢的Python》 12.1
轉載于:https://www.cnblogs.com/leisurelylicht/p/zi-lei-hua-nei-zhi-lei-xing-subclassesofbuiltintyp.html
總結
- 上一篇: sxoi爆炸祭
- 下一篇: Selenium(3)