Python中沒有完全的私有屬性嗎?

 

一個很有意思的問題,關於Python內有沒有真正的私有屬性。我覺得可以說有,也可以說沒有,具體看對比的語言。

有時候,python看似可以設置私有屬性,用代碼表示

class BB():

    def __init__(self, name):

        self.__name = name


    def get_name(self):

        return self.__name



b = BB('bb')

d = BB('dd')

b.__name = 'cc'



print(b.__name)  # cc

print(b.get_name())  # bb

print(d.get_name())  # dd

print(d.__name)  # raise an exception

 

觀察打印結果,b.__name = ‘cc’ ,b.get_name() = ‘bb'

我們可知,b.__name = ‘cc’ 其實並不是修改了私有屬性,只是定義了實例對象b的一個新的變量名,變量名以下劃線(dunder)開頭。私有屬性並不會被修改。

而d.get_name() = ‘dd' ,d.__name調用會拋出異常。我們可以很明顯看出,變量只是實例對象b的屬性。並沒有加載進入類中,在另一個實例對象d中也不可調用。

 

那麼爲什麼又說python沒有真正的私有屬性呢?

因爲python中,通過【實例對象._類對象__私有屬性】,比如b._BB__name是可以直接訪問私有屬性的。

因此,私有屬性只是看似不能獲取,如果你真的想要拿,也是可以拿到的。

 

 

20190212,在github看到類似本問題的回答,記錄一下

Python中單下劃線和雙下劃線

>>> class MyClass():
...     def __init__(self):
...             self.__superprivate = "Hello"
...             self._semiprivate = ", world!"
...
>>> mc = MyClass()
>>> print mc.__superprivate
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: myClass instance has no attribute '__superprivate'
>>> print mc._semiprivate
, world!
>>> print mc.__dict__
{'_MyClass__superprivate': 'Hello', '_semiprivate': ', world!'}

__foo__:一種約定,Python內部的名字,用來區別其他用戶自定義的命名,以防衝突,就是例如__init__(),__del__(),__call__()這些特殊方法

_foo:一種約定,用來指定變量私有.程序員用來指定私有變量的一種方式.不能用from module import * 導入,其他方面和公有一樣訪問;

__foo:這個有真正的意義:解析器用_classname__foo來代替這個名字,以區別和其他類相同的命名,它無法直接像公有成員一樣隨便訪問,通過對象名._類名__xxx這樣的方式可以訪問.

詳情見:http://stackoverflow.com/questions/1301346/the-meaning-of-a-single-and-a-double-underscore-before-an-object-name-in-python

或者: http://www.zhihu.com/question/19754941

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章