类也是对象,创建类对象的类被称为元类
Python 默认的元类是 type,如果类在定义时没有定义__metaclass__
属性,同时其父辈类也没定义,那将使用 type 来创建这个类对象
type 的元类就是 type
# 类名,父类(可为空),绑定的成员
Test = type('Test',(),{'var':100})
test=Test()
print(type(test),type(Test),Test.var)
# 输出
# <class '__main__.Test'> <class 'type'> 100
Python中的抽象类
一种说法 java 中的接口是为了实现多继承,一个对象可以既是一种类型,也是另一种类型,而 java 只能从类中单继承,所有使用接口。Python 是可以多继承的,所以不需要接口。
但还是会有可能会用到抽象类,在【希望子类必须覆盖父类的某些成员】的时候。
创建抽象类
创建抽象类,其实就是指定类对象的元类为 ABCMeta。
from abc import ABC, ABCMeta
class ABClass():
__metaclass__=ABCMeta
@abc.absctractmethod
def func(self):
pass
# 等效于
class ABClass(metaclass=ABCMeta):
pass
@abc.absctractmethod
def func(self):
pass
# 等效于
class ABClass(ABC):
#ABC的metaclass就是ABCMeta,所以它的子类的metaclass也是ABCMeta
pass
@abc.absctractmethod
def func(self):
pass
实现抽象类
class Implementation(ABClass)
:集成自抽象类,子类必须实现抽象方法,否则无法实例化;仅定义不实例化不会报错
ABClass.register(Implementation)
:将类注册成抽象类的虚拟子类,不强制要求实现抽象类中的抽象方法,且该抽象类不会在实体类的 MRO 列表中
抽象类可以通过实现__subclasshook__(cls,C)
方法来替代 register 方法,__subclasshook__
必须被定义为@classmethod
# 实现__subclasshook__的类必须是抽象类
class MyIterable(ABC):
# __subclasshook__方法必须是类方法
@classmethod
def __subclasshook__(cls, C):
if cls is MyIterable:
if any("__iter__" in B.__dict__ for B in C.__mro__):
return True
return NotImplemented
issubclass() 函数在判断子类的情况下会去调用父类的__subclasshook__
方法
如果该方法返回 True,表示是子类,返回 False,表示不是子类,返回 NotImplemented,将使用传统的方法来判断是否是子类,也就是判断子类在定义时是否有集成自父类。
NotImplemented 大概是一个内建模块的对象,可以直接用,就像 True,False,None 这种
网友评论