Python随记(15)__new__方法等 算数运算符 反运算

构造和析构

__init__(self) 给类强加属性的需要注意的是,__init_方法返回值一定是None。只有需要初始化的时候才重写_init_()方法

__new__(cls)方法

实际上__new__才是在一个对象实例化的时候调用的第一个方法。他的参数不是self,而是cls这个类,而其他的参数会直接传递给__init__()。_new_()方法需要返回一个实例化对象,通常是cls这个类的实例化对象,当然也可以是其他的。
一般不会去用它的,但是当继承了一个不可变的类型的时候,他的特性就很重要了。

class Astr(str):
	def __new__(cls,string):
		string = string.upper()
		return str.__new__(cls,string)
a=Astr('i love you')
a >>> I LOVE YOU

_del_(self)

init new 是对对象的构造的话,del就是析构器了。当对象要被销毁的时候,这个方法就会调用。但是要注意的是,并非 del x 就相当于自动调用 x._del_(),这个方法是当垃圾回收机制回收这个对象的时候调用的。

class A:
	def __del__(self):
		print("del 被调用了“)
a1=A()
a2=a1 ; a3=a2
del a1
del a2
del a3
》》del 被调用了

算数运算

工厂函数,其实int() float() str() list() tuple() 这些都是一个类对象。调用他们的时候就是创建了一个相应的实例对象。就像 a + b 就是将两个对象相加。

算术运算方法 含义
_add_(self,other) 加法行为
__sub__(self,other) 减法
__mul__(self.other) 乘法
__truediv__(self,other) 真除法(/)
_floordiv_(self,other) 地板除(//)
__mod__(self,ohter) 取模运算(%)
__divmod__(self,other) 定义当divmod()调用时的行为(a // b, a % b)
__pow__(selfl,other) 幂运算(**)
__lshift__(self,other) << 左位移
__rshift__(self,other) >>右位移
__and__(self,other) 与操作符 &
__xor__(self,other) 异或操作符 ^
__or__(self,other) 或操作
class New_int(int):
	def __add__(self,other):
		return int.__sub__(self,ohter)  #因为sub的方法被我们重写了,要使用减法行为就要使用父类 int 没被改写过的方法
	def __sub__(self,other):
		return int.__add__(self,ohter)
a=New_int(3)
b=New_int(5)
a + b >>>-2   #经过重写将加法变成了减法。。。。
a - b >>> 8

但是当自己改写的时候要小心的。def __add__(self,other): return self+other这就会发生无限递归。def __add__(self,other): return int(self) + int(other)这样就好了。当对象进行了相关的算数运算,自然而然的额就会触发对应的方法。

反运算

就是在算数运算前面加个‘ r’啦。。。
a + b a是主动的,反运算就是让b主动。当a 对象的__add__()方法没有实现或者不支持相应的操作,python就会调用b的 _add_()方法。

class New_int(int):
	def __radd__(self,other):
		return int.__add__(other,self)
a=New_int(5)
b=New_int(3)
a + b >>>8              #由于a对象有__add__()方法,所以b的__radd__()方法没有执行的
1 + b   >>> -2        #这样就有了

另外,对于 a + b 来说,b的__radd__方法self参数是b,other参数是a 。所以在重写反运算方法的时候要注意顺序的

一元操作符: _neg_()表示正号,,__pos_()负号,,__abs_()绝对值,,__invert__()按位取反

对__new__()的补充

总感觉少了点啥。。。。。
实例化对象是谁取决于__new__方法,__new__返回什么就是什么

class F1(object):
  #重写__new__方法,返回这个重写的__new__方法
    def __new__(cls, *args, **kwargs):
        return 123

obj=F1() #实例化对象是谁取决于__new__方法,__new__返回什么就是什么
print(obj,type(obj))  #打印结果:123 <class 'int'>


class F2(object):
    pass

class F3(object):
    def __new__(cls, *args, **kwargs):
        return F2()

obj=F3()    #实例化对象是谁取决于__new__方法,__new__返回什么就是什么
print(obj)  #<__main__.F2 object at 0x00000210119BA4A8>

如果要得到当前类的实例,应当在当前类中的 new() 方法语句中调用当前类的父类的 new() 方法。return object.__new__(cls)

  • __new__至少要有一个参数cls,代表要实例化的类,此参数在实例化时由Python解释器自动提供

  • __new__必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,可以return父类__new__出来的实例,或者直接是object的__new__出来的实例

  • __init__有一个参数self,就是这个__new__返回的实例,__init__在__new__的基础上可以完成一些其它初始化的动作,__init__不需要返回值

发布了25 篇原创文章 · 获赞 0 · 访问量 299

猜你喜欢

转载自blog.csdn.net/weixin_46192930/article/details/104974969
今日推荐