2015-01-13 67 views
3
class ParentClass(object): 
    def __init__(self): 
     self.__x = 1 
     self.y = 10 
    def PRINT(self): 
     print (self.__x, self.y) 

class ChildClass(ParentClass): 
    def __init__(self): 
     super(ChildClass, self).__init__() 
     self.__x = 2 
     self.y = 20 


c = ChildClass() 
c.PRINT() 

为什么输出(1,20)?我知道我是如何得到20,但不是2而不是1?Python继承输出

回答

2

以两个下划线开头的成员是“私人”的。尽管Python没有一种真正的方法来限制对成员的访问,但是它的确有一些名称会让它们更复杂,因此它们保持或多或少的私密性。

所以你的情况,ParentClass有在PRINT方法所使用的__x场。并且ChildClass有一个单独的,独立的__x字段,不会在任何地方使用。所以对于打印,仅使用父母的__x

若要解决此问题,只需将两个下划线更改为单个下划线,即可将名称标记为“内部”,但不是该类型的专用标记。

+0

他说什么。此外,您仍然可以通过对名称进行计算并访问“ParentClass()._ ParentClass__x”来访问私有对象。 – 101

+0

帮你一个忙,不要访问名字上的成员。这正在破坏这一点。 – poke

+3

是不是所谓的名字* mangling *,不是名字* wrangling *?我敢肯定,争吵意味着围捕牲畜或争论,而捣乱意味着把事情搞砸,因此无法辨认。虽然我喜欢将变量名称四舍五入的心理形象...... – SethMMorton

0

对于类中的'私人'变量(__作为前缀),其名称已更改。您可以使用新名称相应地调用变量。就像这样:

#!/usr/bin/python 
# -*- coding: utf-8 -*- 

class ParentClass(object): 
    def __init__(self): 
     self.__x = 1 
     self.y = 10 
    def PRINT(self): 
     print (self.__x, self.y) 
     print (self._ParentClass__x, self.y) 
     print (self._ChildClass__x, self.y) 

class ChildClass(ParentClass): 
    def __init__(self): 
     super(ChildClass, self).__init__() 
     self.__x = 2 
     self.y = 20 


c = ChildClass() 
c.PRINT() 

OUTPUT:

(1, 20) 
(1, 20) 
(2, 20) 
+0

我意识到你的代码只是为了说明一个语言点,但是'.PRINT()'方法中的第三行有点吓人。如果我们这样做,'p = ParentClass(); p.PRINT()'我们得到'AttributeError:'ParentClass'对象没有属性'_ChildClass__x'' –

+0

@ PM2Ring我认为在这种情况下,PRINT()不会以这种方式被调用,因为这只是一个例子,而不是一个程序。 –

3

只是小幅上捅的回答,如果我们加入这一行展开......

the official Python tutorial

Any identifier of the form __spam (at least two leading underscores, at most one trailing underscore) is textually replaced with _classname__spam, where classname is the current class name with leading underscore(s) stripped. This mangling is done without regard to the syntactic position of the identifier, as long as it occurs within the definition of a class.

所以代码结尾:

print c._ChildClass__x, c._ParentClass__x, 

将打印

(1, 20) 
2 1