Python 访问父对象实例
我现在正在用PyGame写一个多文件的Python(2.6.5)游戏。问题是,有一个文件叫“pyconsole.py”,它需要能够调用主文件“main.py”中导入的其他对象的方法。主文件里有一个列表,用来存放所有游戏对象的实例(比如玩家的飞船、敌人的飞船、空间站等等),但我在“pyconsole.py”里却无法从这个列表中调用方法,尽管我在主循环开始之前已经在“main.py”里做了from pyconsole import *
。这是不是根本不可能?我是不是应该用M4把所有文件合并成一个文件,然后进行字节码编译和测试/分发呢?
举个例子:
bash$ cat test.py
#!/usr/bin/python
import math, distancefrom00
foo = 5
class BarClass:
def __init__(self):
self.baz = 10
def get(self):
print "The BAZ is ", self.baz
def switch(self)
self.baz = 15
self.get()
bar = BarClass()
def main():
bar.switch()
print distancefrom00.calculate([2, 4])
if __name__ == '__main__': main()
bash$ cat distancefrom00.py
#!/usr/bin/python
import math
import test
def calculate(otherpoint):
return str(math.hypot(otherpoint[0], otherpoint[1]))+" (foo = "+str(test.foo)+"; "+test.bar.get()+")"
bash$ python test.py
The BAZ is 15
The BAZ is 10
Traceback (most recent call last):
File "test.py", line 24, in <module>
if __name__ == '__main__': main()
File "test.py", line 22, in main
print distancefrom00.calculate([2, 4])
File "/home/archie/Development/Python/Import Test/distancefrom00.py", line 8, in calculate
return str(math.hypot(otherpoint[0], otherpoint[1]))+" (foo = "+str(test.foo)+"; "+test.bar.get()+")"
TypeError: cannot concatenate 'str' and 'NoneType' objects
如果我对Python的命名、类和这些东西的理解没错的话,NoneType意味着名称test.bar.get()
——也就是test.bar
——没有被赋值给任何东西。
4 个回答
你是在 main.py
里创建一个 pyconsole
的对象吗?如果你在 pyconsole
里有一个叫 PyConsole
的类,可以给它的 __init__
方法加一个参数,用来接收游戏对象的列表。这样,你的 pyConsole
对象就能引用这些对象了。
希望这能帮到你。看起来你只是对 Python 如何处理导入模块有些误解。
除了其他回答之外,值得注意的是,当你把test.py当作脚本运行时,它的模块名是__main__
。而当你从distancefrom00.py
中导入test.py
时,这会创建一个新的test
模块。在主脚本中的bar
和从distancefrom00.py
访问的test.bar
是完全不相关的。它们甚至不是同一个类:一个是__main__.BarClass
,另一个是test.BarClass
的实例。
这就是为什么你会看到两个输出,先是15然后是10:主脚本中的bar
调用了它的switch
方法,但test
模块中的bar
并没有被切换。
除了循环导入之外,把你的主脚本导入到另一个模块中也是有问题的。
问题是,有一个文件“pyconsole.py”需要能够调用另一个文件“main.py”中导入的其他对象的方法。
这听起来像是依赖关系搞错了。一般来说,应该避免让某个文件“回头”去调用主文件的内容。主文件“main.py”应该是把其他所有东西连接在一起的核心,而其他文件不应该依赖于它。从技术上讲,依赖关系应该形成一个有向无环图。一旦你在依赖关系图中发现了循环,就要把共同的部分移到一个新文件中,以打破这个循环。
所以,把“main.py”中被“pyconsole.py”使用的内容移到一个新文件里。然后让“main.py”和“pyconsole.py”都去导入这个新文件。