类,隐藏属性和继承

时间:2014-10-08 16:44:39

标签: python class python-2.7 inheritance attributes

我是OOP和Python的新手。几乎所有我知道的都是自学成才,所以如果你能为我提供阅读的链接,我将不胜感激,因为我不知道我应该寻求的确切术语,以澄清我的疑虑。

到目前为止,这是我的代码:

class Point(object):
    x = 2
    y = 3

    def __init__(self, x, y):
        self.x_a = x
        self.y_b = y

class RectPoint(Point):

    def __init__(self, x, y):
        self.x_1 = x
        self.y_1 = y
        self.dist = (x*x + y*y)**0.5


class CircPoint(Point):
    pass

a = Point(3,4)
b = CircPoint(3,4)
c = RectPoint(3,4)

print a.x     # 2
print a.y     # 3
print a.x_a   # 3
print a.y_b   # 4
print b.x     # 2
print b.y     # 3
print b.x_a   # 3
print b.y_b   # 4
print c.x     # 2
print c.y     # 3
print c.x_1   # 3
print c.y_1   # 4
print c.dist  # 5.0
print c.x_a   # AttributeError
print c.y_b   # AttributeError

为什么属性self.x_aself.y_b不适用于课程RectPoint但可用于CircPoint?我怎么能让它们可用?

此外,为什么self.xself.y可用于RectPointCircPoint这两个类?

进一步阅读的链接也将受到赞赏(代替解释)

3 个答案:

答案 0 :(得分:4)

您的RectPoint.__init__方法屏蔽 Point.__init__方法。由于Point.__init__个实例未执行RectPoint,因此永远不会设置self.x_aself.y_b属性。这是因为Python首先搜索实例,然后搜索类,然后搜索属性的基类。这里的方法确实是专门的属性。在创建类的实例时,Python会在类上查找__init__方法,然后在基类上查找。

CircPoint未实现自己的__init__,因此找到并使用Point.__init__self.x_aself.y_b 集。

您为xy提供了具体的 class 属性; Python使用相同的搜索顺序查找这些内容;它们没有在实例上设置,最终会在Point基类上找到;要么是因为你有一个Point实例,要么是Point的子类,并且搜索了该子类的基类。

您可以显式__init__调用已覆盖的RectPoint.__init__方法:

class RectPoint(Point):
    def __init__(self, x, y):
        super(RectPoint, self).__init__(x, y)
        self.x_1 = x
        self.y_1 = y
        self.dist = (x*x + y*y)**0.5

super() function可让您在此处访问原始Point.__init__方法,并先调用它。该方法然后设置self.x_aself.y_b属性,之后它将返回,RectPoint.__init__方法将设置更多属性。

Class chapter of the Python tutorial详细介绍了所有这些内容。

答案 1 :(得分:1)

RectPoint个实例没有x_ay_b个属性,因为您的RectPoint.__init__方法从不定义它们,也从不调用Point.__init__

xy是类属性,可在定义它们的类,任何子类和这些类的实例上使用(除非通过在子类或实例上设置属性来覆盖) 。 self.x首先在实例上查找x,然后在类及其父类中找不到它。

答案 2 :(得分:1)

当你在Python类中覆盖 init 时,你仍然需要调用你继承的类的 init 方法,否则这些属性将无法用于你的子类。您可以使用super方法执行此操作。在RectPoint中,按照以下方式更改 init 方法:

def __init__(self, *args, **kwargs):
    self.x_1 = x
    self.y_1 = y
    self.dist = (x*x + y*y)**0.5
    super(RectPoint,self).__init__(*args,**kwargs)