分享

Python中self的解释

 liqualife 2019-07-14

定义

首先我们要搞明白Python的类中为要什么要用到self这个单词呢,为什么不用'zhangsan'、'lisi'这样的名字呢,这可定有他的用意。查Google翻译解释:

self
名词的解释:自;自我;自己

那么问题来了,这里的自己指代的到底是谁,下面听我详细分解。(仅属于自己的见解,有不对的地方,还望不吝赐教)

分析

测试代码以一下这个代码及其它的扩充为基础,先贴代码,为了好理解,别说了半天不知道我在说什么。

class A(): def song(one): print(one) def sing(self,one): print(one)
  • 1
  • 2
  • 3
  • 4
  • 5
1、首先要搞清楚的一个问题 a=A()与a=A,这两个赋值之间的区别
a=A()print(a)a=Aprint(a)print(A)结果如下:<__main__.A object at 0x0000020A69C81780><class '__main__.A'><class '__main__.A'>分析:a=A()  是有地址的,这说明他是一个实体,比如 int a  中的 a 一样a=A    是没有地址的,发现他和A打印的结果一毛一样,这说明他就是A,也就是一个类名,       等价于上一句中 int a 中的 int       那么也就是说下面这两语句是等价的b=A()   与   b=a()-------------------------------------------------------------------------通过上面的分析,我们知道,a=A()相当于把 A 给实例化了,什么叫实例化呢,类比与 int a ,int 什么都不能做,即 int 不能被赋值,不能进行算术操作等等,但是 a 可以(其实这里的 A 与 int是一样的,追溯到C语言,类只不过是一种自定义的结构变量而已,只不过功能更加强大)。那具体怎么个实例发呢?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
2、self 到底指代的是谁
class A(): def song(one): print(one) def sing(self,one): print(one)a=A()A.sing(a,'hello') #注意这条语句a.sing('hello')打印结果:hellohello-------------------------------A.sing('hello')错误信息:TypeError: sing() missing 1 required positional argument: 'one'提示没有给 one 赋值--------------------------------a.song('hello')错误信息:TypeError: song() takes 1 positional argument but 2 were given那么问题来了,多给了一个什么参数,为什么会多给呢?--------------------------------把类A改一下class A(): def song(one,two): #注意这里多给song了一个参数 print(one)a.song('hello') //这里的参数 'hello'赋给了 twoprint(a)打印结果:<__main__.A object at 0x0000020A69C39CC0><__main__.A object at 0x0000020A69C39CC0>是不是很奇怪,为什么a.song('hello')返回的是 实例 a 的地址呢?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

从这个例子中你就可以发现,实际上 a.sing(“hello”) 等价于 A.sing(a,“hello”),而self就是实例 a 自己,而且你发现 self ,也可以用别的单词来代替。
通过这段分析,我们简单的知道了,类中的方法第一个参数必须是 self ,不然实例无法正确调用类中的方法,也就是说,如果方法中第一个参数不是 self(广义的),那么这个方法是没有任何价值的,因为实例无法调用它,一个无法被调用的方法真不知道有什么用。

参数前面的 self

x=6class A():    def sing(self):        self.x=10    def mutl(self):        y=10*x        print(y)a=A()  a.mutl()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

这里先猜一下结果,到底会打印 60 呢,还是 100 呢?要弄清这个问题,就要先弄清 mutl() 中的 x 到底是哪一个,先看结果在分析。
结果是:60
为什么不调用类内部的 x 参数而跑去调用类外的 x 呢?还是那个问题,self 到底指代的是谁,self 就是 a 本身,那么问题就很明显了,mutl() 方法中的 x 前面没有加 self 所以他调用的不是实例(注意这里说的是实例,而不是类)自身的参数。
到这里我想你大概明白了,参数前面有self和没self的区别了,简单说,带self的参数是人家实例自身的,不带self的,爱谁谁,实例不管。

不同方法中的参数是否可以互相使用

class A(): def mutl(self): x=5 def sing(self): y=5*x print(y)a=A() a.mutl()a.sing()错误如下:<ipython-input-3-e305f6d63af0> in sing(self) 3 x=5 4 def sing(self):----> 5 y=5*x 6 print(y) 7 # def print1(self):NameError: name 'x' is not defined
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

可以看到,对于参数前面不加self的参数,只适用于本方法,不能跨方法调用。


class A():    def mutl(self):        self.x=5    def sing(self):        y=5*self.x        print(y)a=A()  a.mutl()a.sing()打印结果:25
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

这里可以清晰地看到不在报错,加了self,立马实现跨方法调用。


class A(): def mutl(self): self.x=5 def sing(self): y=5*self.x print(y)a=A() a.sing()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

先思考一下这段代码与上面的不同之处。
是不是这里没有调用方法 a.mutl()呢,那结果是什么呢,思考一下。

<ipython-input-6-ddb67bd4703e> in sing(self)      3         self.x=5      4     def sing(self):----> 5         y=5*self.x      6         print(y)      7 AttributeError: 'A' object has no attribute 'x'
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

显示类中没有参数 x ,我什么呢,我明明定义了啊,对滴。但是在把类实例之后你没有通过方法 a.mutl() 来实现对 self.x 进行定义。这也就是为什么要先有构造函数了,先把所有类中的参数全部定义以后,你才能使用。

小结

其实说了这么多,说的也很乱,但是我想说明的就两点:

  1. 类中的方法第一个参数是 self 的才可以被实例调用。
  2. 类中带 self 的参数都是 实例 的,实例对这个参数拥有所有权,即实例中所有的方法都可以使用实例的参数。

至于参数什么时候用加self什么时候不用加self,我想你只要弄白了self到底起什么作用,这个问题就不说自明了。

由于水平有限,分析中可能包含一些错误,还望各位不吝赐教,多多海涵!

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多