8

私は非常に経験の浅いプログラマーであり、学習演習として(Python 3.3を使用して)ゲームを作成しています。現在、メインモジュールと戦闘モジュールがあります。

ゲーム内の人物は、クラス「Person」のインスタンスで表され、メインモジュールで作成されます。ただし、戦闘モジュールは明らかにこれらのオブジェクトにアクセスする必要があります。さらに、後でそれらのオブジェクトへのアクセスも必要になるモジュールをさらに作成する予定です。

他のモジュールがmain.pyからPersonsにアクセスできるようにするにはどうすればよいですか?

現状では、main.pyには

import combat

頂点で; 追加する

import main

戦闘する.pyは役に立たないようです。

オブジェクトを別のモジュール(common.py?)でインスタンス化し、それらにアクセスする必要があるすべてのモジュールにインポートする必要がありますか?

4

2 に答える 2

10

はい、間違いなくこれを除外する必要があります。あなたが試したのはモジュール間の循環インポートであり、それは非常に問題になる可能性があります。combatインポートmainおよびmainインポートの場合、インポートの実行を開始したときに実行が終了しないcombatため、例外が発生する可能性があります。起動スクリプトであると仮定すると、おそらくクラスをインスタンス化するか、別のモジュールからメソッドを呼び出すだけです。グローバル変数も避けてください。今は問題にならないように見えても、後で後ろに噛み付く可能性があります。maincombatmain

そうは言っても、次のようにモジュールのメンバーを参照できます。

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から来ていますか?2つのモジュールを見に行く以外に言う方法はありません。さらに悪いことに、両方のモジュールが定義されているSomeClassSomeClass、後で追加された場合はどうなりますsome_other_moduleか?

于 2013-03-01T22:43:53.913 に答える
1

combatを使用してメインモジュールをモジュールにインポートしたimport main場合は、main。*(メインモジュールに実装されているもの)を使用して、そこにあるクラスとメソッドにアクセスする必要があります。

例:

import main

person = main.Person()

また、前のmain。*を使用from main import *または回避することもできます。import Person

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をインポートし、現在の名前空間に指定されたオブジェクトへの参照を作成します。つまり、プログラムでandをa使用できるようにbなりました。c
  4. 最後に、X = __import__(‘X’)のようimport Xに機能しますが、違いは

    1)モジュール名を文字列として渡し、

    2)現在の名前空間の変数に明示的に割り当てます。

于 2013-03-01T22:46:30.217 に答える