2009-04-28 177 views
26

如何从子类访问父类的私有属性(不公开)?Python“受保护”属性

+4

你的意思是保护的还是私人的?您的问题与您的标题不同... – unwind 2009-04-28 13:00:18

+7

由于受保护和私人在Python中没有多大意义,请提供实际的代码。 – 2009-04-28 13:10:57

回答

60

我的Python公约的理解是

  • _member保护
  • __member是私人

选项,如果你控制了父类

  • 让它保护,而不是私人 因为这似乎是你真的 想
  • 使用的吸气剂(@property高清 _protected_access_to_member ...),以限制保护访问

如果不控制它

  • 撤消名字改编。如果你 目录(对象),你会看到名称 类似_Class__member这是 Python做什么来领导__到 “让它私人”。没有 在Python中真正私有。这可能被认为是邪恶的。
0

做一个访问方法,除非我失去了一些东西:

def get_private_attrib(self): 
    return self.__privateWhatever 
2

如果变量名是“__secret”和类名是“MyClass的”您可以访问它这样命名的实例“变种“

var._MyClass__secret

公约建议/模拟保护是一个领先的下划线将其命名为:self._protected_variable = 10

当然,任何人都可以修改它,如果它真的想要。

10

使用@property和做你想做什么

保护如

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)+" ? ")) 
+5

问题是关于访问子类中的属性。 – 2012-05-11 19:20:17

22

两种哲学

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

“许多程序员都是不负责任,模糊不清的,或者两者兼而有之。”

这些语言的设计者会觉得动心通过引入private符到他们的语言来保护彼此的程序员。 不久后,他们认识到这通常太不灵活,并且也引入protected。相比之下,像Python的Guido van Rossum这样的语言设计者认为程序员是负责任的成年人,并且能够很好地判断(可能并不总是,但通常)。 他们发现,如果有必要这样做,每个人都应该能够访问程序的元素,以便语言不会妨碍正确的事情。 (唯一的编程语言,可以顺利拿到在做错误事情的方式是NULL语言)

因此,_myfield在Python是指像“这个模块的设计者正在做一些不常见的东西有了这个属性,所以如果可以的话,请不要修改它,甚至不要阅读, - 已经提供了访问相关信息的合适方法。“

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

0

似乎没有人回答原来的问题

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

所以这里有一个简单的用例,展示了两个选择 - 访问父类__private variables和使用@property decorator

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 
0

我觉得这个代码是不是史蒂夫的更清晰一点。史蒂夫的回答对我正在尝试做的事情最有帮助,所以谢谢!我用python 2.7和python 3.6测试了这个。

#! /usr/bin/python 
# 
# From https://stackoverflow.com/questions/797771/python-protected-attributes 
from __future__ import print_function 
import sys 

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): 
     print("In the getter, __stockName is %s" % self.__stockName, file=sys.stderr) 
     return self.__stockName 

    @name.setter # when you do Stock.name = x, it will call this function 
    def name(self, name): 
     print("In the setter, name is %s will become %s" % (self.__stockName, name), file=sys.stderr) 
     self.__stockName = name 

if __name__ == "__main__": 
    myStock = Stock("stock111") 

    try: 
     myStock.__stockName # It is private. You can't access it. 
    except AttributeError as a: 
     print("As expect, raised AttributeError", str(a), file=sys.stderr) 
    else: 
     print("myStock.__stockName did did *not* raise an AttributeError exception") 


    #Now you can myStock.name 
    myStock.name = "Murphy" 
    N = float(input("input to your stock: " + str(myStock.name)+" ? ")) 
    print("The value of %s is %s" % (myStock.name, N)) 
相关问题