python视频学习之类和对象二

文章介绍了Python中模拟私有变量的概念,通过namemangling改变变量名称,以及__slots__特性用于节省内存空间,限制动态添加属性。同时,讲解了魔法方法如__init__,__new__,__del__的作用和使用场景,以及运算相关的魔法方法和位运算知识。
摘要由CSDN通过智能技术生成

目录

1.私有变量

2.__slots__

 3.魔法方法

(1)__init__(self[, ])方法

(2)使用__new__()方法的两种情况

(3)__del__(self)销毁对象时调用的魔法方法

(4)运算相关的魔法方法

位运算知识


1.私有变量

私有变量就是指通过某种手段,使得对象中的属性或方法无法被外部所访问的机制。在python中,那种仅限从一个对象内部才能够访问的“私有变量”并不存在,但是python引入了一种叫name mangling的机制,翻译过来就是名字改编,它的语法也很简单,就是在名字的前面加上两个连续的下横线。

由以上代码可知:python中所谓的“私有变量” 就是把你想要私有的变量偷偷改了名字,而且改法有规律。方法名也是同样的道理

注: 不建议这样做。有意使用双下划线开头,表示该属性或方法是希望不被外界所访问到的

问题:对象产生后,是否能通过动态添加属性的方式添加“私有变量”?不可以!!!

结论:名字改编发生在类实例化对象的时候

大家以后再开发中,可能还会看到单个下划线开头的变量或者单个下划线结尾的变量。

单个下划线开头的变量是仅供内部使用的变量,属于约定俗成的命名规则,所以当看到这样的名字我们就不要随意访问或者试图修改;使用单下划线作为结尾的变量名,比如说class,是python用来定义类的,一般不能随便用,如果非要变量名叫class,可以在class后面加上一个下划线

2.__slots__

python为了对象的灵活性,有时会牺牲大量的存储空间,比如动态添加属性这个技能,实现原理是“字典”。字典执行效率很高,拿空间换时间。

如果我们明确知道一个类的对象设计出来,就只是需要固定的几个属性,并且将来也不会有动态添加属性的功能,那么利用字典来存放属性这种空间上的牺牲就是浪费,针对这种情况,python专门设计了一个叫__slots__类属性,避免利用字典来存放造成空间上的浪费

 __slots__的限制不仅体现在动态添加属性上,如果我们在类的内部想要创建一个__slots__不包含属性的对象,也不被允许。因为使用了__slots__属性,对象就会划分一个固定大小的空间来存放指定的属性,节省空间。但是使用该属性,就会牺牲python动态语言的灵活性,没办法拥有动态添加属性的功能

 注意:继承自父类的__slots__属性不会在子类中生效,python只会关注各个具体的类中定义的__slots__属性

 3.魔法方法
(1)__init__(self[, ])方法

能够在对象初始化的时候实现个性化定制,它是对象构建的时候调用的方法。参与构建对象还有一个__new__(cls[, ])方法,它是在__init__()之前被调用的,事实上对象是由__new__()方法创建的,所以它的第一个参数是class类,而不是self.对象诞生的流程是先调用new方法,创建一个实例,然后将其传递给init方法,再进行个性化定制这样一个流程。

(2)使用__new__()方法的两种情况
  • 在元类中定制类
  • 继承不可变数据类型时,如果我们想要从中作梗,就可以重写__new__()方法进行拦截
(3)__del__(self)销毁对象时调用的魔法方法

但是,并不是说调用del z就一定会触发__del__()魔法方法,它触发的条件是对象被销毁。

python和大多数编程语言一样,都引入了garbage collection,简单来说就是 当检测到一个对象没有任何引用时,才会将它销毁,所以只要在del z之前将z 送出去,那么del z理论上就不会调用到__del__()魔法方法了,因为此时对象还存在引用

 

 del 方法是在对象销毁前的最后拦截,我们可以利用这个实现对象重生。del方法可以通过创建一个该实例的新引用来推迟销毁,这也叫做对象的重生(不建议使用)

(4)运算相关的魔法方法

 比如说希望两个字符串相加的结果不是拼接,而是统计两者的字符个数之和

r开头的版本也就是反算术运算这部分的方法

__radd__()方法提前调用

当两个对象相加时,如果左侧的对象和右侧的对象不同类型,并且左侧的对象没有定义__add__()方法,或者其__add__()返回NotImplemented,那么python就会去右侧的对象中查找是否有__radd__方法的定义 

这里能够成功调用S2的__radd__方法 ,首先因为S2实现了radd方法,其次s1和s2是基于不同类的一个对象,再有一个条件是s1里必须不能实现__add__方法,不然还是会优先执行左侧的add方法,这里add方法返回NotImplemented就是明确表示该方法未实现,如果s1不写这个方法也是没问题的,其他魔法方法也是如法炮制

 i开头的版本,也就是增强赋值运算这部分的方法,执行运算兼赋值的操作,也就是s1+=s2等于s1.__iadd__(s2)

如果增强赋值运算符的左侧对象没有实现相应的魔法方法,比如+=的左侧的对象没有实现__iadd__方法,那么python就会退而求其次,使用相应的__add__方法和__radd__方法来替代

 

这里的s2+=s2 不应该是计算两者的字符总个数吗,毕竟我们在s2里面有定义radd:

因为要成功调用radd方法是有条件的,首先它们两个要基于不同的类,这里s2和s2是相同的类,所有它自然不会去调用radd方法,而是去str这个父类里面查找add 方法,得到的就是字符串的拼接

魔法方法不仅能拦截运算法,也可以拦截发生在对象的内置函数 ,比如int()函数

位运算知识

常见的位运算有按位与、按位或、按位非、按位异或。按位与或非和and\or\not的执行逻辑是类似,只是所应用的场景不同。按位与或非运算符是对两个整数进行位运算

bin()函数:获取整数的二进制形式

 

 优先级:在同一个表达式里,按位或、按位异或、按位与、移位,优先级是依次递增的,按位非也就是按位取反,与正号负号处于同一优先级行列

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值