为了账号安全,请及时绑定邮箱和手机立即绑定

什么是可变阴影?

什么是可变阴影?

慕码人8056858 2021-09-14 17:42:23
https://stackoverflow.com/a/37657923/8061009指出对于程序: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 = 7class Main():    def main(self):        m = Child()        print(m.i) #print 7        m.doStuff() #print 7m = Main()m.main()输出将是:$ python Main.py 77然后将该答案与 Java 中的类似程序进行比较:原因是因为 Java 在 Child 类中的 int i 声明使 i 成为类范围变量,而在 Python 子类化中没有这样的变量阴影。如果在 Java 的 Child 类中删除 int i ,它也会打印 7 和 7 。在这种情况下,变量阴影是什么意思?
查看完整描述

3 回答

?
忽然笑

TA贡献1806条经验 获得超5个赞

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


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


In [11]: def shadowing():

    ...:     x = 1

    ...:     def inner():

    ...:         x = 2

    ...:         print(x)

    ...:     inner()

    ...:     print(x)

    ...:


In [12]: shadowing()

2

1

请注意,我们inner()首先调用,它指定x为2,并按此打印2。但是,这并不改变x在外部范围(即,第一x),由于x在inner被遮蔽的第一x。因此,在我们调用inner()并且调用返回之后,现在第一个x返回到作用域中,因此最后一个打印输出1。


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


查看完整回答
反对 回复 2021-09-14
?
繁星点点滴滴

TA贡献1803条经验 获得超3个赞

在 Java 中,方法和字段是根本不同的东西,按照完全不同的规则运行。子类只继承方法;字段特定于声明它们的类。如果子类声明的字段与父类中的字段同名,则它们完全不相关;父类的方法继续访问父类的版本,子类的方法访问其版本。这就是所谓的阴影。如果父类真的想让子类可以使用它的字段,它就必须为它定义 getter/setter 方法。

在 Python 中,没有这样的区别 - 方法基本上是其值恰好是一个函数的字段。此外,整个继承层次结构中的所有字段都存储在单个命名空间中(通常实现为名为 的 dict 属性__dict__)。如果孩子和父母对某事使用相同的名称,则他们必然指的是同一个对象。


查看完整回答
反对 回复 2021-09-14
?
慕无忌1623718

TA贡献1744条经验 获得超4个赞

当在特定范围(决策块、方法或内部类)内声明的变量与在外部范围内声明的变量具有相同名称时,就会发生变量阴影。然后,您所在作用域中的变量会隐藏(隐藏/屏蔽)外部作用域中的变量。


在上面的代码中,变量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


查看完整回答
反对 回复 2021-09-14
  • 3 回答
  • 0 关注
  • 216 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信