如何输入一个接受类或类实例并返回该类实例的函数?

发布于 2025-01-16 06:25:49 字数 558 浏览 1 评论 0原文

我想输入一个可以采用类类型或类实例的函数,然后返回同一类的实例。例如:

from typing import Type, TypeVar, Union

DT = TypeVar("DT")

def tmap(dest_type_or_obj: Union[DT, Type[DT]]) -> DT:
    if isinstance(dest_type_or_obj, type):
        dest_obj = dest_type_or_obj()
    else:
        dest_obj = dest_type_or_obj
    return dest_obj

class Dest:
    pass

instance_dest = tmap(Dest())  # Works fine

type_dest = tmap(Dest)  # [arg-type] mypy(error)
# Argument 2 to "map" of "ObjectMapper" has incompatible type "Type[Dest]"; expected "Type[<nothing>]"

I want to type a function that can take either a class type, or an instance of the class, and then return an instance of that same class. For example:

from typing import Type, TypeVar, Union

DT = TypeVar("DT")

def tmap(dest_type_or_obj: Union[DT, Type[DT]]) -> DT:
    if isinstance(dest_type_or_obj, type):
        dest_obj = dest_type_or_obj()
    else:
        dest_obj = dest_type_or_obj
    return dest_obj

class Dest:
    pass

instance_dest = tmap(Dest())  # Works fine

type_dest = tmap(Dest)  # [arg-type] mypy(error)
# Argument 2 to "map" of "ObjectMapper" has incompatible type "Type[Dest]"; expected "Type[<nothing>]"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

过气美图社 2025-01-23 06:25:49

虽然技术上等效,但 MyPy 需要 使用 overload< /code>

@overload
def tmap(dest_type_or_obj: Type[DT]) -> DT:
    ...
@overload
def tmap(dest_type_or_obj: DT) -> DT:
    ...

这使得 MyPy 能够在实例和类型情况下正确推断类型变量。

reveal_type(tmap(Dest()))  # note: Revealed type is "__main__.Dest*"

reveal_type(tmap(Dest))    # note: Revealed type is "__main__.Dest*"

While technically equivalent, MyPy requires to separate both cases using overload:

@overload
def tmap(dest_type_or_obj: Type[DT]) -> DT:
    ...
@overload
def tmap(dest_type_or_obj: DT) -> DT:
    ...

This enables MyPy to infer the type variable properly in both the instance and type case.

reveal_type(tmap(Dest()))  # note: Revealed type is "__main__.Dest*"

reveal_type(tmap(Dest))    # note: Revealed type is "__main__.Dest*"
生来就爱笑 2025-01-23 06:25:49

您应该将 Dest 类绑定到 TypeVar,以防止 Type[] 错误:

from typing import Type, TypeVar, Union


class Dest:
    pass


DT = TypeVar("DT", bound=Dest)


def tmap(dest_type_or_obj: Union[DT, Type[DT]]) -> DT:
    if isinstance(dest_type_or_obj, type):
        dest_obj = dest_type_or_obj()
    else:
        dest_obj = dest_type_or_obj
    return dest_obj


instance_dest = tmap(Dest())
print((type(instance_dest)))
type_dest = tmap(Dest) 
print((type(type_dest)))
# output
<class '__main__.Dest'>
<class '__main__.Dest'>

You should bound the Dest class to TypeVar, to prevent the Type[<nothing>] error:

from typing import Type, TypeVar, Union


class Dest:
    pass


DT = TypeVar("DT", bound=Dest)


def tmap(dest_type_or_obj: Union[DT, Type[DT]]) -> DT:
    if isinstance(dest_type_or_obj, type):
        dest_obj = dest_type_or_obj()
    else:
        dest_obj = dest_type_or_obj
    return dest_obj


instance_dest = tmap(Dest())
print((type(instance_dest)))
type_dest = tmap(Dest) 
print((type(type_dest)))
# output
<class '__main__.Dest'>
<class '__main__.Dest'>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文