向初学者解释python'self'变量

jrh*_*424 33 python oop scope class

我几乎不知道OOP术语和概念.我从概念上知道对象是什么,对象有方法.我甚至明白在python中,类是对象!那很酷,我只是不知道它意味着什么.它没有点击我.

我目前正在尝试理解一些我认为将阐明我对python的理解的详细答案:

  1. "yield"关键字在Python中的作用是什么?
  2. 什么是Python中的元类?

在第一个答案中,作者使用以下代码作为示例:

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

我不会立即弄清楚self指向的是什么.这绝对是不理解类的一个症状,我将在某些时候开展工作.澄清,在

>>> def func():
...   for i in range(3):
...     print i
Run Code Online (Sandbox Code Playgroud)

我理解i指向列表中的项目range(3),因为它在函数中,不是全局的.但是什么self"指向"?

Pau*_*aul 93

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

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

评论有点欺骗性.上面的代码没有"创建"银行.它定义了银行是什么.银行是具有被称为属性crisis和功能的东西create_atm.这就是上面的代码所说的.

现在让我们创建一个银行:

>>> x = Bank()
Run Code Online (Sandbox Code Playgroud)

在那里,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"
Run Code Online (Sandbox Code Playgroud)

  • 实际上,虽然初学者不应该知道或关心,但是Python中的类是对象(类型为'type').;) (16认同)

Chr*_*ung 18

它可能会帮助您将obj.method(arg1, arg2)调用语法视为纯粹的语法糖用于调用method(obj, arg1, arg2)(除了method通过obj类型查找,并且不是全局的).

如果以这种方式查看它,obj是函数的第一个参数,传统上self在参数列表中命名.(事实上​​,您可以将其命名为其他内容,并且您的代码可以正常工作,但其他Python编码器会对您不满.)

  • @ jrhorn424:是的,它必须是第一个参数.(如果你_don't_想要使用类的实例---如果它是一个静态方法---那么,为了避免必须指定(未使用的)`self`参数,你必须用这个方法来装饰[`@ staticmethod`](http://docs.python.org/library/functions.html#staticmethod)装饰.) (3认同)
  • 我会说它被认为是`type(obj).method(obj,arg1,arg2)`的糖,它避免了查找的毛茸茸. (2认同)

mon*_*kut 12

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

当您已有可用实例时,在调用方法时不需要使用" self ".

从方法内部访问"some_attribute"属性:

class MyClass(object):
    some_attribute = "hello"

    def some_method(self, some_string):
        print self.some_attribute + " " + some_string
Run Code Online (Sandbox Code Playgroud)

从现有实例访问"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
>>> 
Run Code Online (Sandbox Code Playgroud)

这里有一些代码来证明self与实例相同:

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

>>> local_instance.whoami(local_instance)
True
Run Code Online (Sandbox Code Playgroud)

正如其他人所提到的,它按惯例命名为" 自我 ",但它可以被命名为任何东西.


rec*_*ive 5

self是指当前的实例Bank.当你创建一个新的Bank,并调用create_atm它时,self将由python隐式传递,并将引用你创建的银行.


cdh*_*wie 5

我不会立即弄清楚self指向的是什么.这绝对是不理解类的一个症状,我将在某些时候开展工作.

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

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

bar = Bar()

bar.someMethod()
Bar.someMethod(bar)
Run Code Online (Sandbox Code Playgroud)

最后两行具有相同的行为.(除非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
Run Code Online (Sandbox Code Playgroud)