我有以下嵌套函数
from typing import Optional
def outer(
outer_foo:int,
outer_bar:Optional[int] = 5
):
return inner(outer_foo, outer_bar)
def inner(
inner_foo:int,
inner_bar:int
):
return inner_foo+inner_bar
print(outer((1)))
Run Code Online (Sandbox Code Playgroud)
并mypy抛出以下错误:
error: Argument 2 to "inner" has incompatible type "Optional[int]"; expected "int"
Run Code Online (Sandbox Code Playgroud)
鉴于我给出了int默认值outer_bar,我没有看到潜在的问题。但是,我能够解决 mypy 错误,将代码更改为:
from typing import Optional
def outer(
outer_foo:int,
outer_bar:Optional[int] = None
):
if outer_bar is None:
outer_bar = 5
return inner(outer_foo, outer_bar)
def inner(
inner_foo:int,
inner_bar:int
):
return inner_foo+inner_bar
print(outer((1)))
Run Code Online (Sandbox Code Playgroud)
这似乎破坏了声明中默认参数的用处。这是最好的/Python式的方法吗?
我想知道是否有办法在 Python 项目中强制执行类型提示?
目前,我正在使用mypy 预提交挂钩.pre-commit-config.yaml:
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.931
hooks:
- id: mypy
Run Code Online (Sandbox Code Playgroud)
使用这个钩子,由于调用函数时的类型错误,我将(正确地)无法提交以下代码add:
def add(a: int, b: int) -> int:
return a + b
add(a=1.0, b=2.0)
Run Code Online (Sandbox Code Playgroud)
但是,使用上面的mypy和预提交钩子组合,类型提示仍然没有完全强制执行,我将能够在不使用类型提示的情况下提交以下代码:
def add(a, b):
return a + b
Run Code Online (Sandbox Code Playgroud)
我也很好奇,在动态类型语言(例如 Python)中强制执行类型提示是否是一个好主意?我知道我可以为我的项目选择一些静态类型语言(例如 Java),但是,我想使用带有强制类型提示的 Python 的原因是因为这允许我依赖现有的 Python 库(例如 Tensorflow),同时确保由于函数签名中指定了类型,所以编写的代码质量更好。
我有一个DataWriter定义抽象方法的抽象类write()。该类应该是一组动态具体类的基类,其中每个类都旨在实现其自己的方法版本write()。为了定义meta方法参数的数据类型,我创建了WriterMetawrite()类型,如下所示:
WriterMeta = typing.Union[GSheetWritable, S3Writable, LocalWritable]
每个具体类将负责处理符合联合的不同类型之一,但 linter mypy似乎没有掌握这一点,因为当我write()使用其中一种类型定义具体类的方法的签名时参数的联合meta,它标记了 a Liskov substituion principle violation,我认为它不存在,因为具体类是抽象类的子集,这意味着父类可以毫无问题地替换子类。
这是我的代码:
class LocalWritable(typing.TypedDict):
file_name: str
class GSheetWritable(typing.TypedDict):
tab_name: str
class S3Writable(typing.TypedDict):
data_name: str
table_name: str
WriterMeta = typing.Union[GSheetWritable, S3Writable, LocalWritable]
class GSheetOutputWriter(DataWriter):
def __init__(
self, google_driver: GoogleApiDriver, folder: str, settings, timestamp, env
):
self._connector = google_driver
self.folder = folder
self.settings = settings
self.timestamp = timestamp
self.env = env
self.file_name …Run Code Online (Sandbox Code Playgroud) python abstract-class liskov-substitution-principle python-3.x mypy
我想定义一个UserDict从 JSON 读取值并存储给定键的位置的函数。JSON 文件如下所示:
{
"pages": [
{
"areas": [
{
"name": "My_Name",
"x": 179.95495495495493,
"y": 117.92792792792793,
"height": 15.315315315315303,
"width": 125.58558558558553
},
...
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
我想向类型 linter(例如 MyPy)表明该字典作为键是字符串,值是Position.
我当前的代码如下:
import json
from collections import UserDict
from dataclasses import dataclass, field
from pathlib import Path
from typing import Dict, List, Optional, Union
from typing_extensions import Literal
JsonPosition = Dict[str, Union[str, float]]
JsonPage = Optional[Dict[Literal["areas"], List[JsonPosition]]]
@dataclass
class Position:
"""Information for a position"""
name: str
x: …Run Code Online (Sandbox Code Playgroud) 以下代码似乎生成两个 mypy 错误:Overloaded function signatures 1 and 3 overlap with incompatible return types和Overloaded function signatures 2 and 3 overlap with incompatible return types; 但所有重载都有不同的签名 - Literal[True]、Literal[False] 和 None 不重叠。
@overload
def func_a(*, a: Literal[False] = ...) -> str:
...
@overload
def func_a(*, a: None = ...) -> str:
...
@overload
def func_a(*, a: Literal[True] = ...) -> int:
...
def func_a(*, a: Optional[bool] = None) -> str | int:
if a:
return 1
return "foo"
var1 …Run Code Online (Sandbox Code Playgroud) 在Python文档中,我们发现:
T = TypeVar('T') # Can be anything
S = TypeVar('S', bound=str) # Can be any subtype of str
A = TypeVar('A', str, bytes) # Must be exactly str or bytes
Run Code Online (Sandbox Code Playgroud)
我们还发现了这段代码:
def repeat(x: T, n: int) -> Sequence[T]:
"""Return a list containing n references to x."""
return [x]*n
def print_capitalized(x: S) -> S:
"""Print x capitalized, and return x."""
print(x.capitalize())
return x
def concatenate(x: A, y: A) -> A:
"""Add two strings or bytes objects together."""
return …Run Code Online (Sandbox Code Playgroud) 我为Salt编写了一个模块。根据文档,它将__salt__对象添加到中builtins。因此,pyflake警告我__salt__在运行探矿器时未定义,而mypy表示相同,即__salt__未定义!我可以忽略无论是pyflake用# noqa: F821或mypy与# type: ignore该行上。
问题是!如何为他们两者忽略?
我总是mypy在我的Python程序中使用。
typing不可变对象的类型(来自)是什么,可以用于字典键的对象是什么?
回到上下文,我想编写一个从字典继承的类,我有以下代码
class SliceableDict(dict):
def __getitem__(self, attr:Any) -> Any:
return super().__getitem__(attr)
Run Code Online (Sandbox Code Playgroud)
在那种情况下,类型提示是没有用的,不是吗?
谢谢
我是粉丝,mypy我想在具有不同类型值的字典上添加一些类型提示.
我的字典如下
{'name':'John', 'age':136, 'hobbies':['Python', 'cooking', 'reading']}
我想到的当前打字是: Dict[str, Union[str, int, List[str]]
有没有办法指定它name是一个字符串,age是一个整数,并且hobbies是一个列表(进一步特定的类型检查mypy)?
注意:此数据来自包含此类对象列表的外部源.我对它有一个有限的控制,除了循环元素并转换它们.
谢谢
我目前正在学习 fastAPI 教程,我的环境设置了 black、flake8、bandit 和 mypy。本教程中的所有内容都运行良好,但我一直不得不 # type: ignore things 让 mypy 合作。
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
@app.post("/items/")
async def create_items(item: Item) -> Item:
return item
Run Code Online (Sandbox Code Playgroud)
Mypy然后错误:
? mypy main.py [14:34:08]
main.py:9: error: Incompatible types in assignment (expression has type "None", variable has type "str")
main.py:11: error: Incompatible types in assignment (expression has type "None", variable has type "float")
Run Code Online (Sandbox Code Playgroud)
我可以 # type: ignore,但随后我丢失了编辑器中的类型提示和验证。我是否遗漏了一些明显的东西,还是应该为 FastAPI 项目禁用 mypy?
mypy ×10
python ×10
python-3.x ×4
fastapi ×1
liskov-substitution-principle ×1
overloading ×1
pydantic ×1
pyflakes ×1
types ×1