Python中 self
字的目的是什么?我理解它指的是从该类创建的特定对象,但我不明白为什么它明确需要作为参数添加到每个函数 . 为了说明,在Ruby中我可以这样做:
class myClass
def myFunc(name)
@name = name
end
end
我很容易理解 . 但是在Python中我需要包含 self
:
class myClass:
def myFunc(self, name):
self.name = name
谁能跟我说说这个?这不是我在(无可否认的有限)经历中遇到的事情 .
19 回答
它遵循Python zen“显然优于隐式” . 它确实是对您的类对象的引用 . 例如,在Java和PHP中,它被称为
this
.如果
user_type_name
是模型上的字段,则可以通过self.user_type_name
访问它 .实例化对象时,对象本身将传递给self参数 .
因此,对象的数据绑定到对象 . 下面是一个示例,说明如何可视化每个对象的数据外观 . 注意'self'如何被对象名称替换 . 我不是说下面的这个示例图是完全准确的,但它有望用于可视化自我的使用 .
Object被传递给self参数,以便对象可以保持自己的数据 .
虽然这可能不完全准确,但请考虑实例化这样的对象的过程:当创建对象时,它使用该类作为其自己的数据和方法的模板 . 如果不将自己的名称传递给self参数,则类中的属性和方法将保留为通用模板,并且不会引用(属于)对象 . 因此,通过将对象的名称传递给self参数,意味着如果从一个类中实例化100个对象,则它们都可以跟踪它们自己的数据和方法 .
见下图:
通常称为
self
的参数的使用并不难理解,为什么有必要?或者至于为什么明确提到它?我想,对于大多数查找这个问题的用户来说,这是一个更大的问题,或者如果不是,他们肯定会有同样的问题,因为他们会继续学习python . 我建议他们阅读以下几篇博客:1: Use of self explained
请注意,它不是关键字 .
2: Why do we have it this way and why can we not eliminate it as an argument, like Java, and have a keyword instead
我想补充的另一件事是,一个可选的
self
参数允许我在类中声明静态方法,而不是写self
.代码示例:
PS :这仅适用于Python 3.x.
在以前的版本中,您必须显式添加
@staticmethod
装饰器,否则必须使用self
参数 .Python不是为面向对象编程而构建的语言,与Java或C不同 .
在Python中调用静态方法时,只需在其中编写一个带有常规参数的方法 .
但是,在这种情况下,需要您创建变量的对象方法(在本例中为Animal)需要self参数
self方法还用于引用类中的变量字段 .
在这种情况下,self指的是整个类的animalName变量 . 记住:如果方法中有变量,则self不起作用 . 该变量仅在该方法运行时才存在 . 对于定义字段(整个类的变量),您必须在类方法外定义它们 .
如果你不理解我所说的单词,那么Google就是“面向对象的编程” . 一旦你理解了这一点,你甚至不需要问这个问题:) .
您需要使用
self.
的原因是因为Python不使用@
语法来引用实例属性 . Python决定以某种方式执行方法,使方法所属的实例自动传递,但不会自动传递:方法的第一个参数是调用方法的实例 . 这使方法与函数完全相同,并保留实际名称以供您使用(尽管self
是惯例,当您使用其他内容时,人们通常会对您不满 . )self
对代码并不特殊,它只是另一个对象 .Python可以做其他事情来区分普通名称和属性 - 像Ruby这样的特殊语法,或者需要像C和Java那样的声明,或者可能是更不同的东西 - 但是它并没有使事情变得明确,显而易见的是's what, and although it doesn't在任何地方完全做到了,它确实做了例如属性 . 那个's why assigning to an instance attribute needs to know what instance to assign to, and that'为什么它需要
self.
.self
是对象本身的对象引用,因此它们是相同的 . Python方法不在对象本身的上下文中调用 . Python中的self
可用于处理自定义对象模型或其他东西 .是因为按照python的设计方式,替代方案几乎不起作用 . Python旨在允许在一个上下文中定义方法或函数,其中隐式
this
(a-la Java / C)或显式@
(a-la ruby)都不具有使用python约定的显式方法的示例:现在
fubar
函数不起作用,因为它假设self
是一个全局变量(也在frob
中) . 另一种方法是使用替换的全局范围执行方法(其中self
是对象) .隐含的方法是
这意味着
myX
将被解释为fubar
中的局部变量(以及frob
中) . 这里的替代方法是执行具有替换的局部范围的方法,该范围在调用之间保留,但这将删除方法局部变量的可能性 .然而目前的情况很好:
这里当作为方法调用时
frob
将通过self
参数接收它所调用的对象,并且仍然可以使用对象作为参数调用fubar
并且工作相同(我认为它与_243207相同) .我们来看一个简单的矢量类:
我们想要一个计算长度的方法 . 如果我们想在类中定义它会是什么样子?
当我们将其定义为全局方法/函数时,它应该是什么样的?
所以整个结构保持不变 . 我怎么能利用这个呢?如果我们暂时假设我们没有为
Vector
类编写length
方法,我们可以这样做:这是有效的,因为
length_global
的第一个参数可以重新用作length_new
中的self
参数 . 如果没有明确的self
,这是不可能的 .理解显式
self
的需要的另一种方法是查看Python添加一些语法糖的位置 . 当你记住,基本上,一个电话就像内部转变为
很容易看出
self
适合的位置 . 你实际上并没有在Python中编写实例方法;你写的是类方法,它必须将实例作为第一个参数 . 因此,您必须明确地将实例参数放在某处 .我喜欢这个例子:
它的用法类似于在Java中使用
this
关键字,即提供对当前对象的引用 .以下摘录来自Python documentation about self:
有关更多信息,请参阅Python documentation tutorial on classes .
我很惊讶没有人带来Lua . Lua也使用'self'变量,但它可以省略但仍然使用 . C对'this'做同样的事情 . 我没有看到任何理由必须在每个函数中声明'self',但你仍然可以像使用lua和C一样使用它 . 对于一种以简短而自豪的语言来说,奇怪的是它需要你声明自变量 .
首先,自我是一个传统的名字,你可以把任何其他东西(连贯的)代替 .
它指的是对象本身,因此当您使用它时,您声明.name和.age是您要创建的Student对象(注意,而不是Student类)的属性 .
Code is here
假设您有一个类
ClassA
,其中包含一个方法methodA
,定义如下:和
ObjectA
是此类的一个实例 .现在当调用
ObjectA.methodA(arg1, arg2)
时,python会在内部将它转换为:self
变量引用对象本身 .它是对类实例对象的显式引用 .
除了已经陈述的所有其他原因之外,它还允许更容易地访问被覆盖的方法;你可以拨打
Class.some_method(inst)
.它有用的一个例子:
我将用代码演示 does not use classes :
类只是一种避免一直传递这种“状态”的东西的方法(以及其他很好的东西,如初始化,类组合,很少需要的元类,并支持自定义方法来覆盖运算符) .
现在让我们使用内置的python类机器演示上面的代码,以显示它是如何基本相同的 .
[从重复的封闭问题中移出我的答案]
看一下下面的例子,它清楚地解释了
self
的目的使用/需要
self
来区分实例 .在
__init__
方法中,self引用新创建的对象;在其他类方法中,它指的是调用其方法的实例 .自我,作为一个名字, just a convention ,按你的意愿调用它!但是当使用它时,例如删除对象,你必须使用相同的名称:
__del__(var)
,其中var
在__init__(var,[...])
中使用您也应该看看
cls
,以获得 the bigger picture . 这个post可能会有所帮助 .