原视频链接:https://search.bilibili.com/all?keyword=BV1xs411Q799&from_source=nav_search_new
040 类和对象:一些相关的BIF
class A:
pass
class B(A):
pass
print(issubclass(B, A))
print(issubclass(B, B))
print(issubclass(B, object))
# Ture True True
# issubclass(class, classinfo)
# 判断class是否为classinfo的子类
# 类可以认为是自身的子类,object是所有类的基类
b1 = B()
print(isinstance(b1, B))
print(isinstance(b1, A))
print(isinstance(b1, (A, B)))
# True True True
# isinstance(object, classinfo)
# 检查一个实例对象是否在类里面
# 若第一个参数不是对象,则永远返回false
# 若第二个参数不是类或者元组,TypeError
# B为A的子类,所以B的实例化对象也包含于A
class C:
def __init__(self, x = 0):
self.x = x
c = C()
print(hasattr(c, 'x'))
# True 判断c这个object中是否有x这个属性。注意,属性名要为字符串形式
print(getattr(c, 'x'))
# 0
print(getattr(c, 'y', 'Cannot find'))
# Cannot find 若找不到y,啧用后面的default回复
property(fget = None, fset = None, fdel = None, doc = None)
class C:
def __init__(self, size = 10):
self.size = size
def getSize(self):
return self.size
def setSize(self, value):
self.size = value
def deleSize(self):
del self.size
x = property(getSize, setSize, deleSize)
c = C()
print(c.x) # 10
c.x = 18
print(c.size) # 18
del c.x
print(c.x) # 'C' object has no attribute 'size'
041魔法方法:构造和折构
所谓的魔法方法,其实就是被双下划线包裹的方法,总会在需要时被自动调用( __init__
)
实例化时被调用的第一个方法并不是__init__
而是__new__
new在内存给对象开盘储存空间地址,init初始化对象属性
class CapStr(str):
def __new__(cls, string):
string = string.upper()
return str.__new__(cls, string)
a = CapStr('I love hello world')
print(a)
# I LOVE HELLO WORLD
# 由于这个类是继承于str这一不可改变的父类,所以如果需要有多的操作就需要重写new而不是修改父类
class C:
def __init__(self):
print('I\'m __init__')
def __del__(self):
print('I\'m __del__')
c = C()
# I'm __init__
# I'm __del__
042 魔法方法:算术运算
工厂函数:类对象
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(5)
b = New_int(8)
print(a + b)
# -3
# 这里得出-3的原因是,在New_int中重新定义了内置方法__add__和__sub__
043 魔法方法:算术运算 2
魔法方法详解:fishc
class int(int):
def __add__(self, other):
return int.__sub__(self, other)
a = int('5')
b = int('3')
print(a + b)
# 2 保留了int()基础功能的同时,把BIF按自己的想法修改
class Nint(int):
def __radd__(self, other):
return int.__sub__(self,other)
a = Nint(5)
b = Nint(3)
print(a + b)
print(1 + b)
# 8 由于a有自己的add方法,所以不会调用radd,正常加法5+3=8
# 2 b调用radd,self为自己(3),other为1,3-1=2
044 魔法方法:简单定制
045 魔法方法:属性访问
class C:
def __getattribute__(self, name):
print("getattribute")
return super().__getattribute__(name)
def __getattr__(self, name):
print("getattr")
def __setattr__(self, name, value):
print("setattr")
return super().__setattr__(name, value)
def __delattr__(self, name):
print("delattr")
return super().__delattr__(name)
c = C()
c.x
# getattribute
# getattr
# 由此可见,当运行c.x时,首先运行__getattribut__(定义当该类属性被访问时的行为)
# 然后,由于此属性不存在,所以就到了__getattr__(定义当用户试图获取一个不存在属性的行为)
c.x = 1
# setattr
# c.x = 1 设置了属性,运行setattr
del c.x
# delattr
# 属性被删除,运行delattr
class Square:
def __init__(self, width = 0, height = 0):
self.width = width
self.height = height
def __setattr__(self, name, value):
if name == 'square':
self.width = value
self.height = value
else:
return super().__setattr__(name, value)
def getArea(self):
print(self.width * self.height)
r1 = Square(4, 6)
r1.getArea()
# 24
r1.square = 10
print(r1.width, r1.height)
r1.getArea()
# 10, 10, 100
# r1.square = 10: 自动调用__setattr__,name = square, value = 10。所以value = height = width = 10
print(r1.__dict__)
# {'width': 10, 'height': 10}
046 魔法方法:描述符(Property的原理)
描述符:将某种特殊类型的类的实例指派给另一个类的属性
后续视频都是偏工程类,我就没有在小甲鱼视频里学习了,个人笔记到此结束