向初学者解释“self”变量[重复]
- 2025-04-10 09:45:00
- admin 原创
- 19
问题描述:
我几乎不懂 OOP 术语和概念。我从概念上知道什么是对象,以及对象有方法。我甚至知道在 Python 中,类是对象!这很酷,我只是不知道它是什么意思。我不明白。
我目前正在尝试理解一些详细的答案,我认为这些答案将阐明我对 python 的理解:
Python 中“yield”关键字起什么作用?
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(从 rubyist 的角度来看,python“实例方法”似乎是类方法……)充当实例方法,方法是将一个实例作为其第一个变量传递给它(通过上面的“鬼鬼祟祟”的点方法),这是按照self
惯例调用的。如果 self 不是实例
c = ClassName()
c.methodname
但班级本身:
ClassName.methodname
传递的是类而不是实例。
好的,同样重要的是要记住,有些人称该__init__
方法为“魔法”。所以不要担心传入什么来生成新实例。老实说,很可能是nil
。
解决方案 8:
self
指的是类的一个实例。
扫码咨询,免费领取项目管理大礼包!