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.

Comments powered by Disqus