Python-AttributeError:';功能';对象没有属性';排名';

Python-AttributeError:';功能';对象没有属性';排名';,python,attr,Python,Attr,我正在通过自己编写代码和观看来处理不同的项目Euler问题 在处理问题54时,Youtube视频的作者在Python 2.7中定义函数时编写的代码是 def __init__(self, *args): self.cards = sorted(args, key=lambda c: -c.rank) self.duplicates = {} for card in self.cards: if card.rank in self.duplicates:

我正在通过自己编写代码和观看来处理不同的项目Euler问题

在处理问题54时,Youtube视频的作者在Python 2.7中定义函数时编写的代码是

def __init__(self, *args):
    self.cards = sorted(args, key=lambda c: -c.rank)
    self.duplicates = {}
    for card in self.cards:
        if card.rank in self.duplicates:
            continue
        _duplicates = 0
        for card2 in self.cards:
            if card.rank == card2.rank:
                _duplicates += 1
        self.duplicates[card.rank] = _duplicates
这似乎对他很管用。当我在Python 3.0上运行此代码时,我的Pycharm编译器将返回

File "C:/Users/Matthew/PycharmProjects/Project_Euler/Euler54.py", line 51, in __init__
    self.cards = sorted(args, key=lambda c: -c.rank)
  File "C:/Users/Matthew/PycharmProjects/Project_Euler/Euler54.py", line 51, in <lambda>
    self.cards = sorted(args, key=lambda c: -c.rank)
AttributeError: 'function' object has no attribute 'rank'

但这似乎是一个错误的修正。我不知道如何独自解决这个错误。我可以考虑写一个不同的解决方案,因为视频作者展示的策略对初学者不友好。完整的程序粘贴在下面(我不确定是否应该包括这个,因为我没有正式寻找代码审查。我正在尝试让程序运行,以便完成练习)

如果不添加提供的poker.txt文件,程序将不会以粘贴方式运行。请让我知道,如果在SE上为此类属性错误创建帖子是错误的。我不确定是否应该在这个网站上发布Euler项目的代码。

在第195行

cards = [map_card for c in s.split(' ')]

生成一个列表,其中包含对
map\u卡
功能的大量引用。这被错误地写成
map\u-card
,而不是
map\u-card(c)
。应该是

def gen_hands(s):
    cards = [map_card(c) for c in s.split(' ')]
    return PokerHand(*cards[0:5]), PokerHand(*cards[5:])

从错误来看,问题在于:
c.rank
c
显然是一个函数,它应该是某种对象或实例,具有
rank
属性。您是否忘记了一对用来计算函数的
()
。字符串
s
的实际内容除了设置该列表的长度外没有任何影响。您可能需要
地图卡(c)
。是的,谢谢。这确实是个问题。
import time
from collections import namedtuple

start = time.time()

Card = namedtuple('Card', ['rank', 'suit'])

Ace = 14
King = 13
Queen = 12
Jack = 11
Ten = 10


def map_rank(rank_to_map):
    if rank_to_map == 'A':
        return Ace
    if rank_to_map == 'K':
        return King
    if rank_to_map == 'Q':
        return Queen
    if rank_to_map == 'J':
        return Jack
    if rank_to_map == 'T':
        return Ten
    return int(rank_to_map)


def map_suit(suit_to_map):
    if suit_to_map == 'H':
        return 1
    if suit_to_map == 'D':
        return 2
    if suit_to_map == 'C':
        return 3
    # S = Spades
    return 4


def map_card(card_to_map):
    return Card(rank=map_rank(card_to_map[0]), suit=map_suit(card_to_map[1]))


class Hand(object):

    def __init__(self, *args):
        self.cards = sorted(args, key=lambda c: -c.rank)
        self.duplicates = {}
        for card in self.cards:
            if card.rank in self.duplicates:
                continue
            _duplicates = 0
            for card2 in self.cards:
                if card.rank == card2.rank:
                    _duplicates += 1
            self.duplicates[card.rank] = _duplicates

    def __cmp__(self, other):
        for rule in self.rules():
            rule = getattr(self, rule)
            val = rule(other)
            if val:
                return val

    def rules(self):
        return []

    def _straight(self):
        last_card_rank = False
        for card in self.cards:
            if last_card_rank and last_card_rank != card.rank + 1:
                return False
            last_card_rank = card.rank
        return True

    def _flush(self):
        last_card_suit = False
        for card in self.cards:
            if last_card_suit and last_card_suit != card.suit:
                return False
            last_card_suit = card.suit
        return True

    def _duplicate_count(self, c):
        for rank, value in self.duplicates.items():
            if value == c:
                yield rank


class PokerHand(Hand):
    def rules(self):
        rules = super(PokerHand, self).rules()
        rules.append('royal_flush')
        rules.append('straight_flush')
        rules.append('four_of_a_kind')
        rules.append('full_house')
        rules.append('flush')
        rules.append('straight')
        rules.append('three_of_a_kind')
        rules.append('two_pair')
        rules.append('highest_card')
        return rules

    def royal_flush(self, other):
        h1 = self.cards[0].rank == Ace and self._flush() and self._straight()
        h2 = other.cards[0].rank == Ace and other._flush() and other._straight()
        if h1 and not h2:
            return 1
        if h2 and not h1:
            return -1
        if h1 and h2:
            return 0

    def straight_flush(self, other):
        h1 = self._flush() and self._straight()
        h2 = other._flush() and other._straight()
        if h1 and not h2:
            return 1
        if h2 and not h1:
            return -1
        if h1 and h2:
            return self.highest_card(other)

    def four_of_a_kind(self, other):
        return self._of_a_kind(other, 4)

    def three_of_a_kind(self, other):
        return self._of_a_kind(other, 3)

    def _of_a_kind(self, other, value):
        h1 = [r for r in self._duplicate_count(value)]
        h2 = [r for r in other._duplicate_count(value)]
        if len(h1) > len(h2):
            return 1
        if len(h2) > len(h1):
            return -1
        for h1_c, h2_c in zip(h1, h2):
            if h1_c > h2_c:
                return 1
            if h2_c > h1_c:
                return -1

    def two_pair(self, other):
        return self._of_a_kind(other, 2)

    def full_house(self, other):
        h1_3 = [r for r in self._duplicate_count(3)]
        h2_3 = [r for r in other._duplicate_count(3)]
        h1_2 = [r for r in self._duplicate_count(2)]
        h2_2 = [r for r in other._duplicate_count(2)]
        if h1_3 and h1_2 and not (h2_3 and h2_2):
            return 1
        if h2_3 and h2_2 and not (h1_3 and h1_2):
            return -1
        if h1_3 and h1_2 and h2_3 and h2_2:
            for h1_c, h2_c in zip(h1_3, h2_3):
                if h1_c > h2_c:
                    return 1
                if h2_c > h1_c:
                    return -1
            for h1_c, h2_c in zip(h1_2, h2_2):
                if h1_c > h2_c:
                    return 1
                if h2_c > h1_c:
                    return -1

    def flush(self, other):
        h1 = self._flush
        h2 = other._flush
        if h1 and not h2:
            return 1
        if h2 and not h1:
            return -1
        if h1 and h2:
            return self.highest_card(other)

    def straight(self, other):
        h1 = self._straight
        h2 = other._straight
        if h1 and not h2:
            return 1
        if h2 and not h1:
            return -1
        if h1 and h2:
            return self.highest_card(other)

    def highest_card(self, other):
        for c1,c2 in zip(self.cards, other.cards):
            if c1.rank != c2.rank:
                return 1 if c1.rank > c2.rank else -1
        raise Exception("tie in highest_card")


def gen_hands(s):
    cards = [map_card for c in s.split(' ')]
    return PokerHand(*cards[0:5]), PokerHand(*cards[5:])

p1_wins = 0
with open('poker.txt') as f:
    for line in f:
        h1, h2 = gen_hands(line.strip())
        if h1 > h2:
            p1_wins += 1
print(p1_wins)
cards = [map_card for c in s.split(' ')]
def gen_hands(s):
        cards = [map_card for c in s.split(' ')]
        return PokerHand(*cards[0:5]), PokerHand(*cards[5:])
def gen_hands(s):
    cards = [map_card(c) for c in s.split(' ')]
    return PokerHand(*cards[0:5]), PokerHand(*cards[5:])