# 手动创建类
# 概述
我们可以使用types.new_class和type两种方式手动创建类,但是type相较于new_class的形式会忽略一些关键步骤,需要注意。
type接收三个参数:对象名、基类元组以及属性空间。
class type(object)
| type(object_or_name, bases, dict)
| type(object) -> the object's type
| type(name, bases, dict) -> a new type
types.new_class接收四个参数:对象名、基类元组、属性空间以及fn四个参数。
new_class(name, bases=(), kwds=None, exec_body=None)
Create a class object dynamically using the appropriate metaclass.
可以注意到types.new_class可以传入一个函数,这个函数可以接收到__prepare__的结果并接着处理,这是type所不行的。
此外,types还提供了types.prepare_class()来仅仅执行准备阶段,因此关于手动创建类的部分可以多多研究types模块。
import types
metaclass, kwargs, ns = types.prepare_class('Stock', (), {'metaclass': type})
# types.new_class
# 手动实现namedtuple
import operator import types import sys def named_tuple(classname, fieldnames): # Populate a dictionary of field property accessors cls_dict = { name: property(operator.itemgetter(n)) for n, name in enumerate(fieldnames) } # Make a __new__ function and add to the class dict def __new__(cls, *args): if len(args) != len(fieldnames): raise TypeError('Expected {} arguments'.format(len(fieldnames))) return tuple.__new__(cls, args) cls_dict['__new__'] = __new__ # Make the class cls = types.new_class(classname, (tuple,), {}, lambda ns: ns.update(cls_dict)) # Set the module to that of the caller cls.__module__ = sys._getframe(1).f_globals['__name__'] return cls """ >>> Point = named_tuple('Point', ['x', 'y']) >>> Point <class '__main__.Point'> >>> p = Point(4, 5) >>> len(p) 2 >>> p.x 4 >>> p.y 5 >>> p.x = 2 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: can't set attribute >>> print('%s %s' % p) 4 5 >>> """
# type
Stock = type('Stock', (), cls_dict)
← 元类概述 pickle:序列化和反序列化 →