表示结构的最佳方式,其中子类类似于具有一个obj的超类

2024-03-29 07:03:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我想表示一个类似于无序卡片组的结构(比如说在Python 3.7中),它具有一个属性,即单个卡片可以被认为是大小为1的卡片组

class Deck:
    def __init__(self, cards, owner):
        self.owner = owner
        self.cards = cards


class Card(Deck):
    def __init__(self, number, suit, owner):
        self.number = number
        self.suit = suit
        super().__init__({self}, owner)

    def __eq__(self, other):
        return self.number == other.number and self.suit == other.suit and self.owner == other.owner

    def __hash__(self):
        return hash((self.number, self.suit, self.owner))


card = Card(5, 'clubs', 'me')

(上面返回AttributeError: 'Card' object has no attribute 'owner'

如果我想对我的组进行排序,这将很简单,因为Card.__init__()只需将列表[self]传递给Deck.__init__()。但是,我不能只将{self}传递给Deck.__init__(),因为Card.__hash__()可能要求已经设置了组属性!有很多变通办法;我可以简单地在Card.__init__()中设置self.owner = owner,或者我可以将[self]传递给Deck.__init__(),然后在主体中设置self.cards = set(cards),但我觉得奇怪的是,代码的其他部分应该取决于卡组选择如何存储其卡。因此,我的问题不是如何编码,而是设计这种关系的最佳方式,这样我就不必担心这些问题。有什么想法吗

我搜索了这个问题,没有找到任何东西,但它很简单,所以如果它是重复的,我道歉。谢谢你的阅读

编辑:如果一副卡片对我的结构来说是一个糟糕的类比,那么(希望)更准确的类比应该是一个多项式,它是单项式的总和,但每个单项式也是一个多项式,它本身就是一个项


Tags: selfnumberreturn属性initdefhashcard
2条回答

我将忽略这个设计中令人质疑的地方,而将重点放在所提供代码中的错误上

AttributeError是由{self}引起的:

super().__init__({self}, owner)

这将尝试在完全初始化之前获取self的哈希值

{self}替换为[self],代码就可以正常运行了

我认为这里的问题是,你的想法“一张卡片可以被认为是一副大小为1的牌。”不太连贯,你已经无意中找到了一个很好的具体说明

一副牌与一张牌是一个根本不同的概念,为了让一副牌存在,一张非牌也必须独立存在

您可以通过思考“添加一张卡”的操作来了解这一点—您应该能够在牌组中添加一张卡,这将导致两张牌的牌组。但是你不应该对一张牌这样做,因为其他已经包含该牌的牌组会突然变成混合类型-它会有一些是一张牌,一些是两张牌,这不是牌组工作的方式(并且会破坏迭代,等等)

因此,我认为正确的选择是在需要时简单地支持将牌组分解为更小的牌组-将牌组移出牌组可以建模为“将牌组分为两个牌组,一个是N-1牌组,另一个是1牌组”,但1牌组中仍然需要有一个非牌组的牌组对象,否则会出现问题

相关问题 更多 >