python - 创建自己的可选版本

标签 python mypy python-typing

我的代码中有这样的内容:

Undefined = Literal['__undefined_attr__']
undefined: Undefined = '__undefined_attr__'

def funkc(
    foo: Union[str, Undefined] = undefined,
    bar: Union[int, Undefined] = undefined,
    baz: Union[str, Undefined] = undefined,
    boo: Union[float, Undefined] = undefined,
    # ... lots more args like that with many different types
):
    if foo is not undefined:
        ...
    if bar is not undefined:
        ...
    ...  # etc.

现在,如果我可以使用 None 作为默认值,这一切都会变得更加简单,例如:

def funkc(
    foo: Optional[str] = None,
    bar: Optional[int] = None,
    baz: Optional[str] = None,
    boo: Optional[float] = None,
    # ... lots more args like that with many different types
):
    if foo is not None:
        ...
    if bar is not None:
        ...
    ...  # etc.

所以我想我可以创建自己的类型快捷方式,可以像这样使用:

def funkc(
    foo: OptionallyDefined[str] = undefined,
    bar: OptionallyDefined[int] = undefined,
    baz: OptionallyDefined[str] = undefined,
    boo: OptionallyDefined[float] = undefined,
    # ... lots more args like that with many different types
):
    if foo is not undefined:
        ...
    if bar is not undefined:
        ...
    ...  # etc.

但实际上创建这个 OptionalylDefined 的东西却让我无法理解。 mypy 可以做到这一点吗?

<小时/>

解决方案:

感谢user2357112 supports Monica's answer ,这就是我最终使用的:

class Undefined:
    instance = None

    def __new__(cls, *args, **kwargs) -> "Undefined":
        """Singleton, just in case..."""
        if not cls.instance:
            cls.instance = super().__new__(cls, *args, **kwargs)  # type: ignore
        return cls.instance


undefined = Undefined()
ArgType = TypeVar("ArgType")
OptionallyDefined = Union[ArgType, Undefined]


def funkc(...):
    if foo is not undefined:
        ...

最佳答案

我这里没有 mypy,所以我无法测试它,但以下应该可以工作。 (确保使用 mypy 对其进行测试,而不仅仅是运行它):

T = typing.TypeVar('T')

OptionallyDefined = typing.Union[T, Undefined]

def funkc(
    foo: OptionallyDefined[str] = undefined,
    ...
):
    ...

您自己的 TypeVar 尝试失败,因为您同时以与 typing.Literal 不兼容的方式更改了 undefined 的定义。

<小时/>

顺便说一句,这种定义和使用 undefined 的方式并不安全。 MyPy 会将任何 '__undefined_attr__' 字符串视为 Undefined 类型的有效值,但您的 is 比较将拒绝某些字符串并允许其他字符串,取决于实现细节以及任何特定字符串的来源。我会编写一个类并使用该类的实例来表示 undefined,而不是使用字符串和 typing.Literal

关于python - 创建自己的可选版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59297132/

相关文章:

python - 键入一个带有可调用的函数

python-3.x - 如何向 scikit-learn 函数添加类型提示?

python - 在python中调用Libsvm模型

python - 如何在一个 Django HttpResponse 中返回两个变量?

python - 使用 Python 类型的 TypeVar 进行带绑定(bind)的通用类型返回

python - 有没有办法从类中删除 __bool__ 方法?

python - mypy: "__getitem__"的签名与父类(super class)型 "Sequence"不兼容

python - 使用相同的抽象函数从父属性调用子函数

python - 在 Python 中,如何对有时挂起的函数调用强制超时?

python - PEP 484 : exclusive type for type hint