如何在生命周期的早期从 Generic[T] 实例访问 T?

Car*_*ape 5 python generics python-3.x python-typing

我知道我可以这样做:

\n
import typing\n\nT = typing.TypeVar("T")\n\nclass MyGenericClass(Generic[T]):\n    def a_method(self):\n        print(self.__orig_class__)\n\nMyOtherGeneric[SomeBaseClass]().a_method()\n
Run Code Online (Sandbox Code Playgroud)\n

打印SomeBaseClass。也许,我会坚持这种能力来实现我最终想要做的事情(根据修改功能T),但我现在想知道这一切是如何工作的。

\n

本来,我想访问基类型信息(T在实例化对象时或实例化后不久,而不是在其生命周期的后期访问类内部的基本类型信息( 的值)。

\n

作为一个具体的例子,在下面的代码中,我想要一些东西来替换其中的任何一个?n?,这样我就可以获得值SomeOtherBaseClass,这样我就可以在对象生命周期的早期也许还有一些代码也需要高于其中一行。

\n
import typing\n\nT = typing.TypeVar("T")\n\nclass MyOtherGenericClass(Generic[T]):\n    def __init__(self, *args, **kwargs):\n        print(?1?)\n    \n    def __new__(klass, *args, **kwargs):\n        print(?2?)\n\nMyOtherGenericClass[SomeOtherBaseClass]()\n
Run Code Online (Sandbox Code Playgroud)\n

我试图根据 的值在实例化时(或者以某种方式,在实例化之后不久)设置一些实例变量T。我正在重新考虑我的方法,因为typing模块,特别是带有泛型的东西,似乎仍然处于不稳定的开发时期。

\n

那么\xe2\x80\xa6 可能吗?一位用户指出,至少在 3.8 中,__orig_class__在 期间设置typing._GenericAlias.__call__,但是这是如何实现的__call__调用该方法呢?什么时候会发生这种情况?

\n

相关阅读:

\n\n

小智 1

我不知道,看起来你是否想要一个 Self 类型,这是即将推出的 Python 3.11 中PEP 673中的一个内容。

尚未实现的自我类型的当前解决方法是:

from typing import TypeVar

TShape = TypeVar("TShape", bound="Shape")

class Shape:
    def set_scale(self: TShape, scale: float) -> TShape:
        self.scale = scale
        return self


class Circle(Shape):
    def set_radius(self, radius: float) -> Circle:
        self.radius = radius
        return self

Circle().set_scale(0.5).set_radius(2.7)  # => Circle
Run Code Online (Sandbox Code Playgroud)

其中 self 参数和返回类型都使用上限类型变量 TShape 而不是 Self Type 进行提示。