为什么我可以通过ClassName初始化另一个类来在运行时扩展一个类.__ init __(self)

时间:2017-07-08 01:33:56

标签: python class

我想知道为什么我可以在运行时使用以下代码扩展一个类:

class ClassA:
    def __init__(self):
        self.value = "1"
        ClassB.__init__(self)


class ClassB:
    def __init__(self):
        self.punk = "Punk"


test = ClassA()
print(dir(test))

这使我可以访问test.value和test.punk。但我不明白为什么。感谢。

3 个答案:

答案 0 :(得分:2)

ClassB.__init__没有使用self假设它实际上是ClassB的实例,因此在ClassA的实例上显式调用它是合法的,虽然有点奇怪。这与你写的

并没有什么不同
class ClassA:
    def __init__(self):
        self.value = "1"
        punker(self)

def punker(obj):
    obj.punk = "Punk"

punkerClassB.__init__并没有太大的不同,通过将ClassB定义为

,您可以更加轻松地看到这一事实
class ClassB:
    __init__ = punker

答案 1 :(得分:1)

您没有展开ClassB,只是在ClassB.__init__()个实例上执行了ClassA方法。 Python不会阻止您向任何对象添加新属性,例如:

class ClassA:
    def __init__(self):
        self.value = "1"

test = ClassA()
test.punk = "Punk"
print(dir(test))

但这并未扩展 - 该属性仅适用于您的test实例。例如,方法不会被继承。

class ClassA:
    def __init__(self):
        self.value = "1"
        ClassB.__init__(self)


class ClassB:
    def __init__(self):
        self.punk = "Punk"
    def foo(self):
        print("BAR!")

test = ClassA()
print(test.punk)  # OK
test.foo()  # ERR!

答案 2 :(得分:1)

这样做的原因是因为您正在使用ClassA修改self ClassB.__init__()参数。

当您在self内传递ClassBClassA.__init__()时,ClassB.__init__()接受了在已分配属性punk中传递的对象。 通常 self将是ClassB的实例,因为Python隐式传递self的值。但是因为你明确传入了一个不同的参数 - ClassA的一个实例 - Python使用了这个值。

这可以通过一个简单的例子看出:

>>> class A:
    def __init__(self):
        B.__init__(self)


>>> class B:
    def __init__(self):
        print('The type of self is: ', self)


>>> a = A()
The type of self is:  <__main__.A object at 0x03E9A050>
>>> 

正如@chepner所提到的,它就像你使用普通方法并在ClassA的构造函数中调用它一样:

>>> class A:
    def __init__(self):
        B.method(self)


>>> class B:
    def method(self):
        print('The type of self is: ', self)


>>> a = A()
The type of self is:  <__main__.A object at 0x03E9A670>
>>>