python ABC类
python的元类(metaclass)和虚基类(ABC)
使用方法:
class a:
def __init__(self, data):
self.data = data
def getd3(self):
return self.data * 3
class MyMeta(type):
def __new__(metaname, classname, baseclasses, attrs):
print('New called with')
print('metaname', metaname)
print('classname', classname)
print('baseclasses', baseclasses)
print('attrs', attrs)
attrs['getdata'] = a.__dict__['getd3']
# attrs['getdata'] = a.getd3
return type.__new__(metaname, classname, baseclasses, attrs)
def __init__(classobject, classname, baseclasses, attrs):
print('init called with')
print('classobject', classobject)
print('classname', classname)
print('baseclasses', baseclasses)
print('attrs', attrs)
# py2 和py3对metaclass工作方式不也一样, 以下是py3写法
class Kls(metaclass=MyMeta):
def __init__(self,data):
self.data = data
def printd(self):
print(self.data)
ik = Kls('arun')
ik.printd()
print(ik.getdata())
New called with metaname <class '__main__.MyMeta'> classname Kls baseclasses () attrs {'__module__': '__main__', '__qualname__': 'Kls', '__init__': <function Kls.__init__ at 0x11a4cc7b8>, 'printd': <function Kls.printd at 0x11a4f7f28>} init called with classobject <class '__main__.Kls'> classname Kls baseclasses () attrs {'__module__': '__main__', '__qualname__': 'Kls', '__init__': <function Kls.__init__ at 0x11a4cc7b8>, 'printd': <function Kls.printd at 0x11a4f7f28>, 'getdata': <function a.getd3 at 0x11a4ccea0>} arun arunarunarun
from abc import ABCMeta
# 构造元类
def with_metaclass(meta, *bases):
# This requires a bit of explanation: the basic idea is to make a
# dummy metaclass for one level of class instantiation that replaces
# itself with the actual metaclass. Because of internal type checks
# we also need to make sure that we downgrade the custom metaclass
# for one level to something closer to type (that's why __call__ and
# __init__ comes back from type etc.).
#
# This has the advantage over six.with_metaclass in that it does not
# introduce dummy classes into the final MRO.
class metaclass(meta):
__call__ = type.__call__
__init__ = type.__init__
def __new__(cls, name, this_bases, d):
if this_bases is None:
return type.__new__(cls, name, (), d)
return meta(name, bases, d)
return metaclass('temporary_class', None, {})
class MyList(with_metaclass(ABCMeta, )):
pass
MyList.register(list)
assert issubclass(list, MyList)
from abc import ABC
import collections
print(type(1))
<class 'int'>
print(collections.Set)
print(set.__class__)
print(set)
print(set.__doc__)
<class 'collections.abc.Set'> <class 'type'> <class 'set'> set() -> new empty set object set(iterable) -> new set object Build an unordered collection of unique elements.