Python中的点表示法。方法应该在对象之前还是之后?

Python中的点表示法。方法应该在对象之前还是之后?,python,methods,notation,Python,Methods,Notation,我正在学习Python,我正在尝试模拟纸牌游戏。 我有一个关于点符号的问题。我在互联网上到处寻找一个具体的答案,但没有找到 为什么有时我们被教导用点符号调用方法,如下所示: object.methodName() className.methodName(object) 其他时候我们会这样称呼它: object.methodName() className.methodName(object) 有什么区别 这里有一个具体的例子。这是书中的方法定义(如何像计算机科学家一样思考) 有时,对象

我正在学习Python,我正在尝试模拟纸牌游戏。 我有一个关于点符号的问题。我在互联网上到处寻找一个具体的答案,但没有找到

为什么有时我们被教导用点符号调用方法,如下所示:

object.methodName()
className.methodName(object)
其他时候我们会这样称呼它:

object.methodName()
className.methodName(object)
有什么区别

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

有时,对象位于方法之前:

self.isEmpty()
有时对象位于方法之后,在括号中:

Deck.__str__(self)
我们使用哪种方法?这有关系吗

有时对象位于方法之后,在括号中:

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

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

a = Hand()
b = Hand()
然后

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

要访问这些数据,对象本身必须放入每个方法中。 这是通过以下方式实现的:

def foo(self):
    return self.cards
当您定义方法时

除非你没有写一个特殊的类方法,否则你总是要把自己放在那里

调用
object.methodName()
时,该方法会自动获取它所属对象的信息(因为您将对象/实例引用在点之前移交。该信息存储在参数
self
中。因此,该方法可以执行以下操作:
返回self.cards

但是如果你像
Deck.\uuu str\uuu(self)
那样调用它,那么你只有类,这意味着没有
self
(对象引用本身)

因此,该方法不知道它属于哪个实例数据,因此您必须交出
self

综上所述,如果你打电话:
object.\uuu str\uuu()
由于使用对象引用调用该方法,因此给出了有关实例的信息


但是如果您使用
Deck
resp.the
className
,那么您还必须通过
className.method(self)
来放置有关实例的信息,因为否则对象实例就没有对象引用。

通常,对象首先出现

像这样:

object.methodName()

或者像这样:

object.methodName()
className.methodName(object)
self.isEmpty()

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

object.methodName()
className.methodName(object)
Deck.\uuuuu str\uuuuuuuuuu(self)

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

object.methodName()
className.methodName(object)
self.Deck.\u str\u()

原因是上面的代码会抛出一个错误:

“手动实例没有属性组

上面的错误是由于这样写的,Python认为“Deck”是self的属性。但在本例中,它不是。Deck是Hand类型的父类型,它不是self的属性

这是一个代码块,您可以在其中看到有问题的代码,以及父类型(Deck)和我正在处理的子类型(Hand)。在这段代码中,我们正在编写一个方法,通过访问Deck中的字符串格式来覆盖Hand的字符串格式。代码片段
Deck.\uu str\uuuuuuuuuuuuuuself)
是这样写的,因为我们需要一种方法来告诉Python我们希望它从哪个类型的对象复制字符串格式。在本例中,我们希望从父对象Deck获得字符串格式

班长(甲板):
def uuu init uuuu(self,name=”“):
self.cards=[]
self.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()。\uu str\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
我们还没有学习Super,但是您可以在这里了解更多内容()。Super基本上告诉Python为您找到父格式,并使用它。更简单


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

Deck
是一个类,而
Deck.\uu str\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu(导致无限递归错误),您需要父类,因此显式调用它。但是,不建议这样调用该类。请改用
super()。\uuu str\uuu()
(并让
super()
了解父类是什么以及如何找到
Deck.\uu str\uu
正确地调用
self
)。您重写了
Hand
子类中的
\uuuu str\uuuu
方法,因此调用
\uu str\uuuu
的父版本时需要这样做。如前所述,您应该执行
super()
相反,它处理的是更复杂的继承结构。@Martijn Pieters@tdelaney谢谢!我想我明白了。是的,“Deck”是“Hand”的父类。我们还没有学习过“super()”。我在[link](docs.python.org)上查找过它。是的,在哪里可以看到“Deck.”,我们正在尝试访问父类“Deck”的字符串格式。因此,现在我明白了为什么这样编写,并且我现在明白了建议我们使用“super()”。在这种情况下,使用super()的适当语法是:'super()。\uu str__;(self)'@M.Copeland:不,它是
super()。\uu str\uuu()
。这将把下一个父类中的正确方法(按方法解析顺序)绑定到
self