面向对象高级

目录

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. 反射

  • 反射就是通过字符串来操作类或者对象的属性

  • 反射本质就是在使用内置函数,共有四个内置函数:

    1. hasattr:判断一个方法是否存在这个类中

    2. getattr:根据字符串去获取obj里的对应方法的内存地址,加()就能运

    3. setattr:将外部函数或者属性绑定到实例中

    4. 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__被触发了
上一篇:P1583 魔法照片


下一篇:「JOI 2018 Final」毒蛇越狱