Python中的“受保护”属性
我该如何在子类中访问父类的私有属性(而不把它变成公共的)?
9 个回答
18
使用 @property
和 @name.setter
来实现你想要的功能
例如
class Stock(object):
def __init__(self, stockName):
# '_' is just a convention and does nothing
self.__stockName = stockName # private now
@property # when you do Stock.name, it will call this function
def name(self):
return self.__stockName
@name.setter # when you do Stock.name = x, it will call this function
def name(self, name):
self.__stockName = name
if __name__ == "__main__":
myStock = Stock("stock111")
myStock.__stockName # It is private. You can't access it.
#Now you can myStock.name
N = float(raw_input("input to your stock: " + str(myStock.name)+" ? "))
64
两种保护理念
一些编程语言的设计者有这样的想法:
"很多程序员都不负责任,或者智商不高,或者两者都有."
这些设计者会想要通过在他们的语言中引入一个 private
关键字来保护程序员,防止他们互相干扰。没过多久,他们就意识到这样做往往太死板,于是又引入了 protected
。
而像Python的创始人Guido van Rossum这样的语言设计者,则认为程序员是负责任的成年人,通常能够做出正确的判断(虽然不总是如此)。他们认为,只要有需要,大家都应该能够访问程序中的元素,这样语言就不会妨碍做正确的事情。
实际上,唯一一个能可靠地阻止你做错事的编程语言是 NULL 语言。
因此,在Python中,_myfield
的意思大致是:“这个模块的设计者在处理这个属性时做了一些不明显的事情,所以请不要修改它,如果可以的话,尽量不要去读它——我们提供了合适的方式来获取相关信息(或者说我们希望如此)。”
如果你真的需要访问 _myfield
(比如在子类中的特殊情况),那你就可以直接访问它。
103
我对Python的约定理解是:
- 以_开头的成员是受保护的
- 以__开头的成员是私有的
如果你能控制父类,有以下选择:
- 把它设为受保护的,而不是私有的,因为这似乎更符合你的需求
- 使用一个获取器(@property def _protected_access_to_member...)来限制对受保护成员的访问
如果你不能控制父类:
- 撤销名称混淆。如果你使用dir(object)命令,你会看到一些像_Class__member这样的名字,这是Python为了“让它私有”而对以__开头的成员进行的处理。实际上,Python中并没有真正的私有成员。这种做法可能被认为是不好的。