目录
1基本的魔术方法
1.1__init__
- 语法:
__init__(self[, ...])
- 作用:
- 1 会在调用类时自动触发执行,用来为对象初始化自己独有的数据
- 2
__init__
内应该存放的是为对象初始化属性的功能,但是也可以存放其他代码,想要在类调用时就立刻执行 - 3
__init
方法必须返回对象
- 解释:当对象调用类时,
__init__(self[, ...])
会自动被触发,Python会自动将当前调用的空对象传给self
参数。 - 过程:
- 1 先产生一个空对象,调用类内的
__new__
方法 - 2 python会自动调用类中的
__init__
方法,然后将空对象和已经调用类时括号里传入的参数,一同传给__init__
- 3 返回初始化好的对象
- 1 先产生一个空对象,调用类内的
- 注意:
__init__(self[, ...])
不能返回什么值,返回的是None。
class Rec:
def __init__(self,x,y):
self.x=x
self.y=y
def getPeri(self):
return (self.x+self.y)*2
def getArea(self):
return self.x*self.y
rect=Rec(3,4) # 将rect这个对象传给self
print(rect.getPeri()) # 14
print(rect.getArea()) # 12
1.2__new__
- 语法:
__new__(cls[, ...])
__new__
至少要有一个参数cls
,代表要实例化的类,此参数在实例化时由 Python 解释器自动提供,后面的参数直接传递给__init__
。
- 过程:
__new__
对当前类进行了实例化,并将实例返回,传给__init__
的self
。- 但是,执行了
__new__
,并不一定会进入__init__
,只有__new__
返回了值,当前类cls
的实例,当前类的__init__
才会进入。
- 作用:构造方法。
__new__
是在一个对象实例化的时候所调用的第一个方法,在调用__init__
初始化前,先调用__new__
。
class A:
# 构造方法,创建一块对象的空间,有一个指针能指向类--》__new__
def __new__(cls, *args, **kwargs):
o=super().__new__(cls)
print('执行new',o)
return o
def __init__(self):
print('执行init',self)
A()
# 执行new <__main__.A object at 0x000001C29AD65F40>
# 执行init <__main__.A object at 0x000001C29AD65F40>
1.3__str__和__repr__
1__str__
- 当你打印一个对象的时候,触发
__str__
- 当你使用
%s
格式化的时候,触发__str__
str
强转数据类型的时候,触发__str__
2__repr__
repr
是str
的备胎- 有
__str__
的时候执行__str__
,没有实现__str__
的时候,执行__repr__
repr(obj)
内置函数对应的结果是__repr__
的返回值- 当你使用
%r
格式化的时候 触发__repr__
class p:
def __init__(self):
self.student=[]
def append(self,name):
self.student.append(name)
py22=p()
print(py22) # <__main__.p object at 0x00000252BC1A49D0>
py22.append('jaja')
print(py22) # <__main__.p object at 0x00000252BC1A49D0>
-------------------------------------
class p:
def __init__(self):
self.student=[]
def append(self,name):
self.student.append(name)
def __str__(self):
return str(self.student)
py22=p()
print(py22) # []
py22.append('jaja')
print(py22) # ['jaja']
1.4__del__
- 作用:析构器,当一个对象将要被系统回收时调用的方法
class C(object):
def __init__(self):
print('into C __init__')
def __del__(self):
print('into C __del__')
c1 = C()
# into C __init__
c2 = c1
c3 = c2
del c3
del c2
del c1
# into C __del__
2 魔法运算:算数运算
2.1__add__和__sub__
__add__(self,other)
:定义加法的行为__add__(self,other)
:定义减法的行为
class A(int):
def __add__(self, other):
return int.__add__(self,other)
def __sub__(self, other):
return int.__sub__(self, other)
a=A(2)
b=A(3)
print(a+b) # 5
print(a-b) # -1
2.2其他魔法方法
__mul__(self, other)
定义乘法的行为:*
__truediv__(self, other)
定义真除法的行为:/
__floordiv__(self, other)
定义整数除法的行为://
__mod__(self, other)
定义取模算法的行为:%
__divmod__(self, other)
定义当被divmod()
调用时的行为divmod(a, b)
把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b)
。
print(divmod(7, 2)) # (3, 1) print(divmod(8, 2)) # (4, 0)
__pow__(self, other[, module])
定义当被power()
调用或**
运算时的行为__lshift__(self, other)
定义按位左移位的行为:<<
__rshift__(self, other)
定义按位右移位的行为:>>
__and__(self, other)
定义按位与操作的行为:&
__xor__(self, other)
定义按位异或操作的行为:^
__or__(self, other)
定义按位或操作的行为:|
2.3反运算
反运算魔方方法,与算术运算符保持一一对应,不同之处就是反运算的魔法方法多了一个“r”。当文件左操作不支持相应的操作时被调用。
__radd__(self, other)
定义加法的行为:+
__rsub__(self, other)
定义减法的行为:-
__rmul__(self, other)
定义乘法的行为:*
__rtruediv__(self, other)
定义真除法的行为:/
__rfloordiv__(self, other)
定义整数除法的行为://
__rmod__(self, other)
定义取模算法的行为:%
__rdivmod__(self, other)
定义当被 divmod() 调用时的行为__rpow__(self, other[, module])
定义当被 power() 调用或**
运算时的行为__rlshift__(self, other)
定义按位左移位的行为:<<
__rrshift__(self, other)
定义按位右移位的行为:>>
__rand__(self, other)
定义按位与操作的行为:&
__rxor__(self, other)
定义按位异或操作的行为:^
__ror__(self, other)
定义按位或操作的行为:|
a + b
这里加数是a
,被加数是b
,因此是a
主动,反运算就是如果a
对象的__add__()
方法没有实现或者不支持相应的操作,那么 Python 就会调用b
的__radd__()
方法。
class Nint(int):
def __radd__(self, other):
return int.__sub__(other, self) # 注意 self 在后面
a = Nint(5)
b = Nint(3)
print(a + b) # 没有调用__radd__方法
# 8
print(1 + b) # 没有找到1的__add__方法,只找到b的__radd__方法
# -2
3增量赋值运算符
__iadd__(self, other)
定义赋值加法的行为:+=
__isub__(self, other)
定义赋值减法的行为:-=
__imul__(self, other)
定义赋值乘法的行为:*=
__itruediv__(self, other)
定义赋值真除法的行为:/=
__ifloordiv__(self, other)
定义赋值整数除法的行为://=
__imod__(self, other)
定义赋值取模算法的行为:%=
__ipow__(self, other[, modulo])
定义赋值幂运算的行为:**=
__ilshift__(self, other)
定义赋值按位左移位的行为:<<=
__irshift__(self, other)
定义赋值按位右移位的行为:>>=
__iand__(self, other)
定义赋值按位与操作的行为:&=
__ixor__(self, other)
定义赋值按位异或操作的行为:^=
__ior__(self, other)
定义赋值按位或操作的行为:|=
4一元运算符
__neg__(self)
定义正号的行为:+x
__pos__(self)
定义负号的行为:-x
__abs__(self)
定义当被abs()
调用时的行为__invert__(self)
定义按位求反的行为:~x
6 习题
1、上面提到了许多魔法方法,如__new__
,__init__
, __str__
,__rstr__
,__getitem__
,__setitem__
等等,请总结它们各自的使用方法。
__init__
:构造器,当一个实例被创建的时候调用的初始化方法__new__
:返回一个实例对象,__new__
方法返回类的实例对象,这个实例对象传给__int__
方法中定义的self
参数。若__new__
方法返回None
,则不会调用__init__
方法。__str__
:当你打印一个对象的时候,或者当你使用%s
格式化的时候,str
强转数据类型的时候,会触发__str__
。__rstr__
:反运算的魔法方法多了一个“r”。当文件左操作不支持相应的操作时被调用。__getitem__
:定义获取容器中元素的行为,相当于self[key]
__setitem__
:定义设置容器中指定元素的行为,相当于self[key] = value
。
2、利用python做一个简单的定时器类
要求:
- 定制一个计时器的类。
start
和stop
方法代表启动计时和停止计时。- 假设计时器对象
t1
,print(t1)
和直接调用t1
均显示结果。 - 当计时器未启动或已经停止计时时,调用
stop
方法会给予温馨的提示。 - 两个计时器对象可以进行相加:
t1+t2
。 - 只能使用提供的有限资源完成。
import time
class Mytime(object):
def __init__(self):
self.__info = '未开始计时!'
self.__begin = None
self.__end = None
self.__jg = 0
def __str__(self):
return self.__info
def __repr__(self):
return self.__info
def start(self):
print('计时开始...')
self.__begin = time.localtime()
def stop(self):
if not self.__begin:
print('提示:请先调用start()开始计时!')
return
self.__end = time.localtime()
self.__jg = time.mktime(self.__end) - time.mktime(self.__begin)
self.__info = '共运行了%d秒' % self.__jg
print('计时结束!')
return self.__jg
def __add__(self, other):
return '共运行了%d秒' % (other.__jg + self.__jg)