Python"受保护"属性

m2o*_*m2o 37 python

如何从子类访问父类的私有属性(不公开)?

Ed.*_*Ed. 86

我对Python约定的理解是

  • _member受到保护
  • __member是私人的

如果您控制父类的选项

  • 让它保护而不是私有,因为这看起来像你真正想要的
  • 使用getter(@property def _protected_access_to_member ...)来限制受保护的访问

如果你不控制它

  • 撤消名称修改.如果您使用dir(object),您将看到类似于_Class__member的名称,这就是Python将__引导为"使其成为私有"的行为.python中没有真正的私有.这可能被认为是邪恶的.

  • 重要提示:“__”前缀的目的不是使属性在“可见性”意义上私有,而是在“继承”意义上私有,主要是为了在专门为继承设计类时避免命名冲突。正如评论所指出的,修改方案定义良好且稳定,因此如果任何人确实想要的话,它不会阻止任何人访问该属性(或更新它)。 (2认同)

Lut*_*elt 40

两种保护哲学

一些语言设计者订阅以下假设:

"许多程序员都是不负责任的,愚蠢的,或两者兼而有之."

这些语言设计者会感到很想通过private在他们的语言中引入说明符来保护程序员彼此.不久之后,他们认识到这通常太不灵活,也会引入protected.

相比之下,像Python的Guido van Rossum这样的语言设计师则认为程序员是负责任的成年人并且能够做出良好的判断(可能不总是,但通常).他们发现,如果有需要,每个人都应该能够访问程序的元素,这样语言就不会妨碍做正确的事情.(能够可靠地阻止做错事的唯一编程语言是NULL语言)

因此,_myfield在Python中意味着"这个模块的设计者正在使用这个属性做一些非显而易见的事情,所以请不要修改它,如果可以的话,远离阅读它 - 适当的方式访问相关信息已经提供(或者我们希望)."

如果您无法远离访问_myfield(例如在子类中的特殊情况下),您只需访问它.

  • @ BobStein-VisiBone +1对于Python是世俗的人文主义者。 (2认同)
  • 你能相信@san,类比已经[已经做出](http://higherorderfun.com/blog/2011/02/16/if-programming-languages-were-religions/)? (2认同)

kn3*_*n3l 15

使用@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)+" ? "))
Run Code Online (Sandbox Code Playgroud)

  • 问题是关于访问子类中的属性. (6认同)

Noa*_*nos 9

似乎没有人回答最初的问题

如何从子类访问父类的私有属性

所以这是一个简单的用例,演示了两个选项 - 访问父类__private 变量和使用@property 装饰器

class Family:

    def __init__(self, name):
        self.__family_name = name

    @property
    def name(self):
        return self.__family_name


class Child(Family):

    def __init__(self, first_name, last_name):
        super(Child, self).__init__(last_name)
        self.__child_name = first_name


    @property
    def name(self):
        return (self.__child_name, super(Child, self).name)


if __name__ == '__main__':
    my_child = Child("Albert", "Einstein")

    # print (my_child.__child_name)         # AttributeError - trying to access private attribute '__child_name'
    # print (my_child.__family_name)        # AttributeError - trying to access private attribute '__family_name'
    print (my_child._Child__child_name)     # Prints "Albert" - By accessing __child_name of Child sub-class
    print (my_child._Family__family_name)   # Prints "Einstein" - By accessing __family_name in Family super-class
    print (" ".join(my_child.name))         # Prints "Albert Einstein" - By using @property decorators in Child and Family 
Run Code Online (Sandbox Code Playgroud)