如何在Python(打字通用物)中专业班级

发布于 2025-01-24 19:43:33 字数 1046 浏览 0 评论 0原文

如何为专业化(键入 Sense)类提供不同的定义?

例如,为什么这可能有用:

TElement = TypeVar('TElement')

class BaseCollection(Generic[TElement]):
    name: str
    data: List[TElement]

    def __add__(self, other: 'BaseCollection[TElement]'):
        return CombinedCollection[TElement].from_collections(self, other)
    ...

class Collection(BaseCollection):
    pass

# how do I do this specialization
class Collection[int](BaseCollection[int]):
    def sum(self):
        return sum(self.data)


# so that CombinedCollection[int] has also the sum method
class CombinedCollection(Collection[TElement]):
    @classmethod
    def from_collections(cls, *lists: Collection[TElement]):

        return CombinedCollection[TElement]('(' + '+'.join(l.name for l in lists) + ')', 
            [x for l in lists for x in l])

# i.e. I can do
c = Collection[int]('my_collection c', [1,2])
d = Collection[int]('my_collection d', [-1, -2, -3])

cd = c + d
# and now I can do this:
cd.sum()
# -3
cd.name
# (my_collection c+my_collection d)

How to provide a different definition for a specialized (in typing sense) class?

Example, why that might be useful:

TElement = TypeVar('TElement')

class BaseCollection(Generic[TElement]):
    name: str
    data: List[TElement]

    def __add__(self, other: 'BaseCollection[TElement]'):
        return CombinedCollection[TElement].from_collections(self, other)
    ...

class Collection(BaseCollection):
    pass

# how do I do this specialization
class Collection[int](BaseCollection[int]):
    def sum(self):
        return sum(self.data)


# so that CombinedCollection[int] has also the sum method
class CombinedCollection(Collection[TElement]):
    @classmethod
    def from_collections(cls, *lists: Collection[TElement]):

        return CombinedCollection[TElement]('(' + '+'.join(l.name for l in lists) + ')', 
            [x for l in lists for x in l])

# i.e. I can do
c = Collection[int]('my_collection c', [1,2])
d = Collection[int]('my_collection d', [-1, -2, -3])

cd = c + d
# and now I can do this:
cd.sum()
# -3
cd.name
# (my_collection c+my_collection d)

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

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

发布评论

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

评论(1

何处潇湘 2025-01-31 19:43:33

实际上有一种方法可以做到这一点,但是您不必创建类的“专业”,而需要定义类定义中类的所有方法(如果没有类型的注释,这就是Python的样子),并添加一个type constraint on the self parameter of the method:

class Collection(Generic[T]):
    def sum(self: "Collection[int]") -> int:
        ...

a = C[int]([1, 2, 3])
reveal_type(a.sum())  # int
b = C[str](["a", "b", "c"])
reveal_type(b.sum())  # error: Invalid self argument "C[str]" to attribute function "sum"

See a concrete example on

请注意,这仅适用于具体类型,而不适用于类型。如果您将int替换为typevar用bunds(typevar(“ t”,t',bound = nucts.real))或用约束(typevar(“ t”,int,float)),mypy似乎忽略了它们,并且会接受任何类型。上面的示例也证明了这一点。我相信这是一个错误或监督。

There's actually a way to do this, but instead of creating "specializations" of a class, you need to define all methods of a class in the class definition (which is what Python would look like, if without type annotations), and add a type constraint on the self parameter of the method:

class Collection(Generic[T]):
    def sum(self: "Collection[int]") -> int:
        ...

a = C[int]([1, 2, 3])
reveal_type(a.sum())  # int
b = C[str](["a", "b", "c"])
reveal_type(b.sum())  # error: Invalid self argument "C[str]" to attribute function "sum"

See a concrete example on mypy-play.

Note that this only works with concrete types and not type varaibles. If you replace int with a TypeVar with bounds (TypeVar("T", bound=numbers.Real)) or with constraints (TypeVar("T", int, float)), mypy seems to ignore them and will accept any type. This is also demonstrated in the example above. I believe this is a bug or an oversight.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文