我很难找到满足的返回类型mypy。我有两个功能。第一个返回一个Union类型,因为该类型取决于赋予函数的参数。第二个函数使用默认参数调用第一个函数。因此,该类型不是一种Union类型——它可以缩小到Union.
让我给你举一个我的问题的一个非常简单的例子:
from typing import Union
def first(as_string: bool) -> Union[str, int]:
if as_string:
return "42"
else:
return 42
def second(as_string: bool) -> str:
return first(True)
Run Code Online (Sandbox Code Playgroud)
这会导致错误:
Incompatible return value type (got "str", expected "Union[str, int]")
Run Code Online (Sandbox Code Playgroud)
如何mypy在仍然使用类型提示的同时防止抛出错误?
如果您想建议拆分第一个函数,请记住这只是一个简化。我的(第一个)函数接收一个函数(sklearn.metricsfunction)并且大多数时候会返回一个标量。仅当应用混淆矩阵时,类型才会发生变化。第一个函数进行一些预处理,然后应用度量。我只是想为混淆矩阵提供一个不同名称的函数,因为我认为它是度量的特殊情况。
可以通过 json.dumps 转换为 JSON 字符串的值有: - 标量:数字和字符串 - 容器:映射和可迭代
Union[str, int, float, Mapping, Iterable]
你有更好的建议吗?
我有类似的东西:
from typing import Type
class Foo:
pass
def make_a_foobar_class(foo_class: Type[Foo]) -> Type[Foo]:
class FooBar(foo_class):
# this.py:10: error: Variable "foo_class" is not valid as a type
# this.py:10: error: Invalid base class "foo_class"
pass
return FooBar
print(make_a_foobar_class(Foo)())
Run Code Online (Sandbox Code Playgroud)
运行会mypy在该行抛出这两个错误(作为注释添加 ^)class FooBar(foo_class):
该代码似乎工作得很好:
$ python this.py
<__main__.make_a_foobar_class.<locals>.FooBar object at 0x10a422be0>
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
基本上是这个问题(尚未得到解答)的精炼版本。
我想声明的是,变量应该只采用TypedDict.
目前我正在定义一个单独的Literal类型来表示键,例如:
from typing import Literal, TypedDict
class MyTD(TypedDict):
a: int
b: int
mytd = MyTD(a=1, b=2)
key = "a"
mytd[key] # error: TypedDict key must be a string literal; expected one of ('a', 'b')
MyTDKeyT = Literal["a", "b"]
typed_key: MyTDKeyT = "b"
mytd[typed_key] # no error
Run Code Online (Sandbox Code Playgroud)
我希望能够Literal出于想要最小化重复代码的所有常见原因替换定义。
伪代码:
key: Keys[MyTD] = "a"
mytd[key] # would be no error
not_key: Keys[MyTD] = "z" # error
Run Code Online (Sandbox Code Playgroud)
有办法实现这一点吗?
为了澄清,鉴于 mypy 可以告诉我键类型需要是“a”或“b”的文字,我希望可能有一种不太容易出错的方法来将变量注释为该类型,而不是使用并排维护两个单独的键列表,一次在定义中TypedDict,一次在Literal …
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
我正在给Python typing模块一个镜头.
我知道指定List以下*的长度是有效的:
List[float, float, float] # List of 3 floats <-- NOTE: this is not valid Python
Run Code Online (Sandbox Code Playgroud)
是否有更长的名单的简写?如果我想将它设置为10个花车怎么办?
List[float * 10] # This doesn't work.
Run Code Online (Sandbox Code Playgroud)
如果这是可能的,任何想法,这将是方便的.
*注意:事实证明Sequence[]以这种方式向(及其子类)提供多个参数当前不是有效的Python.此外,目前不可能以这种方式Sequence使用typing模块指定长度.
我正在使用 Python 3.6 和flask. 我曾经flask-mysqldb连接到MySQL,但是每当我尝试mypy在我的程序上运行时,我都会收到此错误:
跳过分析“flask_mysqldb”:找到模块但没有类型提示或库存根。
我尝试mypy使用标志ignore-missing-imports或follow-imports=skip. 然后我没有收到错误。为什么我会收到这个错误?如何在不添加任何其他标志的情况下解决此问题?
我正在编写一个 Python 项目,该项目作为包发布到类似 pypi 的存储库(使用setuptools和twine)。我在我的代码中使用类型提示。
问题是,从不同的项目导入包并运行时mypy,出现以下错误:
error: Skipping analyzing 'XXX': found module but no type hints or library stubs
据我了解,我收到此错误是因为我的包不符合https://www.python.org/dev/peps/pep-0561/。
在网上搜索了一些之后,我没有找到一种非手动将所需文件添加到包中的方法。
我求助于编写自己的代码:
stubgen以创建存根文件。py.typed在每个目录中创建文件。dictinpackage_data字段中收集所有创建的setup.py文件。这段代码解决了这个问题并且mypy运行没有错误。但这对我来说感觉非常错误。是否有标准工具可以使包符合 PEP-561?我还缺少其他东西吗?
正确的类型提示是什么functools.partial?我有一个返回 a 的函数partial,我想输入提示,这样就mypy不会抛出任何错误:
def my_func() -> ?:
return partial(foo, bar="baz")
Run Code Online (Sandbox Code Playgroud)
比更具体typing.Callable
考虑下面的代码
import contextlib
import abc
import asyncio
from typing import AsyncContextManager, AsyncGenerator, AsyncIterator
class Base:
@abc.abstractmethod
async def subscribe(self) -> AsyncContextManager[AsyncGenerator[int, None]]:
pass
class Impl1(Base):
@contextlib.asynccontextmanager
async def subscribe(self) -> AsyncIterator[ AsyncGenerator[int, None] ]: <-- mypy error here
async def _generator():
for i in range(5):
await asyncio.sleep(1)
yield i
yield _generator()
Run Code Online (Sandbox Code Playgroud)
对于Impl1.subscribemypy 给出错误
Signature of "subscribe" incompatible with supertype "Base"
Run Code Online (Sandbox Code Playgroud)
在上述情况下指定类型提示的正确方法是什么?或者 mypy 这里错了?
mypy ×10
python ×8
python-3.x ×2
type-hinting ×2
flask-mysql ×1
functools ×1
setuptools ×1
typing ×1