3

私はプログラミングの初心者で、最近 Python とオブジェクト指向プログラミングの基礎を学びました。多くのグローバル変数を持つことは一般的に悪い考えであり、代わりにそれらすべてをクラスに入れることができることを私は知っています。これは正しい方法ですか?

class GameState(object):
    def __init__(self):
        self.variable1 = 1
        self.variable2 = 2
        self.list = [3, 4, 5]

g_state = GameState()

また、g_state 内の変数にアクセスしたい場合、どのように実行するのが最善でしょうか?

アクセスが必要な関数/クラスに g_state を渡しますか? ゲッターを実装して呼び出す?g_state.variable1 を直接使用しますか?

それとももっと良い方法がありますか?

編集:より具体的には、pygame を使用して python でゲームを作成しようとしており、ゲーム状態変数をクラスに入れて、大量のグローバル変数が横たわらないようにすることを考えていました。これらの変数に適切な設計でアクセスする方法がわからないので、後で問題が発生することはありません。

4

4 に答える 4

5

グローバル変数が多すぎるのは得策ではありません。グローバル名前空間が汚染されていると、エラーが発生する可能性があります。

ただし、そのためにクラスに入れるのはやめましょう。本当に多くの変数がある場合は、プログラムを複数のモジュールに分割することを検討する必要があります。

また、Python では JavaScript のようにグローバル変数を作成できないことも理解しておいてください。変数は常にモジュールの下にスコープされます。

例を挙げて説明しましょう。モジュール a.py:

A = 42

モジュール b.py:

import a

print(A)

あなたは何を得ますか?NameError. なんで?変数 A はグローバルではないため、 module の下にありますa。参照するために使用する必要がありますa.A

クラスの下に変数を詰め込む必要はありません。それらは名前空間として機能するモジュールの下にあり、何も問題はありません。

于 2012-12-25T16:52:00.527 に答える
2

変数を格納するためだけにクラスを作成する必要はありません。クラスは、それぞれが一意の値を持つそのクラスの複数のインスタンスが本当に必要な場合にのみ必要になります。

ただし、単一のグローバル状態の場合、この目的には辞書オブジェクトで十分です。必要に応じて、構成と状態専用のモジュールに保存できます。

conf.py

GAME_STATE = {
    'level': 0,
    'score': 0,
    'misc': [1,2,3],
}

main.py

import conf

conf.GAME_STATE['score'] = 100

したがって、他のモジュールはconf.pyモジュールをインポートして状態辞書にアクセスできます。このオブジェクトには、必要なタイプを格納できます。また、必要に応じてこれらの値をディスクにシリアル化し、プログラムの将来の実行時にそれらを読み戻し、構成オプションと一緒に保持するための機能を追加するのに便利な場所も提供します。

于 2012-12-25T17:42:14.077 に答える
2

変数にアクセスする方法は 2 つあります。グローバル オブジェクトを 1 つ使用する方法と、インスタンスを関数に渡す方法です。最初のものは、一般的にも悪い考えです。2番目の方が優れています。ただし、すべての変数を含む単一のオブジェクトを作成しないでください。(最初のコメントを参照)。

オブジェクトを渡す場合、考慮すべきことが他にもあります。適切であれば、メンバー関数として実装することをお勧めします。

class VariableBox(object):
    def __init__(self):
        self.variable1 = 1
        self.variable2 = 2
        self.list = [3, 4, 5]

    def do_something(self):
        self.variable1 = self.variable2 + 42
        return self.variable1
于 2012-12-25T16:52:31.450 に答える
1

いいえ!!!を構築するVariableBoxことはあなたを助けませ

必要な var を適用する場所に使用するだけです。グローバル変数が多すぎる場合は、グローバルと見なすべきものと、特定の構造に関係するものに問題があります。または、代わりに vars の名前付けや配列の作成が困難になることさえありvar1, var2, var3, ...ます。

クラスは、オブジェクトを構築するために設計されています。つまり、特定性は異なりますが、同じ基礎を持つものを作成するために設計されています。価値のあるクラスとは、エンティティと、このエンティティの主な動作をある程度定義するものです。

編集

Python は可視性の制約を提供しないため、単純にデータをクラスに詰め込むだけではデータを保護できません。エントリには、クラスのインスタンスがある場所からアクセスできます。

ゲッターを作成するか、単にクラスのインスタンスを維持するかは、どちらを使用するかを決定するだけの問題です。わかりやすくするために、ゲームにコントローラーを作成することをお勧めします。これにより、ゲーム アセットとゲームプレイの間にこのインターフェイスが作成されます。

たとえば、実行中に次のことができます。

class Controller:

    def __init__():
        self.turn = 0
        self. ...

    def begin():
        self.turn += 1
        self.opening_scene()

class Gameplay:

    def __init__(self, num_players, turn, ...):
        self.turn = turn # if it happens you want to use this value in the game
        self.num_player = num_players

# Main loop
controller = Controller()
controller.num_players = int(raw_input("Number of players: "))

gameplay = Gameplay(controller.num_players, controller.turn)
while True:

    if gameplay.action == ...:
    elif ...:
        ...
    elif *next turn*:
        controller.next_turn() # to set things up to next turn
    else ...:
        ...

内部Controllerで相関情報を集約することができるため、今後の関数でパラメーターの無限のリストが表示されることはありません。

いずれにせよ、どれが最適かはわかりません。これらのモジュール性の問題を研究している人はたくさんいますが、私はその 1 人ではありません。したがって、これはアプリで何がうまくいくかについての私の見解です。

于 2012-12-25T16:54:42.150 に答える