# 8.9. `types` - 内建类型的动态类型创建和名称

源代码： Lib / types.py

该模块定义了效用函数以帮助动态创建新类型。

它还定义了标准Python解释器使用的某些对象类型的名称，但不作为`int`或`str`的内置码公开。

最后，它提供了一些额外的类型相关的实用程序类和函数，这些类和函数对于内置函数不够重要。

## 8.9.1。动态类型创建

`types.``new_class`(name, bases=(), kwds=None, exec_body=None)

  使用适当的元类动态创建类对象。

  前三个参数是组成类定义头的组件：类名，基类（按顺序），关键字参数（例如`metaclass`）。

  exec_body参数是一个回调，用于填充新创建的类命名空间。它应该接受类命名空间作为其唯一的参数，并直接用类内容更新命名空间。如果未提供回调，则与传递`lambda ns： ns`具有相同的效果。

  版本3.3中的新功能。

`types.``prepare_class`(name, bases=(), kwds=None)

  计算适当的元类并创建类命名空间。

  参数是构成类定义头的组件：类名，基类（按顺序）和关键字参数（例如`metaclass`）。

  返回值是一个三元组：`元类， 命名空间， kwds`

  元类是适当的元类，命名空间是准备的类命名空间，kwds是kwds t3 >任何`'metaclass'`条目的参数。如果没有传递kwds参数，这将是一个空的dict。

  版本3.3中的新功能。

也可以看看

Customizing class creation
  这些函数支持的类创建过程的完整详细信息
PEP 3115 - Python 3000中的元类
  引入了`__prepare__`命名空间钩子

## 8.9.2.标准解释器类型

此模块提供了实现Python解释器所需的许多类型的名称。它有意避免包括在处理期间偶然出现的一些类型，例如`listiterator`类型。

这些名称的典型用法是`isinstance()`或`issubclass()`检查。

标准名称为以下类型定义：

`types.``FunctionType`
`types.``LambdaType`

  由`lambda`表达式创建的用户定义函数和函数的类型。

`types.``GeneratorType`

  由生成器函数创建的generator - 类型对象。

`types.``CoroutineType`

  由`async def`函数创建的coroutine对象的类型。

  版本3.5中的新功能。

`types.``CodeType`

  由`compile()`返回的代码对象的类型。

`types.``MethodType`

  methodtype

`types.``BuiltinFunctionType`
`types.``BuiltinMethodType`

  内建函数的类型如`len()`或`sys.exit()`，以及内建类的方法。（这里，“内建”的意思是“用C写的”。）

class `types.``ModuleType`(name, doc=None)

  modules。构造函数采用要创建的模块的名称，并且可选择其docstring。

  注意

  如果要设置各种导入控制的属性，请使用`importlib.util.module_from_spec()`创建一个新模块。

  `__doc__`

    模块的docstring。默认为`None`。

  `__loader__`

    加载模块的loader。默认为`None`。

    在版本3.4中更改：默认为`None`。以前的属性是可选的。

  `__name__`

    模块的名称。

  `__package__`

    模块所属的package。如果模块是顶级（即，不是任何特定包的一部分），那么该属性应设置为`''`，否则应设置为包的名称（如果`__name__`模块是一个包本身）。默认为`None`。

    在版本3.4中更改：默认为`None`。以前的属性是可选的。

`types.``TracebackType`

  跟踪对象的类型，例如在`sys.exc_info()[2]`中找到。

`types.``FrameType`

  如`tb.tb_frame`如果`tb`中找到的帧对象类型是跟踪对象。

`types.``GetSetDescriptorType`

  在扩展模块中使用`PyGetSetDef`定义的对象类型，例如`FrameType.f_locals`或`array.array.typecode`。此类型用作对象属性的描述器；它具有与`property`类型相同的目的，但是对于在扩展模块中定义的类。

`types.``MemberDescriptorType`

  在扩展模块中使用`PyMemberDef`定义的对象类型，例如`datetime.timedelta.days`。此类型用作描述器，用于使用标准转换函数的简单C数据成员；它具有与`property`类型相同的目的，但是对于在扩展模块中定义的类。

  CPython实现细节：在Python的其他实现中，此类型可能与`GetSetDescriptorType`相同。

class `types.``MappingProxyType`(mapping)

  只读代理映射。它提供了对映射条目的动态视图，这意味着当映射更改时，视图反映这些更改。

  版本3.3中的新功能。

  `key in proxy`

    如果底层映射具有键键，则返回`True`，否则`False`。

  `proxy[key]`

    使用键键返回底层映射的项。引发`KeyError`如果键不在底层映射中。

  `iter(proxy)`

    在底层映射的键上返回一个迭代器。这是`iter(proxy.keys())`的快捷方式。

  `len(proxy)`

    返回底层映射中的项目数。

  `copy`()

    返回底层映射的浅层副本。

  `get`(key[, default])

    如果键在底层映射中，则返回键的值，否则默认。如果未指定默认，则默认为`None`，因此此方法从不引用`KeyError`。

  `items`()

    返回底层映射项目的新视图（`（键， 值）`对）。

  `keys`()

    返回底层映射键的新视图。

  `values`()

    返回底层映射值的新视图。

## 8.9.3.附加实用程序类和函数

class `types.``SimpleNamespace`

  一个简单的`object`子类，提供对其命名空间的属性访问，以及一个有意义的repr。

  与`object`不同，使用`SimpleNamespace`可以添加和删除属性。如果使用关键字参数初始化一个`SimpleNamespace`对象，那么它们将直接添加到底层命名空间。

  类型大致相当于以下代码：

      class SimpleNamespace:
          def __init__(self, **kwargs):
              self.__dict__.update(kwargs)

          def __repr__(self):
              keys = sorted(self.__dict__)
              items = ("{}={!r}".format(k, self.__dict__[k]) for k in keys)
              return "{}({})".format(type(self).__name__, ", ".join(items))

          def __eq__(self, other):
              return self.__dict__ == other.__dict__

  `SimpleNamespace`可能有助于替代`类 NS： pass`。但是，对于结构化记录类型，请改用`namedtuple()`。

  版本3.3中的新功能。

`types.``DynamicClassAttribute`(fget=None, fset=None, fdel=None, doc=None)

  将类的路由属性访问权限授予__getattr__。

  这是一个描述器，用于定义通过实例和类访问时不同行为的属性。实例访问保持正常，但通过类访问属性将被路由到类的__getattr__方法；这是通过提高AttributeError来完成的。

  这允许在实例上具有活动的属性，并且在类上具有相同名称的虚拟属性（参见示例的枚举）。

  版本3.4中的新功能。

## 8.9.4.协程效用函数

`types.``coroutine`(gen_func)

  此函数将generator函数转换为coroutine function，返回基于生成器的协程。基于生成器的协程仍然是generator iterator，但也被认为是coroutine对象并且awaitable。但是，它可能不一定实现`__await__()`方法。

  如果gen_func是生成器函数，它将被原地修改。

  如果gen_func不是生成器函数，它将被包装。如果它返回一个实例`collections.abc.Generator`，实例将被包装在一个等待代理对象中。所有其他类型的对象将按原样返回。

  版本3.5中的新功能。