【问题标题】:Dot notation in Python. Should method come before or after the object?Python中的点表示法。方法应该在对象之前还是之后?
【发布时间】:2017-01-28 23:14:29
【问题描述】:

我正在学习 Python,并且正在尝试模拟纸牌游戏。 我有一个关于点符号的问题。我在整个互联网上寻找特定的答案,但找不到。

为什么,有时我们被教导要像这样以点表示法调用方法:

object.methodName()

而其他时候我们会这样称呼它:

className.methodName(object)

有什么区别?

这是一个具体的例子。这是书中的方法定义(如何像计算机科学家一样思考)

class Hand(Deck):
    def __init__ (self, name = " "):
        self.cards = []
        self.name = name

    def __str__(self):
        s = "Hand "+ self.name
        if self.isEmpty():
            return s+" is empty\n"
        else:
            return s+ " contains\n" + Deck.__str__(self)

有时对象在方法之前:

self.isEmpty()

有时对象出现在方法之后,括号中:

Deck.__str__(self)

我们使用哪种方法?有关系吗?

【问题讨论】:

  • Deck 是一个Deck.__str__ 是一个未绑定的方法。如果您尝试self.__str__() 而不是再次调用Hand.__str__() 方法(导致无限递归错误),您需要父类,因此它被显式调用。
  • 但是,不推荐这样调用类。改用super().__str__()(让super()弄清楚父类是什么以及如何正确找到Deck.__str__self)。
  • 您覆盖了Hand 子类中的__str__ 方法,因此需要调用__str__ 的父版本。如前所述,您应该改用super().__str__(),因为它处理更复杂的继承结构。
  • @Martijn Pieters @tdelaney 谢谢!我觉得我懂了。是的,“Deck”是“Hand”的父类。我们还没有被告知“super()”。我在 [link](docs.python.org) 上查找了它。是的,在您看到“Deck.__str__(self)”的地方,我们正在尝试访问父类“Deck”的字符串格式。所以现在我明白了为什么它是这样写的,我现在明白建议我们为此目的使用“super()”。在这种情况下使用 super() 的适当语法是:'super().__str__(self)' ?
  • @M.Copeland:不,是super().__str__()。这会将您的下一个父类中的正确方法(按方法解析顺序)绑定到self,因此您无需手动传入self。添加评论时,有一个帮助链接,您可以检查格式信息;代码用`反引号标记。

标签: python methods notation


【解决方案1】:

有时对象出现在方法之后,在括号中:

Deck.__str__(self)

不,对象总是在它自己的方法之前。此行中有两个 python“对象”。您将self 对象(实际上是一个类实例)作为参数传递给Deck 对象(实际上是一个类)的__str__ 方法。

【讨论】:

    【解决方案2】:

    你用的文:

     object.methodName()
    

    然后你用它自己的数据调用一个特殊实例的方法。 由于该方法与给定实例相关,因此您会得到不同的结果。

    a = Hand()
    b = Hand()
    

    然后

    a.cards
    b.cards
    

    可能不同(在大多数情况下)。

    要访问这些数据,对象自身必须放入每个方法中。 这是由以下人员完成的:

    def foo(self):
        return self.cards
    

    当你定义方法时。

    除非您不编写特殊的类方法,否则您总是必须将 self 放在那里。

    调用object.methodName()时,该方法会自动获取其所属对象的信息(因为您将对象/实例引用交到点之前。此信息存储在参数self中。因此该方法可以用于例如:return self.cards

    但是,如果您将其称为Deck.__str__(self),那么您只有类,这意味着没有self(这是对象引用本身)。

    所以该方法不知道它属于哪个实例数据,所以你必须交出self

    总结一下,如果您调用: object.__str__()给出实例信息是因为你使用了对象引用来调用方法。

    但是如果你使用Deck resp。 className 比您还必须通过 className.method(self) 输入有关实例的信息,否则没有对象实例的对象引用。

    【讨论】:

      【解决方案3】:

      一般来说,对象是第一位的。

      像这样:

      object.methodName()

      或者像这样:

      self.isEmpty()

      但我想知道为什么我的 Python 书教我这样调用这个方法:

      Deck.__str__(self)

      我想知道为什么“self”在括号中,而不是在方法的开头。换句话说,为什么不这样写:

      self.Deck._str_()

      原因,就是上面的代码会报错:

      "Hand instance has no attribute Deck

      上面的错误是因为这样写的,Python认为“Deck”是self的一个属性。但在这种情况下,它不是。 Deck,是Hand类型的PARENT类型,不是self的属性。

      这是代码块,您可以在其中查看相关代码,以及我正在使用的父类型(Deck)和子类型(Hand)。在这段代码中,我们正在编写一个方法来覆盖 Hand 的字符串格式,方法是访问 Deck 中的字符串格式。代码 sn -p Deck.__str__(self) 之所以这样写,是因为我们需要一种方法来告诉 Python 我们希望它从哪个类型对象中复制字符串格式。在这种情况下,我们需要来自父级 Deck 的字符串格式。

      class Hand(Deck): def __init__ (self, name = " "): self.cards = [] self.name = name

      def __str__(self):
          s = "Hand "+ self.name
          if self.isEmpty():
              return s+" is empty\n"
          else:
              return s+ " contains\n" + Deck.__str__(self)
      

      另外,正如@Martijn Pieters 所说,使用 SUPER:super().__str__() 比我这样做更好:Deck.__str__(self) 我们还没有学习 Super,但你可以在这里了解更多信息(https://docs.python.org/2/library/functions.html#super)。 Super 基本上告诉 Python 为你找到父格式,并使用它。容易多了!

      我希望这个解释是可以理解的。我试图过度解释以弥补任何不清楚的地方:-/

      【讨论】:

        猜你喜欢
        • 2012-11-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-22
        • 2011-07-04
        • 1970-01-01
        • 2014-06-24
        • 1970-01-01
        相关资源
        最近更新 更多