内容目录(原文见公众号python宝)
一、self代表类的实例二、self 举例三、self用法详解
一、self代表类的实例
self代表类的实例,而非类。
class Test:
def prt(self):
print(self)
print(self.__class__)
t = Test()
t.prt()
'''从上面的例子中可以很明显的看出,self代表的是类的实例。而self.class则指向类。
<__main__.Test object at 0x000001C467408D68>
<class '__main__.Test'>
'''
如果定义和调用时均不传类实例是可以的,就是
类方法
。
class Test:
def prt():
print(__class__)
Test.prt()
'''
<class '__main__.Test'>
'''
在继承时,传入的是哪个实例,就是那个传入的实例,而不是指定义了self的类的实例。
运行c.cprt()时应该没有理解问题,指的是Child类的实例。
但是在运行c.pprt()时,等同于Child.pprt(c),所以self指的依然是Child类的实例,由于self中没有定义pprt()方法,
所以沿着继承树往上找,发现在父类Parent中定义了pprt()方法,所以就会成功调用。
class Parent:
def pprt(self):
print(self)
class Child(Parent):
def cprt(self):
print(self)
c = Child()
c.cprt()
c.pprt()
p = Parent()
p.pprt()
'''
<__main__.Child object at 0x000001CDA16F50B8>
<__main__.Child object at 0x000001CDA16F50B8>
<__main__.Parent object at 0x000001CDA16F5128>
'''
总结
-
self在定义时需要定义,但是在调用时会自动传入。
-
self的名字并不是规定死的,但是最好还是按照约定是用self
-
self总是指调用时的类的实例。
二、self 举例
类是创建实例的模板,而实例则是一个一个具体的对象,各个实例拥有的数据都相互独立、互不影响;方法是与实例绑定的函数,和普通的函数不同,方法可以直接访问实例的数据
其实 self 中存储的是 实例变量 和 实例函数 的属性,可以理解为一个字典( dict ),如:{‘name’:’zhang’,’age’:’18’}就是这些。
class User(object):
def __init__(self, name, age):
self.name = name
self.age = age
def SetName(self, name):
self.name = name
def SetAge(self, age):
self.age = age
def GetName(self):
return self.name
def GetAge(self):
return self.age
u = User('kzc', 17)
print(u.GetName())
print(u.GetAge())
'''
kzc
17
'''
三、self用法详解
self 参数的具体作用是什么呢?打个比方,如果把类比作造房子的图纸,那么类实例化后的对象是真正可以住的房子。根据一张图纸(类),我们可以设计出成千上万的房子(类对象),每个房子长相都是类似的(都有相同的类变量和类方法),但它们都有各自的主人,那么如何对它们进行区分呢?
当然是通过 self 参数,它就相当于每个房子的门钥匙,可以保证每个房子的主人仅能进入自己的房子(每个类对象只能调用自己的类变量和类方法)。
也就是说,同一个类可以产生多个对象,当某个对象调用类方法时,该对象会把自身的引用作为第一个参数自动传给该方法,换句话说,Python 会自动绑定类方法的第一个参数指向调用该方法的对象。如此,Python解释器就能知道到底要操作哪个对象的方法了。
class Box(object):
def __init__(self, boxname, size, color):
self.boxname = boxname
self.size = size
self.color = color # self就是用于存储对象属性的集合,就算没有属性self也是必备的
def open(self, myself):
print('-->用自己的myself,打开那个%s,%s的%s' % (myself.color, myself.size, myself.boxname))
print('-->用类自己的self,打开那个%s,%s的%s' % (self.color, self.size, self.boxname))
def close(self):
print('-->关闭%s,谢谢' % self.boxname)
b = Box('魔盒', '14m', '红色')
b.close()
b.open(b) # 本来就会自动传一个self,现在传入b,就会让open多得到一个实例对象本身,print看看是什么。
print(b.__dict__) # 这里返回的就是self本身,self存储属性,没有动作。
'''
-->关闭魔盒,谢谢
-->用自己的myself,打开那个红色,14m的魔盒
-->用类自己的self,打开那个红色,14m的魔盒
{'boxname': '魔盒', 'size': '14m', 'color': '红色'}
'''
class Box(object):
def myInit(mySelf, boxname, size, color):
print(mySelf.__dict__)#显示为{}空字典
mySelf.boxname = boxname
mySelf.__dict__['aa'] = 'w'#甚至可以像字典一样操作
mySelf.size = size
mySelf.color = color # 自己写一个初始化函数,一样奏效,甚至不用self命名。其它函数当中用标准self
return mySelf # 返回给实例化过程一个对象!神奇!并且含有对象属性/字典
# def __init__(self, boxname, size, color):
# self.boxname = boxname
# self.size = size
# self.color = color #注释掉原来标准的初始化
def open(self, myself):
print(self)
print('-->用自己的myself,打开那个%s,%s的%s' % (myself.color, myself.size, myself.boxname))
print('-->用类自己的self,打开那个%s,%s的%s' % (myself.color, myself.size, myself.boxname))
def close(self):
print('-->关闭%s,谢谢' % self.boxname)
# 经过改造,运行结果和标准初始化没区别
b = Box().myInit('魔盒', '14m', '红色')
# b = Box('魔盒', '14m', '红色')#注释掉原来标准的初始化方法
b.close()
b.open(b) # 本来就会自动传一个self,现在传入b,就会让open多得到一个实例对象本身,print看看是什么。
print(b.__dict__) # 这里返回的就是self本身,self存储属性,没有动作。
'''
{}
-->关闭魔盒,谢谢
<__main__.Box object at 0x000002DA36AE9668>
-->用自己的myself,打开那个红色,14m的魔盒
-->用类自己的self,打开那个红色,14m的魔盒
{'boxname': '魔盒', 'aa': 'w', 'size': '14m', 'color': '红色'}
'''
About Me:
小麦粒
● 本文作者:小麦粒,专注于python、数据分析、数据挖掘、机器学习相关技术,也注重技术的运用
● 作者博客地址:https://blog.csdn.net/u010986753
● 本系列题目来源于作者的学习笔记,部分整理自网络,若有侵权或不当之处还请谅解
● 版权所有,欢迎分享本文,转载请保留出处
● 个人微信号:pythonbao 联系我加微信群
●个人 QQ:87605025
● QQ交流群pythonbao :483766429
● 公众号:python宝 或 DB宝
● 提供OCP、OCM和高可用最实用的技能培训
● 题目解答若有不当之处,还望各位朋友批评指正,共同进步
欢迎赞赏哦!
有您的支持,小麦粒一定会越来越好!