现在Python 3.10已经发布了,在指示参数或返回值可能是可选的(即可以是None. 那么什么是首选:
选项1:
def f(parameter: Optional[int]) -> Optional[str]:
Run Code Online (Sandbox Code Playgroud)
选项2:
def f(parameter: int | None) -> str | None:
Run Code Online (Sandbox Code Playgroud)
Type | None另外,和之间有什么偏好吗None | Type?
我是 Python 新手,发现 swmmtoolbox 包出现以下错误。我非常感谢您的评论。谢谢
回溯(最近一次调用最后一次):
File "C:\Users\Hydraulic Group\anaconda3\lib\site-packages\typic\compat.py", line 16, in <module>
from typing import Final, TypedDict, Literal, Protocol, **TypeGuard**, get_origin, get_args # type: ignore
ImportError: cannot import name 'TypeGuard' from 'typing' (C:\Users\Hydraulic Group\anaconda3\lib\typing.py)
Run Code Online (Sandbox Code Playgroud)
在处理上述异常的过程中,又发生了一个异常:Traceback(最近一次调用最后):
File "E:\VARS_Research\ostrich_swmm_master\ostrich_swmm\__main__.py", line 11, in <module>
import extract
File "E:\VARS_Research\ostrich_swmm_master\ostrich_swmm\extract.py", line 8, in <module>
import swmmtoolbox.swmmtoolbox as swmmtoolbox
File "C:\Users\Hydraulic Group\anaconda3\lib\site-packages\swmmtoolbox\swmmtoolbox.py", line 19, in <module>
from tstoolbox import tsutils
File "C:\Users\Hydraulic Group\anaconda3\lib\site-packages\tstoolbox\tsutils.py", line 24, in <module>
import typic
File "C:\Users\Hydraulic Group\anaconda3\lib\site-packages\typic\__init__.py", line 4, in …Run Code Online (Sandbox Code Playgroud) mypy v0.910 拒绝 Python 3.9 中的抽象数据类。这是最小的可重复示例:
from abc import ABC, abstractmethod
from dataclasses import dataclass
@dataclass
class Liquid(ABC):
@abstractmethod
def drip(self) -> None:
pass
Run Code Online (Sandbox Code Playgroud)
这是错误消息:
$ mypy --python-version 3.9 so.py
so.py:4: error: Only concrete class can be given where "Type[Liquid]" is expected
Found 1 error in 1 file (checked 1 source file)
Run Code Online (Sandbox Code Playgroud)
如何让此代码通过mypy?
笔记
我从mypy 问题 #5374中了解到,这是mypy中的一个错误,于 2018 年首次注意到,但仍未得到纠正。不过,我认为人们必须将mypy与抽象数据类一起使用,因此必须有一种解决方法或正确的方法来定义或注释该类。有什么推荐的?
错误消息的基础似乎是mypy假设任何类型的对象都Type可以实例化,但抽象类不能实例化。这似乎是错误,因为Type被定义为表示类对象,而不一定是具体的类对象(即可以实例化的类对象)。
添加# type: ignore到包含的行 …
python abstract-base-class mypy python-dataclasses python-typing
我使用的一些包没有类型提示它们的代码,所以当我使用它们时,Pylance 不断告诉我我使用的函数有部分未知的类型,这是我无法解决的问题。有没有办法禁用此类错误?
mypy版本0.910
考虑
d = {
'a': 'a',
'b': {
'c': 1
}
}
d['b']['d'] = 'b'
Run Code Online (Sandbox Code Playgroud)
将其提供给mypy结果
error: Unsupported target for indexed assignment ("Collection[str]")
Run Code Online (Sandbox Code Playgroud)
mypy放置推断错误类型的一侧d(它显然不是字符串集合),添加一个非常基本的显式类型d修复此问题:
d: dict = {
... # same as above
}
Run Code Online (Sandbox Code Playgroud)
Success: no issues found in 1 source file
Run Code Online (Sandbox Code Playgroud)
我觉得这很奇怪。mypy绝对应该能够推断出这d是一个没有d: dict.
我正在尝试输入ndarray像这样的 numpy 提示:
RGB = numpy.dtype[numpy.uint8]
ThreeD = tuple[int, int, int]
def load_images(paths: list[str]) -> tuple[list[numpy.ndarray[ThreeD, RGB]], list[str]]: ...
Run Code Online (Sandbox Code Playgroud)
但在我运行此命令的第一行时,出现以下错误:
RGB = numpy.dtype[numpy.uint8]
TypeError: 'numpy._DTypeMeta' object is not subscriptable
Run Code Online (Sandbox Code Playgroud)
如何ndarray正确输入提示a?
io例如,在编写实现类文件接口的类时,我们可以从模块继承抽象基类之一,如调整迭代器以使其行为类似于 Python 中的类文件对象TextIOBase中所示。
另一方面,在类型注释中,我们应该使用派生自typing.IO(例如TextIO)的类来表示此类对象,如文件或类文件对象的类型提示中所示?或Union 中 io.TextIOBase 的类型检查问题。
然而,这似乎并没有像我预期的那样工作:
import io
import sys
import typing
class MyIO(io.TextIOBase):
def write(self, text: str):
pass
def hello(f: typing.TextIO):
f.write('hello')
hello(sys.stdout) # type checks
hello(open('temp.txt', 'w')) # type checks
hello(MyIO()) # does not type check
Run Code Online (Sandbox Code Playgroud)
当在此代码上运行 mypy 时(使用 Python 3.7.3 和 mypy 0.910),我们得到
错误:“hello”的参数 1 具有不兼容的类型“MyIO”;预期“TextIO”
如何MyIO编写该类,使其被接受为类型的函数参数typing.TextIO(而不仅仅是使用typing.cast(typing.TextIO, ...))?
typing.TextIO不能用作基类:
使用时class MyIO(typing.TextIO):
错误:无法使用抽象属性“__enter__”、“__exit__”、...和“writelines”实例化抽象类“MyIO”(抑制了 …
我知道有一种新的类型格式,Annotated您可以在其中为函数的入口变量指定一些元数据。从文档中,您可以指定传入列表的最大长度,例如:
- Annotated 可以与嵌套和通用别名一起使用:
T = TypeVar('T')
Vec = Annotated[list[tuple[T, T]], MaxLen(10)]
V = Vec[int]
V == Annotated[list[tuple[int, int]], MaxLen(10)]
Run Code Online (Sandbox Code Playgroud)
但我无法完全理解到底是什么MaxLen。你应该从其他地方导入一个类吗?我尝试过导入typing.MaxLen,但似乎不存在(我正在使用Python 3.9.6,我认为它应该存在于此处...?)。
我想象它应该有效的示例代码:
from typing import List, Annotated, MaxLen
def function(foo: Annotated[List[int], MaxLen(10)]):
# ...
return True
Run Code Online (Sandbox Code Playgroud)
哪里可以找到MaxLen?
编辑:
看起来MaxLen你必须创建某种类。问题是我不知道你应该怎么做。有公开的例子吗?有人如何实现这个功能?
目前,当我无法在函数签名中分配默认参数和/或已经具有含义时,我会使用此策略。None
from typing import Optional
DEFAULT = object()
# `None` already has meaning.
def spam(ham: Optional[list[str]] = DEFAULT):
if ham is DEFAULT:
ham = ['prosciutto', 'jamon']
if ham is None:
print('Eggs?')
else:
print(str(len(ham)) + ' ham(s).')
Run Code Online (Sandbox Code Playgroud)
错误:
Failed (exit code: 1) (2607 ms)
main.py:7: error: Incompatible default for argument "ham" (default has type "object", argument has type "Optional[List[str]]")
Found 1 error in 1 file (checked 1 source file)
Run Code Online (Sandbox Code Playgroud)
ham而不出现错误?或者DEFAULT = object() …由于我在 Python 中经常使用类型提示,因此我遇到了递归函数接受dict,str作为键和int或dict作为值 ( Dict[str, Union[int, Dict[...]]) 的场景。此时的问题是可能的dict-value 也有str作为键和int或dict作为值 ( Dict[str, Union[int, Dict[Dict[str, Union[int, Dict[...]]]])。
但是,我不知道传递的字典有什么深度。是否有可能通过类型提示来可视化这种重复模式?
python ×10
python-typing ×10
type-hinting ×9
mypy ×5
python-3.9 ×2
numpy ×1
pylance ×1
python-3.10 ×1
type-alias ×1
typeguards ×1