我对OOP术语和概念相当无知。我从概念上知道对象是什么,知道对象有方法。我甚至明白,在python中,类就是对象!很好,我只是不知道这是什么意思。它不适合我。
我目前正在试图理解一些详细的答案,我认为这些答案将阐明我对python的理解:
- 什么是"yield"Python中的关键字do ? 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
"指向"什么呢?
我将首先为您澄清一些关于类和对象的混淆。让我们看看这段代码:
>>> 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"
这可能有助于您将obj.method(arg1, arg2)
调用语法视为调用method(obj, arg1, arg2)
的纯语法糖(除了method
是通过obj
的类型查找的,并且不是全局的)。
如果你这样看,obj
是函数的第一个参数,传统上在参数列表中被命名为self
。(事实上,你可以将它命名为其他东西,你的代码将正常工作,但其他Python程序员会对你不满。)
"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",但它可以被命名为任何名称。
self
为Bank
的当前实例。当你创建一个新的Bank
,并在其上调用create_atm
时,self
将被python隐式传递,并将引用你创建的银行。
我不马上明白
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
存在"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的原作者和现任仁慈独裁者,他解释了这是什么,以及它是如何产生的。他还写了一篇很好的文章,介绍了一些可能的用途,但大多数人根本不会直接使用它。
一个Ruby主义者的观点 (Ruby是我的第一门编程语言,所以我为我将要使用的任何过度简化,可能错误的抽象道歉)
据我所知,点运算符,例如:
os.path
使得os
作为path()
的第一个变量" invisible "被传递给
如果os.path
是真的:
path(os)
如果有雏菊链,我会想象这样:
os.path.filename
在现实中有点像这样*:
filename(path(os))
进攻部分来了因此,对于self变量,所做的就是允许CLASS METHOD(从ruby主义者的角度来看,python的"实例方法"似乎是类方法……)通过将实例传递给它作为其第一个变量(通过上面的"鬼鬼祟祟的"点方法)作为一个实例方法,按照惯例称为self
。如果self不是一个实例
c = ClassName()
c.methodname
而是类本身:
ClassName.methodname
类将被传递,而不是实例。
好的,同样重要的是要记住__init__
方法被一些人称为"魔法"。所以不要担心传递给生成新实例的是什么。老实说可能是nil
self
指的是类的一个实例