向初学者解释'self'变量

39 投票
8 回答
93725 浏览
提问于 2025-04-16 23:10

我对面向对象编程的术语和概念几乎一无所知。我大概知道什么是对象,也知道对象有方法。我甚至明白在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到底“指向”什么呢?

8 个回答

14

在类的方法被调用时,"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" 这个名字是约定俗成的,其实可以用任何名字。

19

你可以把 obj.method(arg1, arg2) 这种写法看作是调用 method(obj, arg1, arg2) 的一种更简单的方式。唯一的不同是,method 是通过 obj 的类型来查找的,而不是在全局范围内查找。

如果你这样理解的话,obj 就是这个函数的第一个参数,通常在参数列表中叫做 self。当然,你可以把它命名成别的名字,这样代码也能正常运行,但其他的Python程序员可能会对你皱眉头。

99

我来帮你理清一下关于类和对象的概念。我们先看看这段代码:

>>> 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() 时,它会查看 ycrisis 值,而不是 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"

撰写回答