gpt4 book ai didi

python - 自定义类型提示注解

转载 作者:太空狗 更新时间:2023-10-30 02:53:40 24 4
gpt4 key购买 nike

我只是写了一个简单的@autowired decorator用于基于类型注释实例化类的 Python。

为了启用类的惰性初始化,该包提供了一个lazy(type_annotation: (Type, str)) 函数,以便调用者可以像这样使用它:

@autowired
def foo(bla, *, dep: lazy(MyClass)):
...

这工作得很好,在幕后这个 lazy 函数只返回一个函数,该函数返回实际类型并将 lazy_init 属性设置为 True。此外,这不会破坏 IDE(例如 PyCharm)的代码完成功能。

But I want to enable the use of a subscriptable Lazy type use instead of the lazy function.

像这样:

@autowired
def foo(bla, *, dep: Lazy[MyClass]):
...

这很像 typing.Union . 虽然我能够实现可订阅类型,但 IDE 的代码完成功能将变得毫无用处,因为它会为 Lazy 类中的属性提供建议,而不是 我的类(class)

我一直在使用这段代码:

class LazyMetaclass(type):
def __getitem__(lazy_type, type_annotation):
return lazy_type(type_annotation)

class Lazy(metaclass=LazyMetaclass):
def __init__(self, type_annotation):
self.type_annotation = type_annotation

我尝试将 Lazy.__dict__ 重新定义为转发到下标类型的 __dict__ 的属性,但这似乎对 PyCharm 的代码完成功能没有影响。

我坚信我正在努力实现的目标是可能的 typing.Union与 IDE 的代码完成配合得很好。我一直在尝试破译 typing.Union 的源代码中的内容使其在代码完成功能方面表现良好,但到目前为止没有成功。

最佳答案

要使 Container[Type] 符号正常工作,您需要创建一个 user-defined generic type :

from typing import TypeVar, Generic

T = TypeVar('T')

class Lazy(Generic[T]):
pass

然后你使用

def foo(bla, *, dep: Lazy[MyClass]):

Lazy 被看作是一个容纳类的容器。

注意:这仍然意味着 IDE 将 dep 视为 Lazy 类型的对象。 Lazy 在这里是一种容器类型,持有 MyClass 类型的对象。您的 IDE 不会自动完成 MyClass 类型,您不能那样使用它。

该表示法也不会创建 Lazy 类的实例;它通过 GenericMeta 元类创建了一个子类。子类有一个特殊的属性 __args__ 让你反省订阅参数:

>>> a = Lazy[str]
>>> issubclass(a, Lazy)
True
>>> a.__args__
(<class 'str'>,)

如果您只想在运行时访问类型注释,但懒惰地解析名称,您可以只支持一个字符串值:

def foo(bla, *, dep: 'MyClass'):

这是有效的类型注解,并且您的装饰器可以在运行时使用 typing.get_type_hints() function 解析名称(在延迟时间,而不是在装饰时),或者通过在装饰时可调用的 lazy() 中包装字符串。

如果 lazy() 是为了标记一个类型以区别于其他类型提示,那么您正在尝试用其他含义重载类型提示注释,并进行类型提示 根本不支持这样的用例,并且使用包含的 Lazy[...] 无法使其工作。

关于python - 自定义类型提示注解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48722835/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com