作者:
uranusjr (â†é€™äººæ˜¯è¶…級笨蛋)
2016-10-14 11:40:26※ 引述《icetofux ()》之銘言:
: test.py
: 1 class StateMachine:
: 2 def __init__(self):
: 3 self.__state = "IDLE"
: 4
: 5 def state(self):
: 6 return (self.__state)
: 7
: 8 sm = StateMachine()
: 9 print(sm.state())
: 10 sm.__state = "MOV"
: 11 print(sm.state())
Python 的 self.__member 並不會造成這個成員被隱藏, 而是會觸發 name mangling:
https://en.wikipedia.org/wiki/Name_mangling#Python
>>> class Foo:
... def __init__(self):
... self.__member = 'member'
... def get_member(self):
... return self.__member
>>> foo = Foo()
>>> [attr for attr in dir(foo) if 'member' in attr]
['_Foo__member']
>>> foo._Foo__member
'member'
當你在 instance method 中對 self.__member 賦值時
Python 會改把資料存到 _Foo__member
進而造成 class 外的程式無法用 foo.__member 取值 (但可以用 foo._Foo__member)
當你在 class 外的程式對 foo.__member 賦值, 則並不會觸發 name mangling
>>> foo.__member = 'outside'
>>> [attr for attr in dir(foo) if 'member' in attr]
['_Foo__member', '__member']
>>> foo.__member
'outside'
>>> foo._Foo__member
'member'
這兩個成員是分開的
當你在 Foo class 裡面的 instance method 使用 self.__member 取值時
仍然會觸發 name mangling, 進而取到 _Foo__member
註:
Python 文件有特別註明這個 mangling 行為只是用來防止繼承時的意外覆寫
但因為這個 mangling 規則過於 naive, 其實還是很容易出意外
所以一般而言會建議使用 p-member 或完善文件來對付這個問題
而對於你這種 scope management 而言, 更是強烈不建議使用 name mangling