我想在我当前的Python 3.5项目中使用类型提示.我的函数应该接收一个函数作为参数.
如何在类型提示中指定类型函数?
import typing
def my_function(name:typing.AnyStr, func: typing.Function) -> None:
# However, typing.Function does not exist.
# How can I specify the type function for the parameter `func`?
# do some processing
pass
Run Code Online (Sandbox Code Playgroud)
我检查了PEP 483,但在那里找不到函数类型提示.
现在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
?
我有:
\nfoo/\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 bar.py\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 baz\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 alice.py\n
Run Code Online (Sandbox Code Playgroud)\n在 中bar.py
,我导入 Alice,它是一个空类,除了name
属性设置为之外什么都没有"Alice"
。
from baz.alice import Alice\n\na = Alice()\nprint(a.name)\n
Run Code Online (Sandbox Code Playgroud)\n这可以正常运行:
\n$ python foo/bar.py\nAlice\n
Run Code Online (Sandbox Code Playgroud)\n但 mypy 抱怨道:
\n$ mypy --version\nmypy 0.910\n$ mypy --strict .\nfoo/bar.py:1: error: Cannot find implementation or library stub for module named "baz.alice"\nfoo/bar.py:1: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports\nFound 1 error in 1 file (checked 6 source files)\n
Run Code Online (Sandbox Code Playgroud)\n为什么 mypy 会抱怨?
\n我注意到python 3.5和python 3.6增加了很多关于静态类型检查的功能,所以我尝试使用以下代码(在python 3.6中,稳定版本).
from typing import List
a: List[str] = []
a.append('a')
a.append(1)
print(a)
Run Code Online (Sandbox Code Playgroud)
让我感到惊讶的是,python没有给我一个错误或警告,虽然1
附加到一个list
只应该包含字符串.Pycharm
检测到类型错误并给我一个警告,但它并不明显,它没有在输出控制台中显示,我害怕有时我可能会错过它.我想要以下效果:
那可能吗?也许mypy
可以做到,但我更喜欢使用python-3.6-style类型检查(比如a: List[str]
)而不是使用的注释风格(如# type List[str]
)mypy
.而且我很好奇是否在本机python 3.6中有一个切换来实现我上面提到的两点.
我想从 mypy 检查中排除一个文件夹。查看文档我在 mypy.ini 配置文件中尝试了以下配置
[mypy]
python_version = 3.8
exclude '/venv/'
Run Code Online (Sandbox Code Playgroud)
没有运气。
我想从 mypy 检查中排除我的虚拟环境。我只有一个来检查我写的代码。
这是 mypy 的错误吗?
我正在使用 mypy 0.901 和 mypy-extensions 0.4.3。我还使用 mypy vs-code 扩展 0.2.0。
例如:
def foo(bar: int = None):
pass
Run Code Online (Sandbox Code Playgroud)
当我检查bar
pycharm的类型/注释时,告诉我它是Optional[int]
.
bar: int = None
看起来更干净bar: Optional[int] = None
,尤其是当你有 10+ 个参数时。
那么我可以简单地省略Optional
吗?像 mypy 或其他 linter 这样的工具是否会将这种情况突出显示为错误?
看起来python本身不喜欢这个想法:
In [1]: from typing import Optional
In [2]: from inspect import signature
In [3]: def foo(a: int = None): pass
In [4]: def bar(a: Optional[int] = None): pass
In [5]: signature(foo).parameters['a'].annotation
Out[5]: int
In [6]: signature(bar).parameters['a'].annotation
Out[6]: typing.Union[int, NoneType]
Run Code Online (Sandbox Code Playgroud) 我正在尝试输入 Hint the function bar
,但是Too few arguments
当我运行 mypy.txt 时出现错误。
from typing import Callable, Optional
def foo(arg: int = 123) -> float:
return arg+0.1
def bar(foo: Callable[[int], float], arg: Optional[int] = None) -> float:
if arg:
return foo(arg)
return foo()
print(bar(foo))
print(bar(foo, 90))
Run Code Online (Sandbox Code Playgroud)
我也尝试过:
Callable[[], float]
(出现Too many arguments
错误)Callable[[Optional[int]], float]
(又出现一个错误)那么,我应该如何进行函数的类型提示呢bar
?
mypy非常方便并且捕获了很多错误,但是当我编写"科学"应用程序时,我经常最终会这样做:
def my_func(number: Union[float, int]):
# Do something
Run Code Online (Sandbox Code Playgroud)
number
是浮点数还是int,具体取决于用户的输入.有官方的方法吗?
最近我一直在使用Typescript,它允许表达如下内容:
interface Address {
street: string;
housenumber: number;
housenumberPostfix?: string;
}
interface Person {
name: string;
adresses: Address[]
}
const person: Person = {
name: 'Joe',
adresses: [
{ street: 'Sesame', housenumber: 1 },
{ street: 'Baker', housenumber: 221, housenumberPostfix: 'b' }
]
}
Run Code Online (Sandbox Code Playgroud)
非常简洁,并在使用人员编码时将所有奢侈品作为类型检查和代码完成.
这是如何在Python中完成的?
我一直在看Mypy和ABC但是还没有成功找到pythonic方式做类似上面的事情(我的尝试导致了太多的样板符合我的口味).
mypy ×10
python ×10
type-hinting ×6
python-3.x ×4
python-3.10 ×1
python-3.5 ×1
python-3.6 ×1
typescript ×1
virtualenv ×1