Python中的“受保护”属性

53 投票
9 回答
84060 浏览
提问于 2025-04-15 11:17

我该如何在子类中访问父类的私有属性(而不把它变成公共的)?

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中并没有真正的私有成员。这种做法可能被认为是不好的。

撰写回答