简体   繁体   English

使用存根文件提供类似OrderedSet [int]的类型而不修改有序集库

[英]Provide OrderedSet[int] like types using stub file without modifying ordered-set library

I've contributed type hints for ordered-set library. 我为有序集提供了类型提示。 The problem is that despite I have the following lines in ordered_set.pyi file: 问题是尽管我在ordered_set.pyi文件中有以下几行:

from typing import MutableSet, TypeVar, Sequence

T = TypeVar('T')

class OrderedSet(MutableSet[T], Sequence[T]):
    ...

I cannot write: 我不能写:

IntOrderedSet = OrderedSet[int]

in my code, Python raises: 在我的代码中,Python提出:

TypeError: 'ABCMeta' object is not subscriptable

It happens because in the ordered_set.py OrderedSet is defined as: 它发生的原因是在ordered_set.py OrderedSet定义为:

from collections.abc import MutableSet, Sequence

class OrderedSet(MutableSet, Sequence):
    ...

I made a PR with commit that changes OrderedSet class to inherit from typing classes , but ordered-set owner refused to accept it, because as he said: 我做了一个带有提交的PR,它改变了OrderedSet来继承输入类 ,但是ordered-set所有者拒绝接受它,因为他说:

Importing typing inside the code adds an install-time dependency and a run-time cost to the code. 在代码中导入键入会为代码添加安装时依赖性和运行时成本。 ordered_set has gotten by as a single module with no dependencies for 6 years. ordered_set作为单个模块获得了6年没有依赖关系。 Someone could decide they want nothing to do with setuptools and just drop ordered_set on their PYTHONPATH, and it would still work. 有人可以决定他们不想与setuptools做任何事情,只是在他们的PYTHONPATH上删除ordered_set,它仍然可以工作。 I'd hate to lose that over types. 我不想失去那种类型。

Is there a way, to support OrderedSet[int] like types without modifying the library ordered_set.py file? 有没有办法,在不修改库ordered_set.py文件的情况下支持OrderedSet[int]类型?

The only workaround that I'm aware of is to define any custom type aliases such that they exist only at type-check time, and never at run-time. 我所知道的唯一解决方法是定义任何自定义类型别名,使它们仅在类型检查时存在,而不是在运行时存在。

In order to do this, you would need to: 为此,您需要:

  1. Define any type aliases inside if typing.TYPE_CHECKING: blocks. if typing.TYPE_CHECKING: blocks,则在里面定义任何类型的别名。 The typing.TYPE_CHECKING block is always false at runtime, and treated as being true by type checkers. typing.TYPE_CHECKING块在运行时始终为false,并通过类型检查器视为true。
  2. Make sure you either have all of your type hints be strings -- or, if you're using Python 3.7, add from __future__ import annotations , which does that automatically. 确保您要么将所有类型提示都设置为字符串 - 或者,如果您使用的是Python 3.7,请添加from __future__ import annotations ,这会自动执行此操作。 That is, avoid having to ever evaluate type hints in the first place. 也就是说,避免必须首先评估类型提示。

So for example, in your specific setup, you could contribute stubs for the OrderedSet library somewhere then write your code to look like this (assume Python 3.7+): 例如,在您的特定设置中,您可以在某处为OrderedSet库提供存根,然后将代码编写为如下所示(假设Python 3.7+):

from __future__ import annotations
from typing import TYPE_CHECKING
from ordered_set import OrderedSet

# Basically equivalent to `if False`
if TYPE_CHECKING:
    IntOrderedSet = OrderedSet[Int]

def expects_int_ordered_set(x: IntOrderedSet) -> None:
    # blah

some_ordered_set: IntOrderedSet = OrderedSet()

Or, if you're using Python 3.6 or lower: 或者,如果您使用的是Python 3.6或更低版本:

from typing import TYPE_CHECKING
from ordered_set import OrderedSet

if TYPE_CHECKING:
    IntOrderedSet = OrderedSet[Int]

def expects_int_ordered_set(x: 'IntOrderedSet') -> None:
    # blah

some_ordered_set: 'IntOrderedSet' = OrderedSet()

If you're ok with lying a little, we could dispense with the string stuff and define IntOrderedSet to be slightly different things at type-checking time vs runtime. 如果你可以稍微说谎,我们可以省去字符串的东西,并在类型检查时间和运行时定义IntOrderedSet略有不同。 For example: 例如:

from typing import TYPE_CHECKING
from ordered_set import OrderedSet

if TYPE_CHECKING:
    IntOrderedSet = OrderedSet[Int]
else:
    IntOrderedSet = OrderedSet

def expects_int_ordered_set(x: IntOrderedSet) -> None:
    # blah

some_ordered_set = IntOrderedSet()

Make sure to be careful when you're doing this though -- the type checker won't check anything in the 'else' block/won't check to make sure whatever you're doing there is consistent with what's in the if TYPE_CHECKING block. 确保在你这样做时要小心 - 类型检查器不会检查'else'块中的任何内容/不会检查以确保你所做的任何事情与if TYPE_CHECKING中的内容if TYPE_CHECKING块。

The final solution would be to just not define an IntOrderedSet type in the first place. 最终的解决方案是首先不要定义IntOrderedSet类型。 This lets us skip hack 1 while only needing to use hack 2 (which isn't so much a hack -- it'll be default behavior in Python in a few years). 这让我们跳过hack 1而只需要使用hack 2(这不是一个黑客攻击 - 它将在几年内成为Python中的默认行为)。

So for example, we could do this: 例如,我们可以这样做:

from __future__ import annotations
from ordered_set import OrderedSet

def expects_int_ordered_set(x: OrderedSet[int]) -> None:
    # blah

some_ordered_set: OrderedSet[int] = OrderedSet()

Depending on context, it may be the case that I don't even need to add an annotation to that last variable declaration. 根据上下文,可能是我甚至不需要为最后一个变量声明添加注释。 Here, we do, but if we were defining that variable inside of a function, it's possible type checkers like mypy would automatically infer the correct type for us based on how we end up using that variable. 在这里,我们这样做,但如果我们在函数内部定义该变量,那么像mypy这样的类型检查器会根据我们最终使用该变量的方式自动推断出正确的类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用有序字典作为有序集 - Using ordered dictionary as ordered set 使用python修改XML文件(klish types.xml) - Modifying XML file using python (klish types.xml) 如何导入 Python 存根文件中定义的类型? - How to import types defined in a Python stub file? 直接在databricks中使用openpyxl修改xlsx文件,无需pandas/dataframe - Modifying the xlsx file using openpyxl in databricks directly without pandas/dataframe 复制不包括文件类型、子文件夹的目录结构和文件……是否可以在不编写整个脚本的情况下使用标准库? - Copy directory structure and files excluding file types, sub folders… Is it possible using the standard library without writing a whole script? 是否有一个 python xml 解析器库允许删除节点而不修改 xml 文件布局(命名空间/缩进) - Is there a python xml parser library that allows removing nodes without modifying the xml file layout (namespace/indentation) 如何在不使用 Python 中的库函数的情况下将“String”转换为“Int” - How to convert "String" to "Int" without using library functions in Python 为第三方库/模块扩展存根文件 - Extending stub file for a third-party library/module python 中没有模块 lxml.html 的库存根文件 - No library stub file for module lxml.html in python 在不使用预定义库的情况下生成集合的幂集? - Generates the power set of the set without using pre-defined library?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM