2015-04-13 5 views
0

я создал класс под названием карты, которая принимает номер и дает следующий результат в зависимости от методов, вызываемых:Наследство и методы перегрузки

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 с классом карты унаследована:

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 

Я пытаюсь перегружать точки() метод путем перезаписи, но я не могу показаться, чтобы осущ ement self.rank из класса Card. Когда я назначаю y = BlackjackCard(38) и выполняю y.points(), он дает мне type error: unorderable types: method() < int().

Что я здесь делаю неправильно?

+0

Совет: повторность проверки должны ключ вам, что есть лучший путь. Как вы могли рассчитать костюм, ранг и точки с помощью математики вместо цепочки операторов if/else? (Как подсказка, попробуйте использовать операторы деления и модуля.) –

+0

Я очень согласен, что код повторяется, но как я могу сделать его проще? Не могли бы вы привести мне пример на одном из них? –

+0

Я вычислил математические соотношения для метода ранжирования и метода. Еще раз спасибо! –

ответ

2

self.rank - это способ. Либо вызовите его, добавив parens (self.rank()), либо преобразуйте его в свойство.

+0

Спасибо! Я не знал, что так тебе надо было называть это –

0

Ответ Игнасио правильный (с использованием 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, разрешить True или False. Поэтому, а не возвращать 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 
+0

ой, спасибо тебе огромное. это помогло много! Но что означает @property? Что оно делает? Не уверен, что мы узнали об этом еще –

+0

Вот что Игнасио рекомендовал. Обычно, когда вы хотите сделать метод, вы делаете что-то вроде 'myhand.rank()'. Однако, если метод не принимает никаких входов (кроме объекта, 'self'), вы можете использовать декоратор' @ property', чтобы изменить его, чтобы вы могли использовать этот синтаксис: 'myhand.rank'. Это похоже на получение атрибута пользователю (например, 'myhand.number'), но в этом случае он доступен только для чтения. Вы также можете сделать «свойство» доступным для записи, но в этом случае вам это не нужно. – TheBlackCat

Смежные вопросы