您好,登錄后才能下訂單哦!
本篇內容介紹了“Python中__dict__有什么用”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
Python這門編程語言的最大的好處就是其語言的動態性帶來編程的便利性,不像靜態語言那樣死板,比如它可以運行期動態添加類定義時沒有的屬性,例如:
class A: def __init__(self): self.name = 'zhang' def eat(self): print('eat') a = A() a.age = 10 print(a.age)
在Java中這段代碼可定是沒法通過編譯的,但在Python中這樣的操作不再是司空見慣的事情,那Python解釋器在背后究竟做了什么操作呢?答案是__dict__
,Python中的所有內建(build-in)數據類型(type)都有屬性__dcit__
,當然自定義的類(class)也有,因為自定義的類也是一種數據類型嘛。在a.age=10
前后分別加上一行print a.__dict__
可以得到結果:
{'name': 'zhang'} {'age': 10, 'name': 'zhang'} 10
不難看出,在運行期和類定義期所定義的實例對象屬性放在該對象的 __dict__
屬性中,接下來在a=A()
后面加上幾行代碼:
A.country = "China" print a.country print a.__dict__
得到結果:
China {'age': 10, 'name': 'zhang'}
對象a的__dict__
屬性中并沒'country'這個屬性,那它是哪來的呢?那么不妨打印類對象A的__dict__
看看:
print a.country print a.__dict__ print A.__dict__
輸出結果:
China {'age': 10, 'name': 'zhang'} {'country': 'China', '__module__': '__main__', 'eat': <function eat at 0x104e3b230>, ...省略}
這下應該明白了,在運行期間,定義的實例對象(a)的屬性是放在a.__dict__
中,而定義的類對象(A)的屬性是放在A.__dict__
中,那為什么實例對象a是怎么訪問到country屬性的呢? Python中是這樣約定的,以obj.attr訪問時,它會按照如下順序去查找:
對象自身,obj.__dict__['attr']
對象類型,obj.__class__.__dict__['attr']
對象類型的基類,obj.__class__.__bases__中的所有__dict__['attr']
。注意,當多重繼承的情況下有菱形繼承的時候,Python會根據MRO確定的順序進行搜索。
如果在基類都還沒找到要訪問的屬性時,Python解釋器就會跑出一個異常:AttributeError。那么問題來了,我們是否可以給內建(build-in)類型添加一些自定義的屬性呢?比如:
list.myExtension = lambda self,x:x * 2 list.myExtension(10)
運行的時候,解釋器會報錯:TypeError: can't set attributes of built-in/extension type 'list',那能否向list的__dict__
屬性中添加一個值呢?
list.__dict__['myExtension'] = lambda self, x:x * 2
還是一樣,沒法運行:TypeError: 'dictproxy' object does not support item assignment,細細思來,后者不能運行也是符合情理的,兩者就是等價的東西,那為什么不允許程序員擴展內建類型呢?
后面那位睡覺的同學你來回答一下,答曰:Guido van Rossum老爹是用C語言來實現的這些類型,你是沒法再修改的,那如何優雅地擴展已有類型呢?知道OOP的同學都會用繼承的方式來做。于是那位同學繼續睡覺去了。
“Python中__dict__有什么用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。