向初学者解释python“self”variables

我几乎不知道OOP的术语和概念。 我从概念上了解对象是什么,对象是否有方法。 我甚至明白,在Python中,类是对象! 这很酷,我只是不知道这意味着什么。 这是不是跟我一起点击。

我目前正试图了解一些详细的答案,我认为这将说明我对Python的理解:

  1. Python中的“yield”关键字是做什么的?
  2. 什么是Python中的元类?

在第一个答案中,作者使用下面的代码作为例子:

>>> class Bank(): # let's create a bank, building ATMs ... crisis = False ... def create_atm(self) : ... while not self.crisis : ... yield "$100" 

我不立即苟且self所指的。 这绝对是不了解课堂的一个症状,我会在某个时候着手。 澄清,在

 >>> def func(): ... for i in range(3): ... print i 

我明白, i指向列表range(3)中的一个项目,因为它在一个函数中,不是全局的。 但是, self “指向”是什么?

我会先尝试为你清除一些关于类和对象的混淆。 让我们看看这段代码:

 >>> class Bank(): # let's create a bank, building ATMs ... crisis = False ... def create_atm(self) : ... while not self.crisis : ... yield "$100" 

这个评论有点欺骗性。 上面的代码不会“创build”银行。 它定义了银行是什么。 银行是有一个叫crisis的财产,和一个函数create_atm 。 这就是上面的代码所说的。

现在我们来创build一个银行:

 >>> x = Bank() 

在那里, x现在是一家银行。 x有一个财产crisis和一个函数create_atm 。 调用x.create_atm(); 在Python中与调用Bank.create_atm(x); ,所以现在的self指的是x 。 如果你添加一个名为y银行,调用y.create_atm()就会知道y的危机值,而不是x ,因为在这个函数中, self指的是y

self只是一个命名规则,但坚持下去是非常好的。 还是值得指出的是,上面的代码相当于:

 >>> class Bank(): # let's create a bank, building ATMs ... crisis = False ... def create_atm(thisbank) : ... while not thisbank.crisis : ... yield "$100" 

它可以帮助您将obj.method(arg1, arg2)调用语法看作纯调用method(obj, arg1, arg2)语法糖(除了该method是通过objtypes查找的,而不是全局的)。

如果以这种方式查看,则obj是该函数的第一个参数,传统上该参数在参数列表中被命名为self 。 (实际上,你可以将其命名为别的,而且你的代码可以正常工作,但是其他的Python代码会对你不满。)

self ”是实例对象被调用时自动传递给类实例的方法,以标识调用它的实例。 “ self ”用于从方法内部访问对象的其他属性或方法。 (方法基本上只属于一个类的函数)

当你已经有一个可用的实例时,调用方法时不需要使用“ self ”。

从方法内部访问“some_attribute”属性:

 class MyClass(object): some_attribute = "hello" def some_method(self, some_string): print self.some_attribute + " " + some_string 

从现有实例访问“some_attribute”属性:

 >>> # create the instance >>> inst = MyClass() >>> >>> # accessing the attribute >>> inst.some_attribute "hello" >>> >>> # calling the instance's method >>> inst.some_method("world") # In addition to "world", inst is *automatically* passed here as the first argument to "some_method". hello world >>> 

这里有一个小小的代码来certificate自我和实例是一样的:

 >>> class MyClass(object): >>> def whoami(self, inst): >>> print self is inst >>> >>> local_instance = MyClass() >>> local_instance.whoami(local_instance) True 

正如其他人所说,按照惯例它被命名为“ 自我 ”,但它可以被命名为任何东西。

self指的是Bank目前的实例。 当你创build一个新的Bank ,并调用create_atm时, self将被python隐含地传递,并且会引用你创build的银行。

我不立即苟且self所指的。 这绝对是不了解课堂的一个症状,我会在某个时候着手。

self是传递给函数的一个参数。 在Python中,这个第一个参数隐式地是该方法被调用的对象。 换一种说法:

 class Bar(object): def someMethod(self): return self.field bar = Bar() bar.someMethod() Bar.someMethod(bar) 

最后两行有相同的行为。 (除非bar指的是Bar的子类的一个对象 – 那么someMethod()可能指向一个不同的函数对象。)

注意,你可以任意指定“特殊的”第一个参数 – self只是方法的约定。

我明白, i指向列表range(3)中的一个项目,因为它在一个函数中,不是全局的。 但是, self “指向”是什么?

名称self在该函数的上下文中不存在。 试图使用它会引发一个NameError


示例成绩单:

 >>> class Bar(object): ... def someMethod(self): ... return self.field ... >>> bar = Bar() >>> bar.field = "foo" >>> bar.someMethod() 'foo' >>> Bar.someMethod(bar) 'foo' >>> def fn(i): ... return self ... >>> fn(0) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in fn NameError: global name 'self' is not defined 

一个Rubyist的观点 (Ruby是我的第一个编程语言,所以我为任何过于简化的,我将要使用的可能错误的抽象而道歉)

据我所知,点运算符,例如:

 os.path 

是这样的os作为其第一个variables“无形”传递到path()

这就好像os.path真的是这样的:

 path(os) 

如果有一个菊花链,我会想像这个:

 os.path.filename 

在现实中会是这样的*:

 filename(path(os)) 

这里是进攻部分因此,所有的自variables所做的是允许CLASS方法(从ruby的angular度来看,python的“实例方法”看起来像是类方法…)作为一个实例方法,通过获取一个实例传递给它作为它的第一个variables(通过上面的“偷偷摸摸的”点方法),这个variables被称为self约定。 自己不是一个实例

 c = ClassName() c.methodname 

但是class级本身:

 ClassName.methodname 

该类将被传入而不是实例。

好的,还要记住的是__init__方法被一些人称为“魔术”。 所以不要担心生成新实例的内容。 说实话,它可能是nil

self指的是这个类的一个实例。

“自我”(按照惯例)的原因是,当Python运行时看到一个forms为Object.Method(Param1,Param2)的调用时,它调用带有参数(Object,Param1,Param2)的Method。 所以如果你把第一个参数称为“自我”,每个人都会知道你在说什么。

你必须这样做的原因是另一个问题的主题。

就元类而言,这是很less使用的东西。 你可能想看看: http : //python-history.blogspot.com/2009/04/metaclasses-and-extension-classes-aka.html ,原作者和当前仁慈的生命独裁者解释了这是什么,以及它是如何成为的。 他在一些可能的用途上也有不错的文章,但大多数人从来没有直接使用过。