什么是可变阴影?

use*_*870 5 python python-3.x

/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 。

在这种情况下,变量阴影是什么意思?

Mat*_*ith 5

在这种情况下,变量阴影是什么意思?

变量阴影在所有情况下都意味着相同的事情,与上下文无关。它被定义为一个变量“隐藏”了另一个同名变量。因此,当发生变量阴影时,有两个或多个同名变量,它们的定义取决于它们的作用域(意味着它们的值可能因作用域不同而不同)。快速示例:

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()首先调用,它指定x2,并按此打印2。但是,这并不改变x在外部范围(即,第一x),由于xinner遮蔽的第一x。因此,在我们调用inner()并且调用返回之后,现在第一个x返回到作用域中,因此最后一个打印输出1

在这个特定示例中,您引用的原作者说没有发生阴影(并且要清楚:没有发生在实例级别)。你会注意到,i在父呈现相同的值作为i在这个孩子。如果发生阴影,它们将具有不同的值,如上面的示例(即父级将拥有一个变量的副本,i而子级将拥有一个也名为 的变量的不同副本i)。然而,他们没有。i7双方家长和孩子。原作者指出 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)