Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to override class attribute two levels deep?

Tags:

Overriding and inheritance is seeming to work differently than I expect, let me explain this situation. I have three classes: Card, Treasure, and Copper. Copper inherits from Treasure and Treasure inherits from Card. The only difference between Treasure and Card is a single method that Treasure overrides. The only difference between Treasure and Copper is an attribute that Copper overrides. The attribute that Copper overrides is originally from Card and it is an attribute that Treasure uses in its unique method. The issue that I'm running into is that when Copper's method is being called that it inherits from Treasure, it is still using Card's attribute value, not the attribute value that Copper should be overriding it with. Below is some code, any help is appreciated.

Card Class:

class Card:
    normal_full_table = 6
    pile_player_rate = 10

    @staticmethod
    def pile_setup(player_count):
        pass

Treasure Class:

from card.card import Card
from math import floor

class Treasure(Card):
    @staticmethod
    def pile_setup(player_count):
        return (floor(player_count/Card.normal_full_table) + 1) * Card.pile_player_rate

Copper Class:

from card.basic.card_treasure import Treasure


class Copper(Treasure):
    pile_player_rate = 60

What I would expect to happen is when Copper.pile_setup(6) is called that the value pile_player_rate to be 60 since Copper is overriding that value but upon inspection it is still 10. Why is this? Is this because I'm saying specifically Card.pile_player_rate? How can I get Copper to use it unique value for pile_player_rate rather than the generic one in Card? Thanks.

like image 435
neogeek23 Avatar asked Jan 10 '18 13:01

neogeek23


1 Answers

A sounder way to implement this would be a classmethod. That allows you to dynamically access the attributes of the class that the method is called on:

class Treasure(Card):
    @classmethod
    def pile_setup(cls, player_count):
        return (floor(player_count/cls.normal_full_table) + 1) * cls.pile_player_rate

You could implement this method on Card, and without overriding it, it would access the attributes of Treasure when called on Treasure.

like image 130
user2390182 Avatar answered Sep 20 '22 12:09

user2390182