魔法方法总是被”__“包围,是Python面向对象的一切,魔法方法能够在适当的时候自动被调用
init方法:
class Rectangle():
# init方法的返回值一定是None
# 在需要传入参数时调用__init__方法
def __init__(self, x, y):
# 左边是类实例对象的局部变量,右边是传入的参数
self.x = x
self.y = y
def getPeri(self):
return (self.x + self.y) *2
rect = Rectangle(3, 4)
print(rect.getPeri())
new方法:
class CapStr(str):
# 继承不可改变类型的类
# 由于其自身不可改变,所以不可修改
# 所以需要重写new
def __new__(cls, string):
string = string.upper()
return str.__new__(cls, string)
a = CapStr('i love You')
print(a)
del方法:
class C:
def __init__(self):
print('我是init方法,我被调用了')
# 不是只会在del变量时才会引用,只要有引用,就不会调用
def __del__(self):
print('我是del方法,我被调用了')
c = C()
工厂函数:
print(type(len))
print(type(int))
class C:
pass
print(type(C))
class New_int(int):
# 当调用加法时,返回减法
def __add__(self, other):
return int.__sub__(self, other)
# 当调用减法时,返回加法
def __sub__(self, other):
return int.__add__(self, other)
a = New_int(3)
b = New_int(5)
print(a + b)
反运算:
class Nint(int):
def __radd__(self, other):
# 在重写反运算时注意顺序问题
return int.__sub__(self, other)
a = Nint(5)
b = Nint(3)
print(a + b)
print(1 + b)
简单计时器(案例):
import time
class MyTimer():
# 重写魔法方法
def __init__(self):
self.unit = ['年','月','日','小时','分钟','秒']
self.prompt = '未开始计时'
self.lasted = []
self.begin = 0
self.end = 0
def __str__(self):
return self.prompt
__repr__ = __str__
def __add__(self, other):
prompt = '总共运行了'
result = []
for index in range(6):
result.append(self.lasted[index] + other.lasted[index])
if result[index]:
prompt += (str(result[index]) + self.unit[index])
return prompt
# 开始计时
def start(self):
self.begin = time.localtime()
self.prompt = '请先停止计时'
print('开始计时')
def stop(self):
if not self.begin:
print('请先开始计时')
else:
self.end = time.localtime()
self._calc()
print('计时停止')
# 内部方法,计算运行时间
def _calc(self):
self.lasted = []
self.prompt = '总共运行了'
for index in range(6):
self.lasted.append(self.end[index] - self.begin[index])
if self.lasted[index]:
self.prompt += str(self.lasted[index]) + self.unit[index]
print(self.prompt)
property
class C:
def __init__(self, size = 10):
self.size = size
def getSize(self):
return self.size
def setSize(self, size):
self.size = size
def delSize(self):
del self.size
x = property(getSize, setSize, delSize)
c = C
c.x = 1
c.x
1
del c.x
属性访问:
class C:
def __getattribute__(self, name):
# 定义当用户获取一个不存在的属性时的行为(相比较getattr来说,getattribute会优先访问)
print('属性被访问_getattribute')
return super().__getattribute__(name)
def __getattr__(self, item):
# 定义当该类的属性被访问时的行为
print('属性被访问_getattr')
def __setattr__(self, name, value):
# 定义当一个属性被设置时的行为
print('属性被修改')
super().__setattr__(name, value)
def __delattr__(self, name):
# 定义当一个属性被删除时的行为
print('属性被删除')
super().__delattr__(name)