向初学者解释python“self”variables
我几乎不知道OOP的术语和概念。 我从概念上了解对象是什么,对象是否有方法。 我甚至明白,在Python中,类是对象! 这很酷,我只是不知道这意味着什么。 这是不是跟我一起点击。
我目前正试图了解一些详细的答案,我认为这将说明我对Python的理解:
- Python中的“yield”关键字是做什么的?
- 什么是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
是通过obj
types查找的,而不是全局的)。
如果以这种方式查看,则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 ,原作者和当前仁慈的生命独裁者解释了这是什么,以及它是如何成为的。 他在一些可能的用途上也有不错的文章,但大多数人从来没有直接使用过。