国产日韩精品视频_2020久久国产最新免费观看_国内久久久久影院精品_日本一区二区视频在线

使用從泛型類型派生的類的最佳方法是什么?

假設我們得到了一個通用類定義,例如:

from dataclasses import dataclass
from typing import TypeVar, Generic, List


T1 = TypeVar('T1')
T2 = TypeVar('T2')


@dataclass
class MyGenericClass(Generic[T1, T2]):
    val: T1
    results: List[T2]


@dataclass
class BaseClass:
    my_str: str


@dataclass
class MyTestClass(BaseClass, MyGenericClass[str, int]):
    ...

確定MyTestClass是泛型類(即與常規數據類相反)的最佳方法是什么?

此外,在這種情況下,typing模塊是否提供了將泛型類型(TypeVar)解析為具體類型關系的簡單方法?

例如,給定上面的results: List[T2],我想理解MyTestClass上下文中的T2將解析為int類型。

確定類是否為泛型

當前,如果運行set(vars(MyTestClass)) - set(vars(BaseClass)),將得到以下結果:

{'__parameters__', '__orig_bases__'}

然而,我想知道typing是否提供了一種簡單的方法來確定類是泛型還是來自泛型類的sub-classes,例如typing.Dict

所以我感興趣的是is_cls_generic()的效果。

解析TypeVar類型

目前,當我調用typing.get_type_hints(MyTestClass)時,我得到以下結果:

{'val': ~T1, 'results': typing.List[~T2], 'my_str': <class 'str'>}

我想知道typing模塊是否提供了一種簡單的方法來解析這些TypeVar變量,因此期望的結果是:

{'val': str, 'results': typing.List[int], 'my_str': str}
? 最佳回答:

Credits

Introspection helpers

mypy沒有提供您需要的功能,但手工實現并不太困難。

# introspection.py

# mypy issue 776
import sys
from typing import get_args, get_origin, get_type_hints, Generic, Protocol
from typing import _collect_type_vars, _eval_type, _strip_annotations

def _generic_mro(result, tp):
    origin = get_origin(tp)
    if origin is None:
        origin = tp
    result[origin] = tp
    if hasattr(origin, "__orig_bases__"):
        parameters = _collect_type_vars(origin.__orig_bases__)
        if origin is tp and parameters:
            result[origin] = origin[parameters]
        substitution = dict(zip(parameters, get_args(tp)))
        for base in origin.__orig_bases__:
            if get_origin(base) in result:
                continue
            base_parameters = getattr(base, "__parameters__", ())
            if base_parameters:
                base = base[tuple(substitution.get(p, p) for p in base_parameters)]
            _generic_mro(result, base)

def generic_mro(tp):
    origin = get_origin(tp)
    if origin is None and not hasattr(tp, "__orig_bases__"):
        if not isinstance(tp, type):
            raise TypeError(f"{tp!r} is not a type or a generic alias")
        return tp.__mro__
    # sentinel value to avoid to subscript Generic and Protocol
    result = {Generic: Generic, Protocol: Protocol}
    _generic_mro(result, tp)
    cls = origin if origin is not None else tp
    return tuple(result.get(sub_cls, sub_cls) for sub_cls in cls.__mro__)

def _class_annotations(cls, globalns, localns):
    hints = {}
    if globalns is None:
        base_globals = sys.modules[cls.__module__].__dict__
    else:
        base_globals = globalns
    for name, value in cls.__dict__.get("__annotations__", {}).items():
        if value is None:
            value = type(None)
        if isinstance(value, str):
            value = ForwardRef(value, is_argument=False)
        hints[name] = _eval_type(value, base_globals, localns)
    return hints


# For brevety of the example, the implementation just add the substitute_type_vars
# implementation and default to get_type_hints. Of course, it would have to be directly
# integrated into get_type_hints
def get_type_hints2(
    obj, globalns=None, localns=None, include_extras=False, substitute_type_vars=False
):
    if substitute_type_vars and (isinstance(obj, type) or isinstance(get_origin(obj), type)):
        hints = {}
        for base in reversed(generic_mro(obj)):
            origin = get_origin(base)
            if hasattr(origin, "__orig_bases__"):
                parameters = _collect_type_vars(origin.__orig_bases__)
                substitution = dict(zip(parameters, get_args(base)))
                annotations = _class_annotations(get_origin(base), globalns, localns)
                for name, tp in annotations.items():
                    if isinstance(tp, TypeVar):
                        hints[name] = substitution.get(tp, tp)
                    elif tp_params := getattr(tp, "__parameters__", ()):
                        hints[name] = tp[
                            tuple(substitution.get(p, p) for p in tp_params)
                        ]
                    else:
                        hints[name] = tp
            else:
                hints.update(_class_annotations(base, globalns, localns))
        return (
            hints
            if include_extras
            else {k: _strip_annotations(t) for k, t in hints.items()}
        )
    else:
        return get_type_hints(obj, globalns, localns, include_extras)

# Generic classes that accept at least one parameter type.
# It works also for `Protocol`s that have at least one argument.
def is_generic_class(klass):
    return hasattr(klass, '__orig_bases__') and getattr(klass, '__parameters__', None)

Usage

from dataclasses import dataclass
from typing import TypeVar, Generic, List
from .introspection import get_type_hints2, is_generic_class

T1 = TypeVar('T1')
T2 = TypeVar('T2')

@dataclass
class MyGenericClass(Generic[T1, T2]):
    val: T1
    results: List[T2]

@dataclass
class BaseClass:
    my_str: str

@dataclass
class MyTestClass(BaseClass, MyGenericClass[str, int]):
    ...

print(get_type_hints2(MyTestClass, substitute_type_vars=True))
# {'val': <class 'str'>, 'results': typing.List[int], 'my_str': <class 'str'>}
print(get_type_hints2(BaseClass, substitute_type_vars=True))
# {'my_str': <class 'str'>}
print(get_type_hints2(MyGenericClass, substitute_type_vars=True))
# {'val': ~T1, 'results': typing.List[~T2]}
print(is_generic_class(MyGenericClass))
# True
print(is_generic_class(MyTestClass))
# False
print(is_generic_class(BaseClass))
# False
国产日韩精品视频_2020久久国产最新免费观看_国内久久久久影院精品_日本一区二区视频在线

欧美三级网址| 久久免费视频这里只有精品| 国产乱码精品一区二区三| 久久亚洲影院| 午夜一区二区三区不卡视频| 亚洲国产精品精华液2区45| 国产精品国产三级国产普通话99 | 欧美一区综合| 亚洲日本久久| 伊人春色精品| 国产一区二区三区的电影| 欧美肉体xxxx裸体137大胆| 久久综合久久综合这里只有精品| 亚洲伊人网站| 9色精品在线| 亚洲高清视频的网址| 国产一区日韩二区欧美三区| 国产精品乱码一区二三区小蝌蚪 | 久久漫画官网| 欧美一级成年大片在线观看| 亚洲视频自拍偷拍| 日韩亚洲不卡在线| 亚洲国内精品| 一区免费观看视频| 国产视频在线一区二区| 国产精品乱码人人做人人爱| 欧美激情91| 欧美成人久久| 欧美激情2020午夜免费观看| 美女91精品| 麻豆精品一区二区综合av| 久久久久久欧美| 久久久久久高潮国产精品视| 久久久之久亚州精品露出| 欧美在线91| 久久精品在线视频| 久久久久久亚洲精品不卡4k岛国| 久久久久国内| 免费久久99精品国产| 美女日韩在线中文字幕| 欧美成人综合| 欧美日韩性生活视频| 欧美华人在线视频| 欧美日韩综合另类| 国产精一区二区三区| 国产日韩欧美在线播放不卡| 国产一区二三区| 一区二区视频免费在线观看| 亚洲国产精品一区二区第一页| 亚洲国产天堂久久国产91| 亚洲欧洲日韩在线| 亚洲一区二区精品视频| 亚洲女人天堂av| 久久免费视频一区| 欧美激情aaaa| 国产午夜精品理论片a级探花| 怡红院精品视频在线观看极品| 亚洲国产精品激情在线观看| 亚洲手机成人高清视频| 欧美在线一区二区三区| 欧美电影免费观看高清完整版| 欧美午夜精品久久久久久超碰| 国产日韩成人精品| 亚洲国产经典视频| 亚洲女同在线| 欧美成人一区二区在线 | 99国产麻豆精品| 欧美一区激情| 欧美精品在线观看91| 国产精品一区二区三区乱码| 亚洲经典一区| 香蕉亚洲视频| 欧美日韩一二三区| 精品1区2区3区4区| 亚洲午夜国产一区99re久久| 久久久不卡网国产精品一区| 欧美三日本三级三级在线播放| 亚洲第一黄色| 久久精品一本久久99精品| 欧美丝袜第一区| 亚洲精品综合精品自拍| 久久国产黑丝| 国产精品综合久久久| 日韩视频一区二区三区| 久久久久国产精品一区| 国产精品一区二区在线观看网站| 亚洲精品小视频在线观看| 久久久www| 国产一区二区三区丝袜 | 欧美午夜宅男影院在线观看| 91久久精品日日躁夜夜躁欧美| 久久久久九九九| 国产亚洲va综合人人澡精品| 亚洲主播在线播放| 欧美日韩性视频在线| 亚洲最黄网站| 欧美破处大片在线视频| 亚洲茄子视频| 欧美另类视频| 日韩视频一区| 欧美天堂亚洲电影院在线观看| 亚洲最新在线视频| 欧美日韩一区自拍| 亚洲一区二区三区精品视频| 欧美日韩国产亚洲一区| 一区二区精品| 欧美午夜不卡在线观看免费 | 国产日韩欧美一区在线| 久久国产精彩视频| 国语自产精品视频在线看| 欧美在线视频全部完| 国产亚洲精品自拍| 久久久综合精品| 亚洲黄色大片| 国产精品高潮呻吟| 欧美一级大片在线免费观看| 国产真实精品久久二三区| 久久亚洲二区| 一道本一区二区| 国产精品女主播一区二区三区| 欧美在线看片| 在线观看中文字幕不卡| 欧美激情一区二区三级高清视频| 在线亚洲欧美视频| 国产欧美一区二区三区在线看蜜臀| 久久精品国产一区二区电影| 91久久一区二区| 国产精品久久久久91| 久久九九免费视频| 999亚洲国产精| 国产日韩一区二区三区| 欧美福利精品| 午夜视频久久久久久| 亚洲第一黄网| 国产精品免费看| 麻豆国产精品777777在线| 一本一本久久| 好看的亚洲午夜视频在线| 欧美人与禽猛交乱配视频| 久久成人一区二区| 一区二区免费在线视频| 狠色狠色综合久久| 国产精品久久久久久福利一牛影视| 久久精品在线播放| 亚洲一区二区三区四区五区黄| 亚洲第一在线| 国产伦精品一区二区三区免费迷| 美女视频黄免费的久久| 午夜亚洲性色福利视频| 亚洲靠逼com| 一区二区在线不卡| 国模精品一区二区三区| 国产精品久久久久国产a级| 欧美刺激午夜性久久久久久久| 欧美中文字幕久久| 亚洲性线免费观看视频成熟| 99精品久久免费看蜜臀剧情介绍| 影音先锋日韩有码| 国产精品一二三| 欧美亚洲成人免费| 欧美激情久久久久久| 看片网站欧美日韩| 久久夜色精品亚洲噜噜国产mv| 午夜精品在线| 亚洲欧美国产另类| 在线性视频日韩欧美| 日韩视频一区二区| 夜夜嗨av一区二区三区| 亚洲国内自拍| 日韩视频在线观看一区二区| 亚洲国产欧美久久| 亚洲国内高清视频| 亚洲精品女av网站| 亚洲国产天堂久久综合| 亚洲国产精品久久久久婷婷老年| 在线观看欧美视频| 亚洲第一天堂av| 亚洲激情一区| 亚洲美洲欧洲综合国产一区| 日韩一区二区精品葵司在线| 日韩特黄影片| 亚洲综合色激情五月| 午夜精品久久一牛影视| 欧美在线视频导航| 久久一区二区精品| 毛片基地黄久久久久久天堂| 欧美精品免费视频| 欧美午夜精品| 国产亚洲a∨片在线观看| 狠狠狠色丁香婷婷综合激情| 亚洲第一在线| 一区二区冒白浆视频| 欧美一区成人| 欧美福利小视频| 欧美午夜精品一区| 国产欧美视频一区二区三区| 伊人成年综合电影网| 日韩亚洲视频| 久久国产婷婷国产香蕉| 蜜桃精品久久久久久久免费影院|