3

昨日、Python (3.3 を使用) を学習する演習として、テキスト ベースのゲームの作成を開始しました。私は「テキストベースのゲーム」と言っていますが、自分で選択する冒険というよりも、泥のようなものを意味しています。super()とにかく、昨日を使用して継承と多重継承を処理する方法を見つけたときは本当に興奮しましたが、引数の受け渡しがコードを非常に混乱させ、多くの小さな緩い変数をジャグリングする必要があることがわかりました。また、保存ファイルの作成はかなり悪夢のように思えました。

そこで、「特定のクラス階層が 1 つの引数、つまり辞書を取り、その辞書を返すだけだとしたら?」と考えました。例として、init メソッドに切り詰められた 2 つのクラスを次に示します。

class Actor:
    def __init__(self, in_dict,**kwds):
        super().__init__(**kwds)
        self._everything = in_dict
        self._name = in_dict["name"]
        self._size = in_dict["size"]
        self._location = in_dict["location"]
        self._triggers = in_dict["triggers"]
        self._effects = in_dict["effects"]
        self._goals = in_dict["goals"]
        self._action_list = in_dict["action list"] 
        self._last_action = ''
        self._current_action = '' # both ._last_action and ._current_action get updated by .update_action()

class Item(Actor):
    def __init__(self,in_dict,**kwds)
        super().__init__(in_dict,**kwds)
        self._can_contain = in_dict("can contain") #boolean entry
        self._inventory = in_dict("can contain") #either a list or dict entry

class Player(Actor):
    def __init__(self, in_dict,**kwds):
        super().__init__(in_dict,**kwds)
        self._inventory = in_dict["inventory"] #entry should be a Container object
        self._stats = in_dict["stats"]

渡される dict の例:

playerdict = {'name' : '', 'size' : '0', 'location' : '', 'triggers' : None, 'effects' : None, 'goals' : None, 'action list' = None, 'inventory' : Container(), 'stats' : None,}

(辞書が渡されると、 はNoneに置き換えられます。){}

したがって、**kwds の巨大なペイロードの代わりに、in_dict が前のクラスに渡されます。私はこれが好きです:

  1. これにより、コードがよりすっきりと管理しやすくなります。
  2. 辞書に、呼び出されたキーのエントリが少なくともいくつかある限り、コードが壊れることはありません。また、与えられた引数が使用されなくても問題ありません。
  3. ファイル IO がはるかに簡単になったようです (dict として保存されたプレイヤー データの辞書、dict として保存されたアイテム データの辞書など)。

**kwds私は(編集:明らかに私はしなかった)のポイントを取得し、より少ない引数を渡すときに面倒に見えませんでした。これは、各インスタンスの作成時に多数の属性の必要性に対処する快適な方法のようです

とは言っても、私はまだ主要な python noob です。だから、私の質問は次のとおり です。同じ dict を super() を介して基本クラスに繰り返し渡すことが、厄介な (大きくて雑然とした) **kwds パスでそれを厳しくするよりも悪い考えになる根本的な理由はありますか? (例えば、私のレベルの誰かが知らない通訳者の問題。)

編集:

以前は、新しい Player の作成は、属性ごとに渡された引数を使用して、次のようになっていました。

bob = Player('bob', Location = 'here', ... etc.)   

必要な引数の数が急増したため、Engine オブジェクトからのメソッド呼び出しを壊さないようにするために、本当に必要な属性だけを含めました。

これは、これまでの回答とコメントから得た印象です。

内容を変更する機会がなく (Kirk Strauser)、辞書が常にあるべきものを備えている (goncalopp) 限り、同じ辞書を送信することに「問題」はありません。本当の答えは、質問が間違っていたということであり、in_dict代わりに使用すること**kwdsは冗長です。

これは正しいでしょうか?(また、素晴らしい多様なフィードバックをありがとう!)

4

3 に答える 3

0

これは python 固有のものではありませんが、このように引数を渡すことで見られる最大の問題は、カプセル化が壊れることです。どのクラスも引数を変更する可能性があり、各クラスでどの引数が期待されているかを判断するのははるかに難しく、コードが理解しにくくなり、デバッグが難しくなります。

__init__各クラスで明示的に引数を消費し、残りのスーパーを呼び出すことを検討してください。それらを明示的にする必要はありません:

class ClassA( object ):
    def __init__(self, arg1, arg2=""):
        pass

class ClassB( ClassA ):
    def __init__(self, arg3, arg4="", *args, **kwargs):
        ClassA.__init__(self, *args, **kwargs)


ClassB(3,4,1,2)

変数を初期化せずにそのままにして、メソッドを使用して変数を設定することもできます。その後、さまざまなクラスでさまざまなメソッドを使用でき、すべてのサブクラスがスーパークラス メソッドにアクセスできるようになります。

于 2013-10-22T16:02:29.080 に答える