0

私は昨夜遅くに似たような、しかしお粗末な質問をしました(インスタンス変数へのアクセスですが、Pythonのインスタンスメソッドではありません)。これはかなりの混乱を引き起こしました。できれば削除しますが、できません。

これで、質問をより明確に行うことができます。

背景:Python構文を学ぶためにブラックジャックゲームを構築しようとしています。各ハンドはHandクラスのインスタンスであり、現在、ハンドを分割できるようにしようとしています。したがって、ハンドを分割するときは、2つの新しいハンドインスタンスを作成する必要があります。さらに分割する可能性があることを考えると、同じ方法を再分割して手を再分割したいと思います。したがって、(私は)Handクラスを動的にインスタンス化する必要があります。

以下は、メカニズムをブロックするために使用しているコードスニペットです。

import os

os.system("clear")

class Hand():
    instances=[]
    def __init__(self, hand_a, name):
        Hand.instances.append(self)
        self.name = name
        self.hand_a = hand_a

    def show_hand(self):
        ln = len(self.hand_a)
        for x in range(ln):
            print self.hand_a[x]

class Creation():
    def __init__(self):
        pass
    def create_name(self):
        hil = len(Hand.instances)
        new_name = 'hand_' + str(hil + 1)
        return(new_name)

    def new_instance(self):
        new_dict = {0: 'Ace of Clubs', 1: '10 of Diamonds'}
        new_hand_name = {}
        new_hand_name.setdefault(self.create_name(), None)
        print new_hand_name
        new_hand_name[0] = Hand(new_dict, self.create_name())
        print new_hand_name[0]  


hand = Hand("blah", 'hand')
hand_z = Hand("blah_z", 'hand_z')
creation = Creation()
creation.new_instance()

出力は次のとおりです。

{'hand_3': None}
<__main__.Hand instance at 0x10e0f06c8>

次のステートメントによって作成されたインスタンスに関して:

new_hand_name[0] = Hand(new_dict, self.create_name)

new_hand_name[0]newはインスタンスを参照する変数ですか?または、hand_3変数ですか?

つまり、インスタンスメソッドを呼び出すときに、使用できますhand_3.show_hand()か?

4

1 に答える 1

2

まず、質問に答えます。new_hand_name[0]はインスタンスを参照する変数です。具体的にはnew_hand_name、キー0によってアクセスされるディクショナリの値です。new_hand_nameディクショナリを印刷すると、次のようになります。

{'hand_3': None, 0: <__main__.Hand instance at 0x10e0f06c8>}

辞書にの値を追加する"hand_3"必要はありませんが、それに関しては、辞書も必要です。

あなたが本当にやりたいことは、新しいクラスの動的なインスタンス化とは何の関係もありません。それはあなたの問題とは何の関係もありません。問題は、ハンドがカードの単一のリストを表す場合があるが、カードのリストのリストを表す場合もあり、それぞれを別々にプレイする必要があることです。これを解決するための優れた方法の1つは、プレーヤーとハンドを分離し、プレーヤーが複数のハンドを持つことができるようにすることです。この設計を想像してみてください(ブラックジャック機能の多くも省略していますが、プログラムの残りの部分でこれをどのように機能させるかについてのアイデアを与えるために少し残しています)。

def draw_random_card():
    """
    whatever function returns a new card. Might be in a Deck object, depends on
    your design
    """
    # some code here

class Player:
    def __init__(self):
        self.hands = []

    def deal(self):
        """add a random hand"""
        self.hands.append(Hand([draw_random_card(), draw_random_card()]))

    def split(self, hand):
        """split the given hand"""
        self.hands.remove(hand)
        self.hands += hand.split()

class Hand:
    def __init__(self, cards):
        self.cards = cards

    def hit(self):
        """add a random card"""
        self.cards.append(draw_random_card())

    def split(self):
        """split and return a pair of Hand objects"""
        return [Hand(self.cards[0], draw_random_card()),
                Hand(self.cards[1], draw_random_card())]

簡単じゃないですか?

あなたのコメントに応えて:

  1. self.hands[0]Playersクラスとして、またはPlayersクラス内で特定のハンドを参照できますself.hands[1]

  2. 特定の手を追跡したい場合は、その手を参照する文字列を渡す代わりに、その手を渡すだけで済みます。このような:

    def process_hand(hand):
        """do something to a hand of cards"""
        h.hit()
        print h.cards()
        h.hit()
    h = Hand(cards)
    process_hand(h)
    

    これは重要です。関数で手に加えた変更は、実際の手自体で機能します。なぜあなたが調べなければならない文字列を渡すという余分なステップを置くのですか?

    また、ベットなど、各ハンドに固有の情報は、おそらくHandクラス自体に格納する必要があることに注意してください。

  3. それぞれの手を特定の名前で参照したい場合(この場合も必要ありません)、それらの名前をキーとして持つ辞書を使用するだけです。

    self.hands = {}
    self.hands["hand1"] = Hand([card1, card2])
    self.hands["hand2"] = Hand([card1, card2])
    print self.hands["hand1"]
    

    しかし、繰り返しになりますが、これを行う正当な理由はおそらくありません。(これは、新しい変数を「動的に」インスタンス化することとは非常に異なることに注意してください。辞書がどのように機能するかを調べることをお勧めします)。

于 2012-08-29T21:09:58.517 に答える