Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:self.foo=foo必须始终跟在uuu init(self,foo)后面吗?_Python_Init_Self - Fatal编程技术网

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“仅实例”类)。但通常最好使用它,因为它使我上面所说的关于
对象的内容成为事实