iT邦幫忙

0

python 撲克牌程式導讀問題(python100day)[已解決]

各位前輩最近在學習python 100day的內容,在學習到物件導向的內容時卡關了。
我的問題主要是在main function裡面的
player.arrange(get_key)我不太理解get_key明明是一個一般函式為什麼可以直接當arrange的參數使用,get_key在程式裡也沒找到其他地方有帶入參數呼叫和所以我很困惑。
還有就是arrage.sort的排序問題
問題主要在arrange的排序和 get_key 我有在註釋打些疑問麻煩各位大大解惑解惑了。

import random


class Card(object):
    """一张牌"""

    def __init__(self, suite, face):
        self._suite = suite
        self._face = face

    @property
    def face(self):
        return self._face

    @property
    def suite(self):
        return self._suite

    def __str__(self):
        if self._face == 1:
            face_str = 'A'
        elif self._face == 11:
            face_str = 'J'
        elif self._face == 12:
            face_str = 'Q'
        elif self._face == 13:
            face_str = 'K'
        else:
            face_str = str(self._face)
        return '%s%s' % (self._suite, face_str)
    
    def __repr__(self):
        return self.__str__()


class Poker(object):
    """一副牌"""

    def __init__(self):
        self._cards = [Card(suite, face) 
                       for suite in '♠♥♣♦'
                       for face in range(1, 14)]
        self._current = 0

    @property
    def cards(self):
        return self._cards

    def shuffle(self):
        """洗牌(随机乱序)"""
        self._current = 0
        random.shuffle(self._cards)

    @property
    def next(self):
        """发牌"""
        card = self._cards[self._current]
        self._current += 1
        return card

    @property
    def has_next(self):
        """还有没有牌"""
        return self._current < len(self._cards)


class Player(object):
    """玩家"""

    def __init__(self, name):
        self._name = name
        self._cards_on_hand = []

    @property
    def name(self):
        return self._name

    @property
    def cards_on_hand(self):
        return self._cards_on_hand

    def get(self, card):
        """摸牌"""
        self._cards_on_hand.append(card)

    def arrange(self, card_key):
        """玩家整理手上的牌"""
        #這裡的排序原理是什麼?key為什麼要是card_key
        #card_key裡面不是由花色和數字組成嗎
        #那這樣cards_on_hand.sort不就可以對字串做排序了
        
        self._cards_on_hand.sort(key=card_key)

#********************這部分除了arrage有呼叫到以外但呼叫了不用帶入參數呼叫嗎?
# 排序规则-先根据花色再根据点数排序
def get_key(card):
    return (card.suite, card.face)


def main():
    p = Poker()
    p.shuffle()
    players = [Player('东邪'), Player('西毒'), Player('南帝'), Player('北丐')]
    for _ in range(13):
        for player in players:
            player.get(p.next)
    for player in players:
        print(player.name + ':', end=' ')
        #***我困惑的地方
        player.arrange(get_key)
        print(player.cards_on_hand)


if __name__ == '__main__':
    main()

https://github.com/jackfrued/Python-100-Days/blob/master/Day01-15/09.%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E8%BF%9B%E9%98%B6.md

一級函式語言本來就可以把函式當參數傳來傳去的

1 個回答

2
froce
iT邦大師 1 級 ‧ 2021-04-27 13:39:01
最佳解答

跟你說過了啊,遇到code就要一步一步去推導。
這個其實你知道 self._cards_on_hand 這函數的型態,你就得到答案了。
這個我就不帶你推導了。你自己試試。

https://docs.python.org/zh-tw/3/howto/sorting.html#key-functions

下面是提示和一些衍伸的問題:

  1. 在python函數是頭等公民,可以被當參數傳,而且很多時候會需要
  2. 考慮下面的code,請問兩個各叫什麼
def abc(d=""):
    return "abc"+d

print(type(abc))
print(type(abc()))
  1. 為啥會需要這樣傳?比如爬蟲,我今天爬到後原始資料有20000筆,欄位20個,我不希望用資料庫,但我原始資料和過濾後的資料都要,而且過濾的條件都不同,那我是不是需要一個靈活的方法去過濾資料?
    通常這種方式叫 callback。
  2. 最後如果你常寫django、flask你會遇到一種東西叫裝飾子,他背後怎麼做的?
看更多先前的回應...收起先前的回應...

跟高階函數有關嗎?@@

我現在知道函數可以當作參數去做傳遞了但get_key那邊還是想不太明白
為什麼get_key(card)的card是Card物件,froce大可以給點提示嗎感謝。

froce iT邦大師 1 級 ‧ 2021-04-29 08:33:27 檢舉

動態語言你倒什麼給他,他就吃什麼,如果他不能消化就吐error。

def get_key(card):
    return (card.suite, card.face)

l1 = [1, "2"]
l2 = [Card("♠", 1), Card("♠", 2)]

l1.sort(key=get_key)
l2.sort(key=get_key)

你覺得最後兩句會出現什麼結果?
get_key裡並沒有強制限定你參數類型,那個card只是在提示你(撰寫程式者)他吃Card,你list裡要放什麼東西,你要餵它什麼,他管不到,頂多是他消化不良吐error而已。

如果你之前學過靜態語言,應該會很不習慣,所以python目前加入了type hint,不強制限定函式吃什麼,但明白提示撰寫者參數類型,並由IDE提供錯誤檢查和自動提示。

我要發表回答

立即登入回答