/sf/answers/2636054641/指出该程序:
class Parent(object):
i = 5;
def __init__(self):
self.i = 5
def doStuff(self):
print(self.i)
class Child(Parent, object):
def __init__(self):
super(Child, self).__init__()
self.i = 7
class Main():
def main(self):
m = Child()
print(m.i) #print 7
m.doStuff() #print 7
m = Main()
m.main()
Run Code Online (Sandbox Code Playgroud)
输出将是:
$ python Main.py
7
7
Run Code Online (Sandbox Code Playgroud)
然后将该答案与 Java 中的类似程序进行比较:
原因是因为 Java 在 Child 类中的 int i 声明使 i 成为类范围变量,而在 Python 子类化中没有这样的变量阴影。如果在 Java 的 Child 类中删除 int i ,它也会打印 7 和 7 。
在这种情况下,变量阴影是什么意思?
在这种情况下,变量阴影是什么意思?
变量阴影在所有情况下都意味着相同的事情,与上下文无关。它被定义为一个变量“隐藏”了另一个同名变量。因此,当发生变量阴影时,有两个或多个同名变量,它们的定义取决于它们的作用域(意味着它们的值可能因作用域不同而不同)。快速示例:
In [11]: def shadowing():
...: x = 1
...: def inner():
...: x = 2
...: print(x)
...: inner()
...: print(x)
...:
In [12]: shadowing()
2
1
Run Code Online (Sandbox Code Playgroud)
请注意,我们inner()首先调用,它指定x为2,并按此打印2。但是,这并不改变x在外部范围(即,第一x),由于x在inner被遮蔽的第一x。因此,在我们调用inner()并且调用返回之后,现在第一个x返回到作用域中,因此最后一个打印输出1。
在这个特定示例中,您引用的原作者说没有发生阴影(并且要清楚:没有发生在实例级别)。你会注意到,i在父呈现相同的值作为i在这个孩子。如果发生阴影,它们将具有不同的值,如上面的示例(即父级将拥有一个变量的副本,i而子级将拥有一个也名为 的变量的不同副本i)。然而,他们没有。i是7在双方家长和孩子。原作者指出 Python 的继承机制在这方面与 Java 不同。
小智 0
当某个范围(决策块、方法或内部类)中声明的变量与外部范围中声明的变量同名时,就会发生变量遮蔽。然后,您所在作用域中的变量会遮蔽(隐藏/屏蔽)外部作用域中的变量。
在上面的代码中,变量i在超类和子类中都被初始化。因此,超类中的初始化将被子类和类中的初始化所掩盖。
m = Child() #we initialized the child class with i=7
print(m.i) #eventhough we are calling a method in the super class the value of i in the super class is shadowed by the value we initialized the instance of the child class (m)
m.doStuff() #same thing here
Run Code Online (Sandbox Code Playgroud)