大数跨境
0
0

说一说python中的self

说一说python中的self 数据分析学习与实践
2022-02-15
0
导读:一旦你开始使用 Python,就无法摆脱这个词"self"。在方法定义和变量初始化中都可以看到它。但了解它背

一旦你开始使用 Python,就无法摆脱这个词"self"。在方法定义和变量初始化中都可以看到它。但了解它背后的想法似乎有些麻烦。希望在本文结束时,你会对"self"是什么以及在什么地方使用它有一个直观的概念。

一个画外音,我个人是比较反对在编程教学中,对本来是英文的专有名词进行中文翻译的。正所谓语言塑造了思维,因此一些专有名词一旦翻译过来,无论你翻译的多好,总会有一定程度的语意模糊。比如说“class”,我们在看到这个词的瞬间会联想到“课”,但是翻译过来就是“类”,于是我们会不自觉地,去按照“课”或者“一大类”去理解这个专有名词。这是一种非常严重的潜在的误导,因为class这个专有名词和“课”或者“一大类”关系都不太大(:з」∠)。所以还不如不翻译,就当不知道这个词啥意思,在学习的过程中再慢慢理解他代表的意思。

其实因为英文的局限性,很多编程语言里的专属名词也是大佬们一拍脑袋,瞎起的。。比如我吐槽了无数次的matplotlib里面的axes。

但在谈论 self 关键字之前(实际上它不是 python 的关键字,也不是任何特殊的字面意义),首先,让我们回顾一下什么是 类变量实例变量类变量是与所有使用该特定类创建的实例(对象)共享的变量。因此,当从任何实例中访问一个类变量时,其值都是一样的。另一方面, 实例变量是所有实例为自己保留的变量(即一个特定的对象拥有其实例变量)。所以通常情况下,实例变量的值在不同的实例之间是不同的。

在Python中, 类变量被定义在类定义之后,并且在任何 方法之外。

 
  1. class SomeClass:

  2. variable_1 = '这是一个类变量'

  3. variable_2 = 100 #这也是一个类变量

与类变量不同,实例变量应该在 方法中定义。

 
  1. class SomeClass:

  2. variable_1 = '这是一个类变量'


  3. variable_2 = 100 #这也是一个类变量.


  4. def __init__(self, param1, param2):

  5. self.instance_var1 = param1

  6. #instance_var1 is a instance variable

  7. self.instance_var2 = param2

  8. #instance_var2 is a instance variable

让我们实例化上述类,并对这些实例和上述类做一些理解。

obj1 = SomeClass("some thing", 18)

creating SomeClass的实例1命名为obj1

obj2 = SomeClass(28, 6)

creating SomeClass的实例2命名为 obj2

obj1.variable_1
''这是一个类变量''

obj2.variable_1
''这是一个类变量''

所以正如上面所看到的,当 variable1_ 被访问时,obj1obj2 都给出了相同的值,这是我们应该从一个 类变量中期待的正常行为。让我们来了解一下实例变量。

obj1.instancevar1
'some thing'
obj2.instance
var1
28

所以实例变量的预期行为可以从上面看到,没有任何错误。也就是说,obj1obj2都有两个不同的实例变量给自己。Python 的初学者将从以下内容中受益匪浅 best Python tutorials.

在Python中的实例和类方法

就像有实例变量和类变量一样,也有 实例方法类方法。这些方法是用来设置或获取相关类或实例的状态。因此, 类方法的目的是设置或获取 的细节(状态)。实例方法的目的是设置或获取关于实例(对象)的细节。既然如此,让我们看看如何在python中创建实例和类方法。

当定义一个 实例方法时,该方法的第一个参数应该始终是self。为什么总是 "self "将在下一节讨论(这也是本帖的主要目的)。然而,我们可以给它起除self以外的任何名字,但这个参数所代表的内容永远是一样的。坚持使用self是个好习惯,因为它是惯例。

 
  1. class SomeClass:

  2. def create_arr(self): # An instance method

  3. self.arr = []


  4. def insert_to_arr(self, value): #An instance method

  5. self.arr.append(value)

我们可以将上述类实例化为 obj3 ,并做一些check,如下所示。

obj3 = SomeClass()
obj3.createarr()
obj3.insert
to_arr(5)
obj3.arr
[5]

所以你可以注意到,尽管在定义一个实例方法时,第一个参数是 self ,但在调用该方法时,我们没有为 self 传递任何参数。这怎么会不混淆呢?幕后发生了什么?这些将在下一节中解释。

好了,在解释了实例方法之后,我们剩下的就是类方法(--我是这么说的)。就像实例方法一样,在类方法中也有一个特殊的参数,应该作为第一个参数。这就是 cls 参数,它代表类。

 
  1. class SomeClass:

  2. def create_arr(self): # An instance method

  3. self.arr = []


  4. def insert_to_arr(self, value): #An instance method

  5. self.arr.append(value)


  6. @classmethod

  7. def class_method(cls):

  8. print("the class method was called")

甚至不需要实例化一个对象,我们就可以访问类方法,如下所示。

 
  1. SomeClass.class_method()

所以我们只需要用类的名字来调用类的方法。在这里也和实例方法一样,虽然有一个定义为 cls 的参数,但我们在调用方法时不传递任何参数--接下来解释。

注意:Python 有另一种类型的方法,称为静态方法。这些是普通的方法,不像实例方法或类方法那样有任何特殊参数。因此这些静态方法既不能修改对象状态也不能修改类的状态。

现在所有的事情都被提醒了(实例/类的变量和方法),让我们来谈谈self在Python中的使用( - 最后)。

self — intuition

你们中的一些人现在可能已经明白了,或者一些人可能已经部分明白了;总之,python中的self代表或指向它所调用的实例。让我们通过一个例子来说明这一点。

 
  1. class SomeClass:

  2. def __init__(self):

  3. self.arr = []

  4. #All SomeClass objects will have an array arr by default


  5. def insert_to_arr(self, value):

  6. self.arr.append(value)

所以现在让我们创建两个 SomeClass 的对象,并为它们的数组添加一些值。

obj1 = SomeClass()
obj2 = SomeClass()
obj1.inserttoarr(6)

重要的是: 与其他一些语言不同,当在python中创建一个新的对象时,它不会为自己创建一套新的实例方法。因此,实例方法位于类对象中,不需要在每个对象初始化时创建--这是节省内存的好方法。回顾一下,Python是一种完全面向对象的语言,所以类也是一个对象。所以,它存在内存中。

既然如此,让我们看看上面的例子。我们已经创建了 obj1 ,并且正在调用 SomeClass 的实例方法 inserttoarr() ,同时传递一个参数 6 。但是现在,该方法如何知道 "哪个对象在调用我,谁的实例属性应该被更新"。在这里,我应该向谁的 arr 数组添加值 6 ?好了,现在我想你明白了。这就是 self 的工作。在幕后,在每个实例方法的调用中,python都会将实例与该方法的调用一起发送。所以实际发生的情况是,Python将上面的实例方法调用转换为下面这样的情况。

 
  1. SomeClass.inseart_to_arr(obj1, 6)

现在你知道为什么在Python中应该总是使用 self 作为实例方法的第一个参数,以及当我们调用一个实例方法时,背后真正发生了什么。- 编码愉快!!



“树”的应用


如何通俗的理解二进制


如何通俗的理解队列(queue)


如何通俗理解“树”


如何通俗的理解堆栈


如何通俗理解链表-2


如何通俗的理解链表-1



【声明】内容源于网络
0
0
数据分析学习与实践
数据分析,数据科学,线性代数,统计学,AI,python,可视化,excel
内容 343
粉丝 0
数据分析学习与实践 数据分析,数据科学,线性代数,统计学,AI,python,可视化,excel
总阅读4
粉丝0
内容343