49307


簡単なカードゲームを作りながらオブジェクト指向を勉強しようとしているのですが全然わかりません。  
`def draw(self, p1n, p1c, p2n, p2c):`この`self`はインスタンス自身になる(game =
Game()だったらgame.p1nということ？意味これはgameインスタンスのp1nですよ。)と聞いて私、自身意味はよく分からないのですが何となくclassを使って複数のインスタンスを（引数を与えて出てくるもの）作る事ができる。

その一個一個を識別するためにselfはあるんだと考えています。

**問題**  
なのに `def__gt__(self,
c2):`ではインスタンス自身になる引数selfをc1の引数として使っています。この場合、主体となるインスタンスが不明なるのでは（自分で言っておるけど意味はよくわかっていまっせん。識別番号みたいなもの？）と考えて夜も眠れません。

なぜ`def __gt__(self, c1, c2):`のように識別とするselfがいらないのでしょうか？  
特殊メソッドだからでしょうか？

[code]

    from random import shuffle
    
    class Card(object):
        """docstring for Card"""
        suits = ['spades', 'hearts','diamonds', 'clubs']
        values = [None, None, '2', '3', '4', '5', '6', '7', '8', '9', '10',
                  'Jack', 'Queen', 'King', 'Ace']
        def __init__(self, v, s):
            self.value = v
            self.suit = s
        def __lt__(self, c2):
            if self.value < c2.value:
                return True
            if self.value == c2.value:
                if self.suit < c2.suit:
                    return True
                else:
                    return False
    
        def __gt__(self, c2):
            print(c2.__class__.__name__)
            # print(c2.value)
            # print(self)
            # print(self.value)
            # reprを消してやるとvaluesの中身が見れる。
            # print(self.values)
            # selfにはCardクラスの名前と第一に引数が入ってる。
    
            if self.value > c2.value:
                return True
            if self.value == c2.value:
                if self.suit > c2.suit:
                    return True
                else:
                    return False
        def __repr__(self):
            v = self.values[self.value] + 'of' \
                + self.suits[self.suit]
            return v
    
    # ここでトランプを生成
    # デッキから一枚カードを取り出すメソッドもある！
    class Deck:
        def __init__(self):
            self.cards = []
            for i in range(2, 15):
                for j in range(4):
                    self.cards.append(Card(i, j))
            shuffle(self.cards)
            #print(self.cards)
    
        def rm_card(self):
            if len(self.cards) == 0:
                return
            return self.cards.pop()
    
    # deck = Deck()
    # for card in deck.cards:
    #   print(card)
    
    class Player:
        def __init__(self, name):
            self.wins = 0
            self.card = None
            self.name = name
    
    # Gameクラスがスタート
    # 次にデッキクラス
    class Game:
        def __init__(self):
            # プレーヤー１名前と表示されてその後ろに名前を入力
            name1 = input('プレーヤー１名前')
            name2 = input('プレーヤー２名前')
            self.deck = Deck()
            self.p1 = Player(name1)
            self.p2 = Player(name2)
    
        def wins(self, winner):
            w = 'このラウンドは{}が勝ちました'
            w = w.format(winner)
            print(w)
    
        def draw(self, p1n, p1c, p2n, p2c):
            #ここのselfは一体どうなってる
            # print(format(self)) selfにはGameクラスが入ってる？
            # print(p1n)
            d = '{}は{}、{}は{}を引きました。'
            d = d.format(p1n, p1c, p2n, p2c)
            print(d)
    
        def play_game(self):
            cards = self.deck.cards
            print('戦争を始めます')
            # デッキが2枚以下になるまでループ
            while len(cards) >= 2:
                m = 'qで終了、それ以外のキーでplay:'
                response = input(m)
                if response == 'q':
                    break
                p1c = self.deck.rm_card()
                # gtがあるのはCard() gtを使うのはGame().play_gameのGame().Deck().rm_card
                # self.deck = Deck() → cards = self.deck.cards deck.cardsはDeckクラスのself.cards = []
                # self.deck.rm_card → Game().Deck().rm_card
                #print(self.deck.cards)
                p2c = self.deck.rm_card()
                #print(self.deck.cards)
                p1n = self.p1.name
                p2n = self.p2.name
                #自動で引かれたカードが何か表示
                self.draw(p1n, p1c, p2n, p2c)
                #どっちのカードが強いか比較して処理する。
                if p1c > p2c:
                    # playerクラスのwinに値を追加
                    self.p1.wins += 1
                    self.wins(self.p1.name)
                else:
                    self.p2.wins += 1
                    self.wins(self.p2.name)
    
            win = self.winner(self.p1, self.p2)
            print('ゲーム終了、{}の勝利です！'.format(win))
    
        def winner(self, p1, p2):
            if p1.wins > p2.wins:
                return p1.name
            if p1.wins < p2.wins:
                return p2.name
            return '引き分け!'
    
    game = Game()
    game.play_game()
    print(game.name1)
    
[/code]

[ここのselfの説明](http://yoshiori.hatenablog.com/entry/20090716/1247720811)を読んで以下のコードでインスタンスメソッドから引数を取り出せると思って実行したのですがダメでした。  
なぜprint(game.name1)で値を持ってこれないんでしょうか？  
print(game.play_game().p1n)これも試したのですがダメでした。  
何週間もこのコードを理解しようと頑張っているのですが、なかなか掴みきれません。


CC BY-SA 4.0
2018-10-15T09:03:04.270
49295
2018-10-15T12:37:47.530
22565
question
python python3
python インスタンスメソッドの引数について


わからないことを整理して一つ一つ潰していったほうがいいです。  
質問がごちゃごちゃしていると回答もごちゃごちゃします。

> なのに `def __gt__(self, c2):`
> ではインスタンス自身になる引数selfをc1の引数として使っています。この場合、主体となるインスタンスが不明なるのでは（自分で言っておるけど意味はよくわかっていまっせん。識別番号みたいなもの？）と考えて夜も眠れません。
>
> なぜ`def __gt__(self, c1, c2):` のように識別とするselfがいらないのでしょうか？ 特殊メソッドだからでしょうか？

コードをシンプルにしてみました。

[code]

    class Card(object):
        """docstring for Card"""
        def __init__(self, v):
            self.value = v
    
        def __lt__(self, c):
            if self.value < c:
                return True
            else:
                return False
    
        def __gt__(self, c):
            if self.value > c:
                return True
            else:
                return False
    
[/code]

こうなります。

[code]

    card1 = Card(1)
    
    card1.value
    1
    
    card1 > 5
    False
    
    card1.__gt__(5)
    False
    
    card9 = Card(9)
    
    card9.value
    9
    
    card9 > 5
    True
    
    card9.__gt__(5)
    True
    
    card9 > card1
    True
    
[/code]

`card1 > 5` というコードと、`card1.__gt__(5)` は同じことをしていて、`5` は引数 `c` に渡されます。`self` には
Python が内部で自動的に渡します。  
クラス `Card` のインスタンスとして `card1` と `card9` を作成しています。`card1` の `self` には `card1`
の、`card9` の `self` には `card9` のインスタンスオブジェクトが渡されます。

> なぜprint(game.name1)で値を持ってこれないんでしょうか？  
>  print(game.play_game().p1n)これも試したのですがダメでした。

変数 `name1` や `p1n` を `self.name1` や `self.p1n` で定義すればできます。  
self をつけない場合はローカル変数となり、外部からは参照できません。


CC BY-SA 4.0
2018-10-15T12:37:47.530
49307
2018-10-15T12:37:47.530
13227
49295
answer