Python中使用super()的变量传递问题求助
嘿,问题不在
super(),是变量作用域搞的鬼! 首先得给你澄清:你的super()用法其实没毛病,真正导致输出中断、报错的是变量x的作用域问题,咱们来一步步理清楚:
1. 为什么你的代码会输出到一半就卡住/报错?
先看你的sandbox.py代码:
from module1 import Testy class Sandy(Testy): def run(self): print("This is value of x in Sandy: %d" % x) super(Sandy, self).mymet() if __name__ == "__main__": x = 4 test = Sandy() test.run()
你在if __name__ == "__main__"这个代码块里定义了x=4,但这个x是仅在该代码块内有效的局部变量,而Sandy.run()方法里直接引用x时,Python会按「方法局部→类变量→模块全局变量」的顺序查找,根本找不到这个x,所以运行时会直接抛出NameError: name 'x' is not defined,这就是你看到输出只显示一半的原因(报错中断了程序)。
再看module1.py里的Testy.mymet():
class Testy(object): def mymet(self): print("This is the value of x in Testy %d: " % x)
这里同样直接引用x,就算前面的问题解决了,module1.py的作用域里也没有定义x,照样会报错。
2. 两种修复方案,推荐第二种
方案一:把x改成模块全局变量
把sandbox.py里的x=4移到main块外面,变成模块级的全局变量:
from module1 import Testy # 定义模块全局变量x,整个模块都能访问 x = 4 class Sandy(Testy): def run(self): print("This is value of x in Sandy: %d" % x) super(Sandy, self).mymet() if __name__ == "__main__": test = Sandy() test.run()
但这时候还要修改module1.py,导入sandbox的x:
from sandbox import x class Testy(object): def mymet(self): print("This is the value of x in Testy: %d" % x)
不过这种全局变量的写法不太推荐,容易引发其他问题。
方案二:用实例变量/参数传递(更符合面向对象思想)
这是更优雅的做法,彻底摆脱全局变量:
修改sandbox.py:
from module1 import Testy class Sandy(Testy): def __init__(self, x): super().__init__() self.x = x # 把x存为实例的属性 def run(self): print("This is value of x in Sandy: %d" % self.x) super().mymet(self.x) # Python3可以简化super()写法,把x作为参数传给父类方法 if __name__ == "__main__": x = 4 test = Sandy(x) test.run()
修改module1.py:
class Testy(object): def mymet(self, x): # 接收传递过来的x参数 print("This is the value of x in Testy: %d" % x)
这样运行后就能正常输出:
This is value of x in Sandy: 4 This is the value of x in Testy: 4
3. 补充下super()的小知识
你的super(Sandy, self).mymet()是Python2的写法,Python3里可以直接写成super().mymet(),效果完全一样,都是调用父类的对应方法,这部分你写的是对的~
内容的提问来源于stack exchange,提问作者JPow
相关产品推荐
相关产品推荐

