构造和析构
__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__不需要返回值