我几乎不知道OOP术语和概念。我从概念上知道对象是什么,对象有方法。我甚至明白在python中,类是对象!那很酷,我只是不知道它意味着什么。它没有点击我。
我目前正在尝试理解一些我认为将阐明我对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
“指向什么?”
答案 0 :(得分:92)
我会首先尝试清除一些关于类和对象的混淆。让我们看看这段代码:
>>> class Bank(): # let's create a bank, building ATMs
... crisis = False
... def create_atm(self) :
... while not self.crisis :
... yield "$100"
评论有点具欺骗性。上面的代码没有“创建”银行。它定义了银行是什么。银行是具有名为crisis
的属性和函数create_atm
的东西。这就是上面代码所说的内容。
现在让我们创建一个银行:
>>> x = Bank()
在那里,x
现在是一家银行。 x
有一个属性crisis
和一个函数create_atm
。在python中调用x.create_atm();
与调用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"
答案 1 :(得分:18)
可能会帮助您将obj.method(arg1, arg2)
调用语法视为调用method(obj, arg1, arg2)
的纯语法糖(除了method
通过obj
类型查找,并不是全球性的。
如果以这种方式查看,obj
是函数的第一个参数,传统上在参数列表中将其命名为self
。 (实际上,您可以将其命名为其他内容,并且您的代码将正常运行,但其他Python编码器会对您不满。)
答案 2 :(得分:12)
“ 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
>>>
这是一个小代码,用于演示self与实例相同:
>>> class MyClass(object):
>>> def whoami(self, inst):
>>> print self is inst
>>>
>>> local_instance = MyClass()
>>> local_instance.whoami(local_instance)
True
正如其他人所提到的,它按照惯例命名为“ self ”,但它可以命名为任何东西。
答案 3 :(得分:5)
self
指的是Bank
的当前实例。当您创建新的Bank
并在其上调用create_atm
时,self
将由python隐式传递,并将引用您创建的银行。
答案 4 :(得分:5)
我没有立即了解
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
答案 5 :(得分:2)
“self”的原因(根据惯例)是当Python运行时看到Object.Method(Param1,Param2)形式的调用时,它调用带参数的Method(Object,Param1,Param2)。因此,如果你将第一个参数称为“自我”,那么每个人都会知道你在说什么。
你必须这样做的原因是另一个问题的主题。
就元类而言,这是很少使用的东西。你可能想看看: http://python-history.blogspot.com/2009/04/metaclasses-and-extension-classes-aka.html,原始作者和当前仁慈的Python生活独裁者解释了这是什么,以及它是如何形成的。他还有一篇关于一些可能用途的好文章,但大多数人根本不会直接使用它。
答案 6 :(得分:2)
一个Rubyist的观点(Ruby是我的第一个编程语言,所以我为我即将使用的过于简单,可能错误的抽象道歉)
据我所知,点运算符,例如:
os.path
是os
被传递到path()
作为其第一个变量“无形”
好像os.path
就是这样:
path(os)
如果有菊花链,我会想到这个:
os.path.filename
在现实中会有点像这样*:
filename(path(os))
这是令人反感的部分
因此,使用自变量所做的一切就是允许CLASS METHOD(从rubyist的角度来看python'实例方法'似乎是类方法......)通过将一个实例作为第一个变量传递给它来充当实例方法(通过上面的“偷偷摸摸”点方法)按惯例称为self
。我自己不是一个实例
c = ClassName()
c.methodname
但班级本身:
ClassName.methodname
该类将被传入而不是实例。
好的,记住的重要一点是__init__
方法被某些人称为“魔法”。所以不要担心传递什么来生成新实例。说实话,它可能是nil
。
答案 7 :(得分:1)
self
指的是该类的实例。