0

我有两个类:基类 A 和派生类 B。在 BI 的构造函数中尝试使用 A 的构造函数来初始化实例。为什么派生类的构造函数中的赋值“self = A(x)”不起作用?

class A:
    def __init__(self, x=0):
        print "constructing A"
        self.x = x

    def printx(self):
        print "x =",self.x 

class B(A):
    def __init__(self,x):
        A.__init__(self)
        print "constructing B"
        self = A(x)
        self.printx()


b = B(2)
b.printx()

输出:

constructing A
constructing B
constructing A
x = 2
x = 0
4

2 回答 2

2

你不想调用构造函数B.__init__,你应该传递xA.__init__

class A:
    def __init__(self, x=0):
        print "constructing A"
        self.x = x
    def printx(self):
        print "x =",self.x 

class B(A):
    def __init__(self,x):
        A.__init__(self, x)
        print "constructing B"
        self.printx()
于 2012-11-21T21:59:45.033 回答
1

在 Python 中,将变量名(如self)视为“指向”或“引用”值。当您创建以下实例时B

b = B(2)

使用已分配给 的早期实例的B.__init__变量调用该方法。现在,在这个方法中,当 Python 到达selfB

        self = A(x)

变量self被重新分配给 的新实例A。的实例B仍然存在;self只是不再指向它。

请注意,这self是一个与 Python 中的任何其他变量一样的变量。(self不是关键字,它只是调用方法的第一个参数的约定self。)


顺便说一句,要self使用 的值进行初始化x,请使用

class B(A):
    def __init__(self,x):
        A.__init__(self, x)    # <-- Note the x
        print "constructing B"
        self.printx()

然后

b = B(2)
b.printx()

产量

constructing A
constructing B
x = 2
x = 2

当一个类具有备用构造函数时,例如getA,Python 中的典型模式是使用类方法:

class A(object):
    def __init__(self, x=0):
        print "constructing A"
        self.x = x

    def printx(self):
        print "x =",self.x 

    @classmethod
    def getA(cls, x):
        print('constructing getA')
        self = cls(x)
        self.y = 1
        return self

A现在用 classmethod创建一个实例getA,你会说

a = A.getA(x)

A作为第一个参数传递给类方法getA,并存储在变量中cls

这样做的好处是(而不是使用工厂函数getA),如果你A像这样子类化:

class B(A):
    def __init__(self,x):
        A.__init__(self, x)
        print "constructing B"
        self.printx()

B那么您也可以创建使用类方法的实例getA

b = B.getA(2)

产量

constructing getA
constructing A
constructing B
x = 2

print(type(b))
print(b.y)

产量

<class '__main__.B'>  # b is an instance of B
1   # showing the y attribute has been set.
于 2012-11-21T21:57:07.863 回答