向初学者解释“self”变量[重复]

2025-04-10 09:45:00
admin
原创
19
摘要:问题描述:我几乎不懂 OOP 术语和概念。我从概念上知道什么是对象,以及对象有方法。我甚至知道在 Python 中,类是对象!这很酷,我只是不知道它是什么意思。我不明白。我目前正在尝试理解一些详细的答案,我认为这些答案将阐明我对 python 的理解:Python 中“yield”关键字起什么作用?Pytho...

问题描述:

我几乎不懂 OOP 术语和概念。我从概念上知道什么是对象,以及对象有方法。我甚至知道在 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“指向”什么呢?


解决方案 1:

首先,我会试着为您澄清一些关于类和对象的困惑。让我们看看这一段代码:

>>> 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"

解决方案 2:

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

如果你这样看,obj是函数的第一个参数,传统上self在参数列表中命名。(事实上,你可以用其他名字命名,你的代码也能正常工作,但其他 Python 程序员会对你皱眉头。)

解决方案 3:

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 ”,但它可以被命名为任何名称。

解决方案 4:

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

解决方案 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

解决方案 6:

之所以有“self”(按照惯例),是因为当 Python 运行时看到 Object.Method(Param1,Param2) 形式的调用时,它会调用带有参数 (Object,Param1,Param2) 的 Method。因此,如果您将第一个参数称为“self”,每个人都会知道您在说什么。

你必须这样做的原因是另一个问题的主题。

至于元类,它很少被使用。您可能想看看:
http://python-history.blogspot.com/2009/04/metaclasses-and-extension-classes-aka.html,原作者和 Python 的现任仁慈独裁者解释了这是什么,以及它是如何产生的。他还写​​了一篇关于一些可能用途的精彩文章,但大多数人从未直接使用它。

解决方案 7:

一位 Ruby 程序员的观点(Ruby 是我的第一门编程语言,因此对于我将要使用的任何过于简单、可能错误的抽象,我深表歉意)

据我所知,点运算符例如:

os.path

是作为其第一个变量“不可见地”os传递进去的path()

就好像os.path真的是这样:

path(os)

如果有菊花链我会想象这样:

os.path.filename

在现实中会是这样的*:

filename(path(os))

接下来是攻击部分
,因此,使用 self 变量,所做的就是允许 CLASS METHOD(从 ruby​​ist 的角度来看,python“实例方法”似乎是类方法……)充当实例方法,方法是将一个实例作为其第一个变量传递给它(通过上面的“鬼鬼祟祟”的点方法),这是按照self惯例调用的。如果 self 不是实例

c = ClassName()
c.methodname

但班级本身:

ClassName.methodname

传递的是类而不是实例。

好的,同样重要的是要记住,有些人称该__init__方法为“魔法”。所以不要担心传入什么来生成新实例。老实说,很可能是nil

解决方案 8:

self指的是类的一个实例。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2482  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1533  
  PLM(产品生命周期管理)项目对于企业优化产品研发流程、提升产品质量以及增强市场竞争力具有至关重要的意义。然而,在项目推进过程中,范围蔓延是一个常见且棘手的问题,它可能导致项目进度延迟、成本超支以及质量下降等一系列不良后果。因此,有效避免PLM项目范围蔓延成为项目成功的关键因素之一。以下将详细阐述三大管控策略,助力企业...
plm系统   0  
  PLM(产品生命周期管理)项目管理在企业产品研发与管理过程中扮演着至关重要的角色。随着市场竞争的加剧和产品复杂度的提升,PLM项目面临着诸多风险。准确量化风险优先级并采取有效措施应对,是确保项目成功的关键。五维评估矩阵作为一种有效的风险评估工具,能帮助项目管理者全面、系统地评估风险,为决策提供有力支持。五维评估矩阵概述...
免费plm软件   0  
  引言PLM(产品生命周期管理)开发流程对于企业产品的全生命周期管控至关重要。它涵盖了从产品概念设计到退役的各个阶段,直接影响着产品质量、开发周期以及企业的市场竞争力。在当今快速发展的科技环境下,客户对产品质量的要求日益提高,市场竞争也愈发激烈,这就使得优化PLM开发流程成为企业的必然选择。缺陷管理工具和六西格玛方法作为...
plm产品全生命周期管理   0  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用