【问题标题】:Access objects from another module从另一个模块访问对象
【发布时间】:2013-03-01 22:37:15
【问题描述】:

我是一个非常缺乏经验的程序员,我创建一个游戏(使用 Python 3.3)作为学习练习。我目前有一个主模块和一个战斗模块。

游戏中的人由“Person”类的实例表示,并在主模块中创建。但是,战斗模块显然需要访问这些对象。此外,我稍后可能会创建更多模块,这些模块也需要访问这些对象。

如何允许其他模块从 main.py 访问 Person?

目前,main.py 有

import combat

在顶部;添加

import main

combat.py 似乎没有帮助。

我是否应该在一个单独的模块(common.py?)中实例化我的对象并将它们导入到需要访问它们的每个模块中?

【问题讨论】:

    标签: python object scope


    【解决方案1】:

    是的,您绝对应该考虑到这一点。您尝试的是模块之间的循环导入,这可能会带来很大的问题。如果combat 导入mainmain 导入combat,那么您可能会遇到异常,因为当combat 开始执行导入时,main 还没有完成执行。假设main 是您的启动脚本,它可能只需要实例化一个类或从另一个模块调用一个方法。也避免使用全局变量。即使现在看起来它们不会成为问题,但以后可能会在后面咬你。

    也就是说,您可以像这样引用模块的成员:

    import common
    x = common.some_method_in_common()
    y = common.SomeClass()
    

    from common import SomeClass
    y = SomeClass()
    

    就个人而言,我通常会避免在没有使用模块名称限定的情况下引用来自另一个模块的方法,但这也是合法的:

    from common import some_method_in_common
    x = some_method_in_common()
    

    我通常将from ... import ... 用于类,我通常将第一种形式用于方法。 (是的,这有时意味着除了导入模块本身之外,我还从模块导入了特定的类。)但这只是我个人的约定。

    强烈不鼓励使用的替代语法是

    from common import *
    y = SomeClass()
    

    这会将 common 的每个成员导入当前范围,但不以下划线 (_) 开头。我不鼓励它的原因是因为它使理解名称的来源并且使破坏事情变得太容易了。考虑这对导入:

    from common import *
    from some_other_module import *
    y = SomeClass()
    

    SomeClass 来自哪个模块?除了去看看这两个模块之外,没有别的办法。更糟糕的是,如果 两个 模块定义 SomeClassSomeClass 之后被添加到 some_other_module 怎么办?

    【讨论】:

    • 谢谢,很有帮助。
    • 不客气。如果某人提供的答案回答了您的问题,您可以通过单击上/下投票按钮下方的复选标记将其标记为答案。
    【解决方案2】:

    如果您已经使用import maincombat 模块中导入了主模块,那么您应该使用main.*(在主模块中实现的东西)来访问其中的类和方法。

    示例:

    import main
    
    person = main.Person()
    

    您也可以使用from main import *import Person 来避免前面的main.*。

    http://effbot.org/zone/import-confusion.htm 中描述了一些导入模块的规则:

    1. import X 导入模块 X,并创建对该模块的引用 当前命名空间中的模块。或者换句话说,在你跑完之后 这个语句,你可以使用X.name来引用定义的东西 模块 X。
    2. from X import * 导入模块 X,并在 该模块定义的所有公共对象的当前命名空间 (也就是说,所有没有以“_”开头的名称的东西)。或者 换句话说,在你运行这条语句之后,你可以简单地使用 一个简单的名称来引用模块 X 中定义的东西。但 X 本身是 未定义,所以X.name 不起作用。如果名字已经 定义,它被新版本取代。如果 X 中的名称是 更改为指向其他对象,您的模块不会注意到。
    3. from X import a, b, c 导入模块 X,并创建引用 在给定对象的当前命名空间中。或者换句话说, 您现在可以在程序中使用abc
    4. 最后,X = __import__(‘X’)import X 一样工作,具有 你的区别

      1) 将模块名称作为字符串传递,并且

      2) 将其显式分配给当前命名空间中的变量。

    【讨论】:

    • 天啊!我忘了这件事。愚蠢的错误。
    • 请不要建议from X import *
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-23
    • 2017-05-12
    • 1970-01-01
    • 2014-07-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多