types — 內建型別的動態型別建立和命名

原始碼: Lib/types.py


此模組定義了用於輔助動態建立新型別的實用函式。

它還定義了標準 Python 直譯器使用但未作為 intstr 等內建型別公開的一些物件型別的名稱。

最後,它提供了一些額外的與型別相關的實用類和函式,這些類和函式不夠基礎,無法成為內建型別。

動態型別建立

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

使用適當的元類動態建立一個類物件。

前三個引數是構成類定義頭部的元件:類名、基類(按順序)和關鍵字引數(例如 metaclass)。

exec_body 引數是一個回撥函式,用於填充新建立的類名稱空間。它應該接受類名稱空間作為其唯一引數,並直接使用類內容更新名稱空間。如果沒有提供回撥函式,則效果與傳入 lambda ns: None 相同。

在 3.3 版本加入。

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

計算適當的元類並建立類名稱空間。

引數是構成類定義頭部的元件:類名、基類(按順序)和關鍵字引數(例如 metaclass)。

返回值為一個 3 元組:metaclass, namespace, kwds

metaclass 是適當的元類,namespace 是準備好的類名稱空間,而 kwds 是傳入的 kwds 引數的更新副本,其中刪除了任何 'metaclass' 條目。如果沒有傳入 kwds 引數,則這將是一個空字典。

在 3.3 版本加入。

3.6 版本發生變化: 返回元組的 namespace 元素的預設值已更改。現在當元類沒有 __prepare__ 方法時,使用保留插入順序的對映。

參見

元類

這些函式支援的類建立過程的完整詳細資訊

PEP 3115 - Python 3000 中的元類

引入了 __prepare__ 名稱空間鉤子

types.resolve_bases(bases)

根據 PEP 560 的規定動態解析 MRO 條目。

此函式查詢 bases 中不是 type 例項的項,並返回一個元組,其中每個具有 __mro_entries__() 方法的物件都替換為呼叫此方法解包的結果。如果 bases 項是 type 的例項,或者它沒有 __mro_entries__() 方法,則它將原樣包含在返回的元組中。

在 3.7 版本加入。

types.get_original_bases(cls, /)

返回最初作為 cls 的基類提供的物件元組,在此之前任何基類都沒有呼叫 __mro_entries__() 方法(遵循 PEP 560 中規定的機制)。這對於自省 泛型 很有用。

對於具有 __orig_bases__ 屬性的類,此函式返回 cls.__orig_bases__ 的值。對於沒有 __orig_bases__ 屬性的類,則返回 cls.__bases__

示例:

from typing import TypeVar, Generic, NamedTuple, TypedDict

T = TypeVar("T")
class Foo(Generic[T]): ...
class Bar(Foo[int], float): ...
class Baz(list[str]): ...
Eggs = NamedTuple("Eggs", [("a", int), ("b", str)])
Spam = TypedDict("Spam", {"a": int, "b": str})

assert Bar.__bases__ == (Foo, float)
assert get_original_bases(Bar) == (Foo[int], float)

assert Baz.__bases__ == (list,)
assert get_original_bases(Baz) == (list[str],)

assert Eggs.__bases__ == (tuple,)
assert get_original_bases(Eggs) == (NamedTuple,)

assert Spam.__bases__ == (dict,)
assert get_original_bases(Spam) == (TypedDict,)

assert int.__bases__ == (object,)
assert get_original_bases(int) == (object,)

3.12 新版功能.

參見

PEP 560 - 對型別模組和泛型型別的核心支援

標準直譯器型別

此模組為實現 Python 直譯器所需的許多型別提供了名稱。它特意避免包含一些在處理過程中偶然出現的型別,例如 listiterator 型別。

這些名稱的典型用法是用於 isinstance()issubclass() 檢查。

如果您例項化任何這些型別,請注意簽名可能在 Python 版本之間有所不同。

為以下型別定義了標準名稱

types.NoneType

None 的型別。

在 3.10 版本加入。

types.FunctionType
types.LambdaType

使用者定義函式和由 lambda 表示式建立的函式的型別。

引發 審計事件 function.__new__,引數為 code

審計事件僅在直接例項化函式物件時發生,而不會在正常編譯時引發。

types.GeneratorType

由生成器函式建立的 生成器-迭代器物件的型別。

types.CoroutineType

async def 函式建立的 協程 物件的型別。

在 3.5 版本加入。

types.AsyncGeneratorType

由非同步生成器函式建立的 非同步生成器-迭代器物件的型別。

在 3.6 版本加入。

class types.CodeType(**kwargs)

程式碼物件 的型別,例如由 compile() 返回的程式碼物件。

引發 審計事件 code.__new__,引數為 code, filename, name, argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize, flags

請注意,審計的引數可能與初始化器所需的名稱或位置不匹配。審計事件僅在直接例項化程式碼物件時發生,而不會在正常編譯時引發。

types.CellType

單元格物件的型別:此類物件用作函式的 閉包變數 的容器。

在 3.8 版本加入。

types.MethodType

使用者定義類例項的方法的型別。

types.BuiltinFunctionType
types.BuiltinMethodType

len()sys.exit() 這樣的內建函式的型別,以及內建類的方法。(這裡,“內建”指的是“用 C 語言編寫”)。

types.WrapperDescriptorType

某些內建資料型別和基類(例如 object.__init__()object.__lt__())的方法的型別。

在 3.7 版本加入。

types.MethodWrapperType

某些內建資料型別和基類的 *繫結* 方法的型別。例如,它是 object().__str__ 的型別。

在 3.7 版本加入。

types.NotImplementedType

NotImplemented 的型別。

在 3.10 版本加入。

types.MethodDescriptorType

某些內建資料型別的方法的型別,例如 str.join()

在 3.7 版本加入。

types.ClassMethodDescriptorType

某些內建資料型別的 *未繫結* 類方法的型別,例如 dict.__dict__['fromkeys']

在 3.7 版本加入。

class types.ModuleType(name, doc=None)

模組 的型別。建構函式接受要建立的模組的名稱和可選的 文件字串

參見

模組物件文件

提供了 ModuleType 例項上可找到的特殊屬性的詳細資訊。

importlib.util.module_from_spec()

使用 ModuleType 建構函式建立的模組,其許多特殊屬性未設定或設定為預設值。module_from_spec() 提供了一種更可靠的方法來建立 ModuleType 例項,確保各種屬性都設定得當。

types.EllipsisType

Ellipsis 的型別。

在 3.10 版本加入。

class types.GenericAlias(t_origin, t_args)

引數化泛型 的型別,例如 list[int]

t_origin 應該是一個非引數化的泛型類,例如 listtupledictt_args 應該是一個 tuple(可能長度為 1)的型別,這些型別對 t_origin 進行引數化。

>>> from types import GenericAlias

>>> list[int] == GenericAlias(list, (int,))
True
>>> dict[str, int] == GenericAlias(dict, (str, int))
True

在 3.9 版本中新增。

3.9.2 版本發生變化: 此型別現在可以被子類化。

參見

泛型別名型別

有關 types.GenericAlias 例項的深入文件

PEP 585 - 標準集合中的型別提示泛型

引入 types.GenericAlias

class types.UnionType

聯合型別表示式 的型別。

在 3.10 版本加入。

3.14 版本發生變化: 這現在是 typing.Union 的別名。

class types.TracebackType(tb_next, tb_frame, tb_lasti, tb_lineno)

回溯物件的型別,例如在 sys.exception().__traceback__ 中找到的型別。

有關可用屬性和操作的詳細資訊以及動態建立回溯的指南,請參見語言參考

types.FrameType

幀物件 的型別,例如如果 tb 是一個回溯物件,則在 tb.tb_frame 中找到的型別。

types.GetSetDescriptorType

在擴充套件模組中用 PyGetSetDef 定義的物件的型別,例如 FrameType.f_localsarray.array.typecode。此型別用作物件屬性的描述符;它具有與 property 型別相同的目的,但適用於在擴充套件模組中定義的類。

types.MemberDescriptorType

在擴充套件模組中用 PyMemberDef 定義的物件的型別,例如 datetime.timedelta.days。此型別用作使用標準轉換函式的簡單 C 資料成員的描述符;它具有與 property 型別相同的目的,但適用於在擴充套件模組中定義的類。

此外,當使用 __slots__ 屬性定義類時,對於每個槽位,一個 MemberDescriptorType 例項將作為類的屬性新增。這允許槽位出現在類的 __dict__ 中。

CPython 實現細節: 在 Python 的其他實現中,此型別可能與 GetSetDescriptorType 相同。

class types.MappingProxyType(mapping)

對映的只讀代理。它提供了一個對映條目的動態檢視,這意味著當對映更改時,檢視會反映這些更改。

在 3.3 版本加入。

3.9 版本發生變化: 已更新以支援 PEP 584 中的新聯合 (|) 運算子,它只是委託給底層對映。

key in proxy

如果底層對映包含鍵 key,則返回 True,否則返回 False

proxy[key]

返回底層對映中鍵為 key 的項。如果 key 不在底層對映中,則引發 KeyError

iter(proxy)

返回底層對映鍵的迭代器。這是 iter(proxy.keys()) 的快捷方式。

len(proxy)

返回底層對映中的項數。

copy()

返回底層對映的淺複製。

get(key[, default])

如果 key 在底層對映中,則返回 key 對應的值,否則返回 default。如果未給出 default,則預設為 None,因此此方法永遠不會引發 KeyError

items()

返回底層對映項((key, value) 對)的新檢視。

keys()

返回底層對映鍵的新檢視。

values()

返回底層對映值的新檢視。

reversed(proxy)

返回底層對映鍵的反向迭代器。

在 3.9 版本中新增。

hash(proxy)

返回底層對映的雜湊值。

3.12 新版功能.

class types.CapsuleType

膠囊物件 的型別。

在 3.13 版本加入。

額外的實用類和函式

class types.SimpleNamespace

object 的一個簡單子類,提供對其名稱空間的屬性訪問,以及有意義的 repr。

object 不同,使用 SimpleNamespace 可以新增和刪除屬性。

SimpleNamespace 物件可以像 dict 一樣初始化:既可以透過關鍵字引數,也可以透過單個位置引數,或者兩者兼有。當使用關鍵字引數初始化時,這些引數會直接新增到底層名稱空間。或者,當使用位置引數初始化時,底層名稱空間將使用該引數中的鍵值對進行更新(可以是對映物件或生成鍵值對的 可迭代 物件)。所有此類鍵都必須是字串。

該型別大致等同於以下程式碼

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

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

    def __eq__(self, other):
        if isinstance(self, SimpleNamespace) and isinstance(other, SimpleNamespace):
           return self.__dict__ == other.__dict__
        return NotImplemented

SimpleNamespace 可用作 class NS: pass 的替代品。但是,對於結構化記錄型別,請改用 namedtuple()

SimpleNamespace 物件受 copy.replace() 支援。

在 3.3 版本加入。

3.9 版本發生變化: repr 中的屬性順序從字母順序更改為插入順序(如 dict)。

3.13 版本發生變化: 增加了對可選位置引數的支援。

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

將類上的屬性訪問路由到 __getattr__。

這是一個描述符,用於定義透過例項和透過類訪問時行為不同的屬性。例項訪問保持正常,但透過類訪問屬性將路由到類的 __getattr__ 方法;這是透過引發 AttributeError 來完成的。

這允許在例項上啟用屬性,並在類上具有相同名稱的虛擬屬性(請參閱 enum.Enum 獲取示例)。

在 3.4 版本加入。

協程實用函式

types.coroutine(gen_func)

此函式將 生成器 函式轉換為 協程函式,該函式返回一個基於生成器的協程。基於生成器的協程仍然是一個 生成器迭代器,但也被視為一個 協程 物件,並且是 可等待的。但是,它可能不一定實現 __await__() 方法。

如果 gen_func 是一個生成器函式,它將原地修改。

如果 gen_func 不是生成器函式,它將被包裝。如果它返回 collections.abc.Generator 的例項,該例項將被包裝在一個 *awaitable* 代理物件中。所有其他型別的物件將原樣返回。

在 3.5 版本加入。