Python面向对象之魔法方法
一、简介
python==3.7; 2020-04-12
python 类中,使用左右双下划线的预定义方法。当对对象做某种操作时,会触发魔法方法的调用, 是程序员与Python解释器交互的接口.
二、几个基本的魔法方法
class Constant():
def __new__(cls,*args, **kwargs):
print(f"__new__ 被调用 -- {cls}")
if not hasattr(cls, "is_instanced"):
cls.is_instanced = super(Constant, cls).__new__(cls)
return cls.is_instanced
def __init__(self, password):
print(f"__init__ 被调用 -- {self}")
self.password = password
constant = Constant("123456")
print(constant, Constant)
print(constant.password)
constant = Constant("111111")
print(constant, Constant)
print(constant.password)
__new__ 被调用 --
__init__ 被调用 -- <__main__.Constant object at 0x0000027CA719D908>
<__main__.Constant object at 0x0000027CA719D908>
123456
__new__ 被调用 --
__init__ 被调用 -- <__main__.Constant object at 0x0000027CA719D908>
<__main__.Constant object at 0x0000027CA719D908>
111111
class A():
def __init__(self):
print("init")
def close(self):
print("close")
def __del__(self):
print("析构函数被调用")
self.close()
a = A()
print("end")
init
析构函数被调用
close
end
class Fibonacci():
"""
斐波那契数列1
"""
def __call__(self, n):
self.a = 1
self.b = 1
self.c = 2
if n <= 2:
return 1
else:
for i in range(n-2):
self.c = self.a + self.b
self.a, self.b = self.b, self.c
return self.c
fibonacci = Fibonacci()
for i in range(1,11):
print(fibonacci(i), end = " ")
1 1 2 3 5 8 13 21 34 55
class Student():
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"name: {self.name}, age: {self.age}"
class Test():
name = "Test"
tesla = Student("Tesla", 18)
print(tesla)
temp = str(tesla) + f" --- {tesla}"
print(temp)
test = Test()
print(test)
name: Tesla, age: 18
name: Tesla, age: 18 --- name: Tesla, age: 18
<__main__.Test object at 0x0000027CA7657988>
class A():
"test doc"
name = "name"
a = A()
a.age = 18
print(a.__dict__, a.__doc__)
析构函数被调用
close
{'age': 18} test doc
三、 对象属性相关的魔法方法
class Constant():
def __getattr__(self, name):
print("getattr", name)
def __getattribute__(self, name):
print("getattribute")
return super().__getattribute__(name)
def __setattr__(self, name, value):
print("setattr: ", name, value)
super().__setattr__(name, value + "--赋值前做点处理")
def __delattr__(self, name):
print("delattr")
super().__delattr__(name)
constant = Constant()
constant.user = "Tesla"
print("打印 user: ", constant.user)
del constant.user
print("打印 user: ", constant.user)
setattr: user Tesla
getattribute
打印 user: Tesla--赋值前做点处理
delattr
getattribute
getattr user
打印 user: None
四、容器相关的魔法方法
class Fibonacci():
"""
Fibonacci2 生成、存储斐波那契数列
"""
def __init__(self, n=20, a=1, b=1):
self.length = n
self.list = [a,b]
self.i = 0
for each in range(n-2):
temp = a + b
a, b = b, temp
self.list.append(temp)
self.a = a
self.b = b
def __setitem__(self, key, value):
if key==0:
self.a = value
elif key==1:
self.b = value
else:
print("仅支持给index=0,1 赋值")
return None
a = self.a
b = self.b
self.list = [self.a, self.b]
for each in range(self.length-2):
temp = a + b
a, b = b, temp
self.list.append(temp)
def __getitem__(self, key):
if isinstance(key, int):
return self.list[key]
elif isinstance(key, slice):
start = key.start
stop = key.stop
step = key.step
return self.list[start:stop:step]
def __delitem__(self, key):
print("不支持del")
def __iter__(self):
return self
def __next__(self):
if 0 <= self.i < self.length:
temp = self.list[self.i]
self.i +=1
return temp
else:
self.i = 0
raise StopIteration
def __contains__(self, item):
return item in self.list
def __reversed__(self):
return self.list[::-1]
def __str__(self):
string = ""
for each in self.list:
string += f", {each}"
return string[2:]
def __len__(self):
return self.length
fibonacci = Fibonacci(10)
print(fibonacci)
fibonacci[0] = 1
fibonacci[1] = 2
fibonacci[2] = 3
del fibonacci[1]
print(fibonacci)
print("切片:", fibonacci[::-1])
a = sorted(fibonacci)
b = reversed(fibonacci)
print("sorted:", a)
print("reversed:", b)
print(2 in fibonacci)
print(2 not in fibonacci)
for each in fibonacci:
print(each)
1, 1, 2, 3, 5, 8, 13, 21, 34, 55
仅支持给index=0,1 赋值
不支持del
1, 2, 3, 5, 8, 13, 21, 34, 55, 89
切片: [89, 55, 34, 21, 13, 8, 5, 3, 2, 1]
sorted: [1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
reversed: [89, 55, 34, 21, 13, 8, 5, 3, 2, 1]
True
False
1
2
3
5
8
13
21
34
55
89
五、 算数操作相关的魔法方法
class Matrix():
"""矩阵简单运算"""
def __init__(self, value):
self.value = value
self.shape = (len(value),len(value[0]))
for each in value:
if len(each) != len(value[0]):
raise TypeError("类型错误")
def __add__(self, other):
if other.shape != self.shape:
raise TypeError("不同shape矩阵不能相加")
result = []
for i in range(self.shape[0]):
temp = []
if self.shape[0] > 0:
for j in range(self.shape[1]):
temp.append(self.value[i][j] + other.value[i][j])
else:
temp = self.value[i] + other.value[i]
result.append(temp)
return Matrix(result)
def __sub__(self, other):
if other.shape != self.shape:
raise TypeError("不同shape矩阵不能相加")
result = []
for i in range(self.shape[0]):
temp = []
if self.shape[1] > 0:
for j in range(self.shape[1]):
temp.append(self.value[i][j] - other.value[i][j])
else:
temp = self.value[i] - other.value[i]
result.append(temp)
return Matrix(result)
def __mul__(self, other):
print(other)
if other.shape != self.shape:
raise TypeError("不同shape矩阵不能相加")
result = []
add = 0
for i in range(self.shape[0]):
temp = []
if self.shape[1] > 0:
for j in range(self.shape[1]):
add2 = 0
for k in range(self.shape[1]):
add2 += (self.value[i][k] * other.value[k][j])
temp.append(add2)
result.append(temp)
else:
add += self.value[i] * other.value[i]
result = add if self.shape[1] <=0 else result
return Matrix(result)
def __str__(self):
string = ""
for each in self.value:
string += f"{each}\n"
return string
a = Matrix([[1,2],[3,4]])
b = Matrix([[1,1],[1,1]])
c = a + b
print(a,b)
print(c, type(c))
print(a - b)
print(a * b)
[1, 2]
[3, 4]
[1, 1]
[1, 1]
[2, 3]
[4, 5]
[0, 1]
[2, 3]
[1, 1]
[1, 1]
[3, 3]
[7, 7]