Python 创建自己的可选版本

Python 创建自己的可选版本,python,mypy,python-typing,Python,Mypy,Python Typing,我的代码中有类似的内容: Undefined=Literal[''未定义的属性] 未定义:未定义=“\uuu未定义\u属性” def funkc( foo:Union[str,未定义]=未定义, 条:并集[int,未定义]=未定义, baz:Union[str,未定义]=未定义, boo:Union[float,未定义]=未定义, #…更多类似的arg,有许多不同的类型 ): 如果foo不是未定义的: ... 如果条形图未定义: ... ... # 等 现在,如果我可以使用None作为默认值

我的代码中有类似的内容:

Undefined=Literal[''未定义的属性]
未定义:未定义=“\uuu未定义\u属性”
def funkc(
foo:Union[str,未定义]=未定义,
条:并集[int,未定义]=未定义,
baz:Union[str,未定义]=未定义,
boo:Union[float,未定义]=未定义,
#…更多类似的arg,有许多不同的类型
):
如果foo不是未定义的:
...
如果条形图未定义:
...
...  # 等
现在,如果我可以使用None作为默认值,这将变得更简单,比如:

def funkc(
foo:可选[str]=无,
条形图:可选[int]=无,
baz:可选[str]=无,
boo:可选[浮动]=无,
#…更多类似的arg,有许多不同的类型
):
如果foo不是None:
...
如果bar不是无:
...
...  # 等
所以我想我可以创建我自己的类型快捷方式,可以像这样使用:

def funkc(
foo:OptionallyDefined[str]=未定义,
条形图:可选定义[int]=未定义,
baz:可选定义[str]=未定义,
boo:可选定义的[float]=未定义,
#…更多类似的arg,有许多不同的类型
):
如果foo不是未定义的:
...
如果条形图未定义:
...
...  # 等
但实际上创建这个
可选定义的
东西让我不知所措。mypy可以这样做吗


解决方案:

多亏了这一点,我最终使用的是:

未定义的类:
实例=无
定义(cls,*args,**kwargs)->“未定义”:
“辛格尔顿,以防万一……”
如果不是cls.instance:
cls.instance=super()
返回cls.instance
未定义=未定义()
ArgType=TypeVar(“ArgType”)
OptionallyDefined=联合[ArgType,未定义]
def funkc(…):
如果foo不是未定义的:
...

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

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



另一方面,这种定义和使用未定义的
的方式是不安全的。MyPy将考虑任何<代码> 'yunDeDeDeAttrux'’/CudioString为类型<代码>未定义的有效值,但是您的<代码>是比较将拒绝某些字符串并允许其他,取决于实现细节和来自特定字符串的位置。我会编写一个类,并使用该类的一个实例来执行
未定义的
,而不是使用字符串和
键入。Literal

啊,是的,
实际上是我在使用
未定义的=object()
时留下的。然而,
Literal
仅适用于字符串、整数等,而不适用于对象:(谢谢提醒!
T = typing.TypeVar('T')

OptionallyDefined = typing.Union[T, Undefined]

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