向初学者解释“self”变量

13 浏览
0 Comments

向初学者解释“self”变量

我对面向对象编程的术语和概念几乎一无所知。我从概念上知道什么是对象,以及对象有方法。我甚至明白在Python中,类也是对象!这很酷,只是我不知道它意味着什么。我还没有完全理解一些详细的答案,我认为它们会帮助我理解Python:\n

    \n

  1. Python中的\"yield\"关键字是什么意思?
  2. \n

  3. Python中的元类是什么?
  4. \n

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

>>> class Bank(): # 让我们创建一个银行,里面有ATM
...    crisis = False
...    def create_atm(self) :
...        while not self.crisis :
...            yield "$100"

\n我不立即理解self指向的是什么。这显然是不理解类的一个症状,我会在某个时候解决这个问题。为了澄清,在\n

>>> def func():
...   for i in range(3):
...     print i

\n我理解i指向range(3)列表中的一个项,由于它在函数中,所以不是全局的。但是self指向什么呢?

0
0 Comments

"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"属性:

>>> # 创建实例
>>> inst = MyClass()
>>>
>>> # 访问属性
>>> inst.some_attribute
"hello"
>>> 
>>> # 调用实例的方法
>>> inst.some_method("world") # 除了"world"外,inst作为第一个参数自动传递给"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",但它可以被命名为任何其他名称。

对于明确说明local_instance被传递给方法,并且方法只是在类中定义的函数,给予+1。谢谢!

0
0 Comments

解释给初学者的“self”变量

在Python中,我们经常看到这样的语法:obj.method(arg1, arg2),实际上,这只是一种语法糖,等价于method(obj, arg1, arg2)(不同的是,method是通过obj的类型查找的,而不是全局的)。

如果我们从这个角度来看,obj实际上是函数的第一个参数,在参数列表中通常被命名为self(实际上你可以给它取其他名字,代码依然可以正常运行,但其他Python程序员可能会对你皱眉头)。

这种观点还能解释为什么会出现foo() takes exactly n arguments, n+1 given的错误提示,当调用者传递了n个参数,但实际上应该传递n-1个参数。

我认为可以将其理解为type(obj).method(obj, arg1, arg2),这样可以避免关于查找的困惑。

所以,这是否意味着每次在类中定义函数时,如果我想让这个函数作用于类的实例上,就需要一个名为self的必需参数?

是的,而且它必须是第一个参数。(如果你不希望使用类的实例,比如静态方法,为了避免指定(未使用的)self参数,你必须使用staticmethod修饰器装饰该方法。)

0
0 Comments

解决方法:

为了解决初学者对于类和对象的混淆问题,可以通过以下方法进行解释:

首先,需要明确的是,上面的代码块并不是在“创建”一个银行,而是在定义一个银行。一个银行(Bank)是一个具有名为“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():

crisis = False

def create_atm(thisbank):

while not thisbank.crisis:

yield "$100"

实际上,尽管初学者不需要知道或关心,但在Python中,类也是对象(类型为'type')。

对于上面的评论,我给予了+1,因为它对于类的概念有了很好的解释。我之前没有完全理解类和实例之间的区别,也不知道可以通过Class.method(obj)这种方式来创建对象。

对于这个问题,有人提出了质疑,认为上面的例子是错误的,因为crisis在初始化时没有使用self,因此它是一个类变量,并且在实例之间是共享的。所以,银行x和y检查的是同一个crisis的值?!

我进行了检查。两个例子都是正确的。但我仍然不理解其中的区别。

这似乎是一个经常被问到的问题。你可以在这里找到答案,例如:stackoverflow.com/questions/39039884/…

事实上,x.create_atm()在python中等同于调用Bank.create_atm(x)。我认为这个类比非常有帮助。

0