1. isinstance,issubclass
1.1 isinstance与type
type是用来判断类型的,但是不会认为子类是父类的一种类型
isinstance也是用来判断对象类型,但是会认为子类是父类的一种类型
class A:
pass
class B(A):
pass
class C(B):
pass
c = C()
print(type(c) == C)
print(type(c) == A) # 不能找到父类
print('*'*50)
print(isinstance(c,C))
print(isinstance(c,A)) # 能找到父类
True
False
**************************************************
True
True
1.2 issubclass
判断是否是子类的
class A:
pass
class B(A):
pass
class C(B):
pass
print(issubclass(C,A))
True
2. 反射
-
反射就是通过字符串来操作类或者对象的属性
-
反射本质就是在使用内置函数,共有四个内置函数:
-
hasattr:判断一个方法是否存在这个类中
-
getattr:根据字符串去获取obj里的对应方法的内存地址,加()就能运
-
setattr:将外部函数或者属性绑定到实例中
-
delattr:删除一个实例或类的方法
-
class People():
country = 'china'
def __init__(self,name,age):
self.name = name
self.age = age
def eat(self):
print(f'{self.name} is eating')
peo = People('hades',27)
print(hasattr(peo,'eat'))
True
print(getattr(peo,'eat'))
getattr(peo,'eat')()
<bound method People.eat of <__main__.People object at 0x000002813096B710>>
hades is eating
print(peo.__dict__)
setattr(peo,'weight',120)
print(peo.__dict__)
{'name': 'hades', 'age': 27}
{'name': 'hades', 'age': 27, 'weight': 120}
delattr(peo,'age')
print(peo.__dict__)
{'name': 'hades', 'weight': 120}
3. __init__,__new__
我们首先得从__new__(cls[,...])的参数说说起,__new__方法的第一个参数是这个类,而其余的参数会在调用成功后全部传递给__init__方法初始化
所以,__new__
方法(第一个执行)先于__init__
方法执行:
class A:
def __new__(cls):
print('__new__被触发了')
obj = object.__new__(cls)
return obj # 必须返回
def __init__(self):
print('__init__被触发了')
a = A()
__new__被触发了
__init__被触发了
4. __call__
对象后面加括号时,就会触发__call__
方法
- 注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 call 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
class People():
country = 'china'
def __init__(self):
print('__init__被触发了')
def __call__(self):
print('__call__被触发了')
p = People()
__init__被触发了
p()
__call__被触发了