简体   繁体   English

Python:如何显示嵌套类型信息?

[英]Python: how to display nested type information?

Does Python inclue a built-in type variant that will display nested type information, something like this? Python 是否包含将显示嵌套类型信息的内置类型变体,像这样?

>>> extended_type([()])
<class 'list' containg <class 'tuple'>>

No. Type hints and the typing module and PEP 585 provide a notation for this (namely list[tuple] or List[tuple] before Python 3.9), but these are only meant to be checked by an external type-checker like MyPy;不可以。类型提示和typing模块以及 PEP 585 为此提供了一个表示法(即 Python 3.9 之前的list[tuple]List[tuple] ),但这些只能由像 MyPy 这样的外部类型检查器进行检查; there's no capability for checking it at runtime.没有在运行时检查它的能力。

PEP 585 on Making isinstance(obj, list[str]) perform a runtime type check : PEP 585 on Making isinstance(obj, list[str]) 执行运行时类型检查

This functionality requires iterating over the collection which is a destructive operation in some of them.此功能需要迭代集合,这在其中一些是破坏性操作。 This functionality would have been useful, however implementing the type checker within Python that would deal with complex types, nested type checking, type variables, string forward references, and so on is out of scope for this PEP.这个功能本来很有用,但是在 Python 中实现类型检查器来处理复杂类型、嵌套类型检查、类型变量、字符串前向引用等超出了这个 PEP 的范围。

The type of a container's items are opaque to the type of the container itself.容器项目的类型对于容器本身的类型是不透明的。 However, you can make your own for things that implement __iter__ :但是,您可以为实现__iter__东西制作自己的东西:

def extended_type(x):
    types = set()
    if hasattr(x, "__iter__"):
        for item in x:
            if item == x:
                # prevent strings from infinitely recursing
                continue
            types.add(extended_type(item))
        contains = ""
        if len(types) > 0:
            contains = " containing " + ", ".join(types)
        return f"<class '{type(x).__name__}'{contains}>"
    return f"<class '{type(x).__name__}'>"

extended_type([(1, 2, 'a'), {1: 2}])
# "<class 'list' containing <class 'tuple' containing <class 'str'>, <class 'int'>>, <class 'dict' containing <class 'int'>>>"

@Aplet123 inspires me. @Aplet123 启发了我。

from typing import List
import json


def extended_type(obj, buffer_list: List = None):
    if buffer_list is None:
        buffer_list = []
    buffer_list.append(f"<class '{type(obj).__name__}'>")
    if hasattr(obj, '__iter__') and not isinstance(obj, str):
        sub_buf = []
        for item in (obj.values() if isinstance(obj, dict) else obj):
            extended_type(item, sub_buf)
        if sub_buf:
            buffer_list.append(sub_buf)
    return buffer_list

test测试

def my_func():
    ...


class CC:
    ...


data_type_info: List = extended_type([(1, 'a'),
                                      [1, [2, '5', [2, 'a', CC()]]],
                                      {'a': 0, 1: 2, 'b': 's', 'l': [3, 'four']},
                                      my_func])

result: str = json.dumps(data_type_info, indent=2, sort_keys=True)
print(result)

output输出

[
    "<class 'list'>",
    [
        "<class 'tuple'>",
        [
            "<class 'int'>",
            "<class 'str'>"
        ],
        "<class 'list'>",
        [
            "<class 'int'>",
            "<class 'list'>",
            [
                "<class 'int'>",
                "<class 'str'>",
                "<class 'list'>",
                [
                    "<class 'int'>",
                    "<class 'str'>",
                    "<class 'CC'>"
                ]
            ]
        ],
        "<class 'dict'>",
        [
            "<class 'int'>",
            "<class 'int'>",
            "<class 'str'>",
            "<class 'list'>",
            [
                "<class 'int'>",
                "<class 'str'>"
            ]
        ],
        "<class 'function'>"
    ]
]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM