Python 访问父对象实例

2 投票
4 回答
1265 浏览
提问于 2025-04-16 01:50

我现在正在用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 个回答

0

你是在 main.py 里创建一个 pyconsole 的对象吗?如果你在 pyconsole 里有一个叫 PyConsole 的类,可以给它的 __init__ 方法加一个参数,用来接收游戏对象的列表。这样,你的 pyConsole 对象就能引用这些对象了。

希望这能帮到你。看起来你只是对 Python 如何处理导入模块有些误解。

1

除了其他回答之外,值得注意的是,当你把test.py当作脚本运行时,它的模块名是__main__。而当你从distancefrom00.py中导入test.py时,这会创建一个新的test模块。在主脚本中的bar和从distancefrom00.py访问的test.bar是完全不相关的。它们甚至不是同一个类:一个是__main__.BarClass,另一个是test.BarClass的实例。

这就是为什么你会看到两个输出,先是15然后是10:主脚本中的bar调用了它的switch方法,但test模块中的bar并没有被切换。

除了循环导入之外,把你的主脚本导入到另一个模块中也是有问题的。

2

问题是,有一个文件“pyconsole.py”需要能够调用另一个文件“main.py”中导入的其他对象的方法。

这听起来像是依赖关系搞错了。一般来说,应该避免让某个文件“回头”去调用主文件的内容。主文件“main.py”应该是把其他所有东西连接在一起的核心,而其他文件不应该依赖于它。从技术上讲,依赖关系应该形成一个有向无环图。一旦你在依赖关系图中发现了循环,就要把共同的部分移到一个新文件中,以打破这个循环。

所以,把“main.py”中被“pyconsole.py”使用的内容移到一个新文件里。然后让“main.py”和“pyconsole.py”都去导入这个新文件。

撰写回答