我想知道为什么我可以在运行时使用以下代码扩展一个类:
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。但我不明白为什么。感谢。
答案 0 :(得分:2)
ClassB.__init__
没有使用self
假设它实际上是ClassB
的实例,因此在ClassA
的实例上显式调用它是合法的,虽然有点奇怪。这与你写的
class ClassA:
def __init__(self):
self.value = "1"
punker(self)
def punker(obj):
obj.punk = "Punk"
punker
与ClassB.__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
内传递ClassB
到ClassA.__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>
>>>