继承和重载方法

时间:2015-04-13 23:47:04

标签: python inheritance overloading

我创建了一个名为Card的类,它接受一个数字并根据所谓的方法提供以下输出:

class Card:

def __init__(self, number):
    self.number = number

def suit(self):
    if self.number in range(0, 13):
        return 0
    elif self.number in range(13, 26):
        return 1
    elif self.number in range(26, 39):
        return 2
    elif self.number in range(39, 52):
        return 3

def rank(self):
    if self.number in range(0, 13):
        return self.number
    elif self.number in range(13, 26):
        return self.number - 13
    elif self.number in range(26, 39):
        return self.number - 26
    elif self.number in range(39, 52):
        return self.number - 39

def points(self):
    if self.number in (12,25,38,51):
        return 4
    elif self.number in (11,24,37,50):
        return 3
    elif self.number in (10,23,36,49):
        return 2
    elif self.number in (9,22,35,48):
        return 1
    else:
        return 0
def __repr__(self):
    ranks = ['2','3','4','5','6','7','8','9','10','J','Q','K','A']

    if self.number in range(0, 13):
        return ranks[self.number] + '\u2663'

    elif self.number in range(13, 26):
        return ranks[self.number - 13] + '\u2666'

    elif self.number in range(26, 39):
        return ranks[self.number - 26] + '\u2665'

    elif self.number in range(39, 52):
        return ranks[self.number - 39] + '\u2660'

def __lt__(self,other):
    if str(self.rank) < str(other.rank):
        return True
    else:
        return False

*有关使代码更好的任何提示均值得赞赏

现在我必须写一个名为BlackjackCard的类,继承了Card类:

class BlackjackCard(Card):

def __init__(self, number):
    Card.__init__(self, number)

def points(self):

    if self.rank == 12:
        return 11
    elif self.rank in (11,10,9):
        return 10
    elif self.rank < 11:
        return self.rank

我试图通过重写来重载方法点(),但我似乎无法从类Card实现self.rank。 当我分配y = BlackjackCard(38)并执行y.points()时,它会给我一个type error: unorderable types: method() < int()

我在这里做错了什么?

2 个答案:

答案 0 :(得分:2)

self.rank是一种方法。可以通过添加parens(self.rank())来调用它,也可以将其转换为属性。

答案 1 :(得分:0)

Ignacio的答案是正确的(使用property),但就改进代码而言,提出了一些建议。

首先,您可以if foo in range(a, b):代替if a <= foo < b:,但在您的情况下,您可以使用数学进一步简化此操作。该诉讼仅为floor(number/13),或更简单number//13。同样,排名是number/13的余数,模数为13,即number%13

其次,不是每次都重新计算所有内容,而是可以在另一个方法中重复使用一种方法的结果。例如,您在__repr__中重新计算套装。

最后,python中的布尔测试,如x < y,解析为TrueFalse。因此,如果测试通过,则返回True而不是False,如果不是,则可以完全返回测试结果。

此外,我不认为您想要在str中返回排名的__lt__,而是返回数字排名。

所以这是我的改进版本:

class Card:
    def __init__(self, number):
        self.number = number

    @property
    def suit(self):
        return self.number // 13

    @property
    def rank(self):
        return self.number % 13

    @property
    def points(self):
        return max(0, self.rank-8)

    @property
    def suit_str(self):
        suits = ['\u2663', '\u2666', '\u2665', '\u2660']
        return suites[self.suit]

    @property
    def rank_str(self):
        ranks = {9: 'J', 10: 'Q', 11: 'K', 12: 'A'}
        return ranks.get(self.rank, str(self.rank+2))

    def __repr__(self):
        return self.rank_str+self.suit_str

    def __lt__(self, other):
        return self.rank < other.rank