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