我怎样才能使这个代码Python

2024-10-04 05:32:00 发布

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

所以我有一个对象的代码。这个物体是你可以在石头剪纸游戏中做的动作。 现在,这个对象需要是一个整数(用于匹配协议)和一个字符串,以便编写和查看。在

class Move:
    def __init__(self, setMove):
        self.numToName = {0:"rock", 1:"paper",2:"scissors"} 
        self.nameToNum = dict(reversed(pairing) for pairing in self.numToName.items())
        if setMove in self.numToName.keys():
            self.mMove=setMove
        else:
            self.mMove=self.nameToNum.get(setMove) #make it to a number

    def defeats(self):
        return Move((self.mMove-1)%3)
    def losesTo(self):
        return Move((self.mMove+1)%3)
    def tiesWith(self):
        return self

    #Operator overloading
    def __eq__(A,B):
        return A.mMove==B.mMove
    def __gt__(A,B):
        return A.defeats(B)
    def __lt__(A,B):
        return A.losesTo(B)
    def __ge__(A,B):
        return A>B or A==B
    def __le__(A,B):
        return A<B or A==B

    def __str__(self):
        return self.numToName.get(self.mMove);

    def __int__(self):
        return self.mMove;

现在我对python有点陌生,有C和Java背景。 python中的一个重要问题是,只有一种正确的方法来做某件事。 另一件事不是担心类型。 我很明显地担心这里的类型。在

所以我不确定处理这些对象的正确方法是什么。 目前,我有一个对象,可以是任何三种类型之一(或更多,但我不确定这将做什么) 也许我应该用不同类的对象?让他们成为单身汉? 另外,我的对象目前是可修改的创建后,这是一件坏事在我的脑海。在

那么这个代码是Python式的,我怎样才能使它更优雅呢? (我想这是一个很好的例子,可以帮助我找出什么是好的python代码。抱歉,如果它看起来有点开放)


Tags: 对象代码inself类型getmovereturn
3条回答

下面是一个简短的版本,它描述了结果。在

def winner(p1, p2):
    actors = ['Paper', 'Scissors', 'Rock']
    verbs = {'RoSc':'breaks', 'ScPa':'cut', 'PaRo':'covers'}
    p1, p2 = actors.index(p1), actors.index(p2)
    winner, looser = ((p1, p2), (p2, p1))[(1,0,1)[p1 - p2]]
    return ' '.join([actors[winner],
                     verbs.get(actors[winner][0:2] + actors[looser][0:2],
                               'ties'),
                     actors[looser]])

这种结构的好处是显而易见的,当扩大到涵盖岩石,纸张,剪刀,蜥蜴,斯波克

^{pr2}$

你只有三个可能的动作,对吧?为什么不把它们表示为字符串呢?似乎你拥有这些数字的唯一原因是为了用一些“聪明”的数学来进行比较(即谁比谁强),但老实说,我认为这不值得。您真正需要的是一个函数来确定在每个可能的比较中哪一个是赢家:

def winner(move0, move1):
    if move0 == move1:
        return None
    elif (move0 == 'rock' and move1 == 'scissors') or \
         (...paper vs. rock...) or \
         (...scissors vs. paper...):
        return 0
    else:
        return 1

我刚刚构造了返回值None0、和{}作为示例,您可以使用适合您的情况的任何值。在

“简单比复杂好,”Python第3行的禅;-)

一旦你把代码写下来就是为了理解这个问题。在这种情况下,不必担心对玩家、游戏、掷球等进行更深层次的抽象,你会遇到以下问题:有一定数量的招式,每种招式都有一个名称,都有固定的规则,哪些招式胜过哪些其他招式,你需要找到一种方法来定义招式,并在比较中找出哪一种招式获胜。在

当我读到你的代码时,我并没有立即看到这个问题,我看到很多额外的想法进入了代码本身,找到类型表示,做算术技巧,通常将问题强制到代码框架中,而不是相反。所以我建议如下:


class Move:
  TYPES = ['rock', 'paper', 'scissors']
  BEATS = {
    'rock': ['scissors'],
    'paper': ['rock'],
    'scissors': ['paper']
  }

  def __init__(self, type):
    if type not in self.TYPES:
      raise Exception("Invalid move type")
    self.type = type

  def __str__(self):
    return self.type

  def __cmp__(self, other):
    if other.type in self.BEATS[self.type]:
      return 1
    elif self.type in self.BEATS[other.type]:
      return -1
    else:
      return 0

你就完蛋了。你可以加入所有其他的访问器,等等,但这只是糖衣,核心问题得到解决,代码可读性强,灵活,易于扩展等等。这就是我认为的“pythonic”的意思。在

相关问题 更多 >