Python:self.foo=foo必须始终跟在uuu init(self,foo)后面吗?
我已经花了三天的时间努力学习Python:self.foo=foo必须始终跟在uuu init(self,foo)后面吗?,python,init,self,Python,Init,Self,我已经花了三天的时间努力学习\uuuu init\uuuu和“self”,从“艰难学习Python”练习42开始,接着阅读Python文档的部分内容,坦白地说,我准备用砖头砸自己的脸,直到昏倒 话虽如此,我注意到在初始的\uuuuu init\uuuuuu定义中有一个非常常见的约定,即使用(self,foo)进行后续操作,然后在该定义中立即声明self.foo=foo 从LPTHW,ex42: class Game(object): def __init__(self, start):
\uuuu init\uuuu
和“self”,从“艰难学习Python”练习42开始,接着阅读Python文档的部分内容,坦白地说,我准备用砖头砸自己的脸,直到昏倒
话虽如此,我注意到在初始的\uuuuu init\uuuuuu
定义中有一个非常常见的约定,即使用(self,foo)进行后续操作,然后在该定义中立即声明self.foo=foo
从LPTHW,ex42:
class Game(object):
def __init__(self, start):
self.quips = ["a list", "of phrases", "here"]
self.start = start
艾伦·高尔德:
def __init__(self,val): self.val = val
我在一个可怕的空间里,我可以看到只有一件事我没有得到,我知道,无论我读了多少关于它的书,并试图弄明白它,它仍然是不透明的。也许如果有人能向我解释这一点一致性,灯就会亮起来。这是因为我们需要说变量“foo”总是等于(foo)参数,它本身包含在“self”参数中,该参数自动分配给它所附加的def 您可能想进一步研究面向对象编程 粗略地说,当你说
class Game(object):
def __init__(self, start):
self.start = start
你是说:
- 我有一种叫做
Game
- 无论何时创建新的
,它都会要求我提供一些额外的信息,游戏
。(这是因为开始
的初始值设定项名为游戏
,要求提供此信息。)\uuuu init\uuuu
- 初始值设定项(也称为“构造函数”,尽管这有点用词不当)需要知道它正在初始化哪个对象(刚才创建的)。这是第一个参数——按照惯例,它通常被称为
(但您可以调用其他任何参数…)self
- 游戏可能需要记住我给它的
开始是什么。因此,它通过创建名为
的实例变量将此信息存储在自身内部(没有什么特别的,它只是您想要的任何名称),并将start
参数的值分配给start
变量start
- 如果它不存储参数的值,它就不会有该信息供以后使用
希望这能解释发生了什么。参数名称应该是有意义的,以传达它们在函数/方法中所起的作用或有关其内容的一些信息 您可以看到构造函数的参数更加重要,因为它们通常是新实例工作所必需的,并且包含类的其他方法中所需的信息 假设您有一个
游戏
类,它接受玩家列表
class Game:
def __init__(self, playerList):
self.playerList = playerList # or self.players = playerList
def printPlayerList(self):
print self.playerList # or print self.players
该类的各种方法都需要此列表。因此,将其分配给self.playerList
是有意义的。您还可以将其分配给self.players
,任何您觉得更舒服且可以理解的内容。但是如果您不将其分配给self.
它将无法通过其他方法访问
因此,如何命名参数/attributes/etc()并没有什么特别之处,但使用有意义的名称会使代码更容易理解。或者,如果您有以下情况,您是否理解上述课程的含义:
class G:
def __init__(self, x):
self.y = x
def ppl(self):
print self.y
?:)它的功能完全相同,但更难理解…我不太确定您遗漏了什么,所以让我来谈谈一些基本项目 Python
类
对象中有两个“特殊”初始化名称,一个是用户比较少担心的名称,称为\uuuuuu new\uuuuuu
,另一个是更常见的名称,称为\uuuu init\uuuuuu
当您调用类对象构造函数时,例如(根据您的示例)x=Game(args)
,首先调用Game.\uuuu new\uuuu
以获取保存对象的内存,然后调用Game.\uu init\uuu
以填充该内存。大多数情况下,您可以允许底层的对象。\uuu new\uuu
分配内存,您只需填充内存即可。(你可以使用自己的分配器来处理一些特殊的、奇怪的、罕见的情况,比如像普通整数那样永远不会改变并且可能共享身份的对象。也可以使用“元类”来处理一些奇怪的事情。但这都是以后要讨论的话题。)
您的游戏。调用\uuuu init\uuuuu
函数时,将使用“构造函数的所有参数”加上一个隐藏在前面的参数,该参数是为该对象本身分配的内存。(对于基本上是“属性”字典的“普通”对象,加上类的魔力胶水,但是对于带有\uuuu插槽\uuuuuu
的对象,属性字典被省略。)命名第一个参数self
只是一个惯例,但并不违反它,如果你这么做,人们会讨厌你。:-)
没有任何东西需要您将所有参数保存到构造函数。您可以设置任意或所有喜欢的实例属性:
class Weird(object):
def __init__(self, required_arg1, required_arg2, optional_arg3 = 'spam'):
self.irrelevant = False
def __str__(self):
...
问题是,一个奇怪的()实例在初始化之后是非常无用的,因为您需要传递两个参数,这两个参数被简单地丢弃,并且给出了第三个可选参数,这两个参数也被丢弃:
x = Weird(42, 0.0, 'maybe')
需要这些被丢弃的参数的唯一一点是为了将来的扩展,事实上(在早期开发期间,您可能有这些未使用的字段)。因此,如果您没有立即使用和/或将参数保存到\uuuu init\uuuu
,那么中肯定有奇怪的东西
顺便说一句,在类定义中使用(object)
的唯一原因是向Python2.x表明这是一个“新样式”类(区别于非常旧的Python“仅实例”类)。但通常最好使用它,因为它使我上面所说的关于对象的内容成为事实