创建自己的可选版本
Create own version of Optional
我的代码中有这样的东西:
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 实现吗?
解法:
感谢,这是我最终使用的:
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
比较将拒绝某些字符串并允许其他字符串,具体取决于实现细节和任何特定字符串的来源.我会写一个 class 并为 undefined
使用 class 的实例,而不是使用字符串和 typing.Literal
.
我的代码中有这样的东西:
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 实现吗?
解法:
感谢
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
比较将拒绝某些字符串并允许其他字符串,具体取决于实现细节和任何特定字符串的来源.我会写一个 class 并为 undefined
使用 class 的实例,而不是使用字符串和 typing.Literal
.