向初学者解释'self'变量
我对面向对象编程的术语和概念几乎一无所知。我大概知道什么是对象,也知道对象有方法。我甚至明白在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
到底“指向”什么呢?
8 个回答
在类的方法被调用时,"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" 这个名字是约定俗成的,其实可以用任何名字。
你可以把 obj.method(arg1, arg2)
这种写法看作是调用 method(obj, arg1, arg2)
的一种更简单的方式。唯一的不同是,method
是通过 obj
的类型来查找的,而不是在全局范围内查找。
如果你这样理解的话,obj
就是这个函数的第一个参数,通常在参数列表中叫做 self
。当然,你可以把它命名成别的名字,这样代码也能正常运行,但其他的Python程序员可能会对你皱眉头。
我来帮你理清一下关于类和对象的概念。我们先看看这段代码:
>>> 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
的 crisis
值,而不是 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"