以下代码mypy按预期被拒绝:
def foo(value: int) -> None:
print(value, type(value))
foo(None)
Run Code Online (Sandbox Code Playgroud)
输出:
error: Argument 1 to "foo" has incompatible type "None"; expected "int"
Run Code Online (Sandbox Code Playgroud)
但是在引入了一个默认参数之后None,就没有错误了:
def foo(value: int=None) -> None:
print(value, type(value))
foo(None)
Run Code Online (Sandbox Code Playgroud)
如果我们从to更改,我希望mypy只允许None(作为参数和默认值),但似乎不需要这样做。为什么?valueintOptional[int]
假设我有一些代码
def get_x(d: dict) -> int:
d["x"]
Run Code Online (Sandbox Code Playgroud)
但是,我想告诉 mypyd应该只包含某些键(例如只有“x”键)。这样,如果我在尝试引用无效键的代码中犯了错误d,mypy 将触发错误。
我的问题是:
我很困惑为什么不像上面两个FooBar.__mro__那样显示<class '__main__.Parent'>。
在深入研究 CPython 源代码后,我仍然不知道为什么。
from typing import NamedTuple
from collections import namedtuple
A = namedtuple('A', ['test'])
class B(NamedTuple):
test: str
class Parent:
pass
class Foo(Parent, A):
pass
class Bar(Parent, B):
pass
class FooBar(Parent, NamedTuple):
pass
print(Foo.__mro__)
# prints (<class '__main__.Foo'>, <class '__main__.Parent'>, <class '__main__.A'>, <class 'tuple'>, <class 'object'>)
print(Bar.__mro__)
# prints (<class '__main__.Bar'>, <class '__main__.Parent'>, <class '__main__.B'>, <class 'tuple'>, <class 'object'>)
print(FooBar.__mro__)
# prints (<class '__main__.FooBar'>, <class 'tuple'>, <class 'object'>)
# expecting: (<class '__main__.FooBar'>, <class …Run Code Online (Sandbox Code Playgroud) 这三个函数的返回类型提示有什么区别吗?
def my_func1():
print("Hello World")
return None
def my_func2():
print("Hello World")
return
def my_func3():
print("Hello World")
Run Code Online (Sandbox Code Playgroud)
它们是否都应该有-> None返回类型提示,因为这就是它们实际上显式或隐式返回的内容?或者应该my_func2或my_func3实际上没有返回类型提示?
问这个问题的动机是这个问题,这个很好的答案,以及我正在学习Type Hints的事实。
如何正确编写返回类型被装饰器修改的函数的类型?
简单的例子:
def example_decorator(fn):
def wrapper(data):
res = fn(data)
return ', '.join(res)
return wrapper
@example_decorator
def func(data: list): # -> ???? str ? list ?
new_data = data
new_data.append('XYZ')
return new_data
# When we type func -> list
def test() -> str:
result = func(['ABC', 'EFG'])
print(type(result)) # <class 'str'>
return result # Incompatible return type [7]: Expected str but got list.
test()
Run Code Online (Sandbox Code Playgroud) 如何正确键入注释下面的函数?
def f(cls: type) -> ???:
return cls()
# Example usage:
assert f(int) == 0
assert f(list) == []
assert f(tuple) == ()
Run Code Online (Sandbox Code Playgroud)
有没有一种方法可以???使用涉及值的内容进行类型注释cls,而不仅仅是Any或省略返回类型注释?如果我必须更改参数的类型注释也可以cls。
我知道标题很混乱,所以让我以二叉搜索树为例:
# This code passed mypy test
from typing import Generic, TypeVar
T = TypeVar('T')
class BST(Generic[T]):
class Node:
def __init__(
self,
val: T,
left: 'BST.Node',
right: 'BST.Node'
) -> None:
self.val = val
self.left = left
self.right = right
Run Code Online (Sandbox Code Playgroud)
上面的代码通过了mypy测试。
dataclass但是,当我尝试使用dataclass来简化 的定义时Node,代码在 mypy 测试中失败了。
# This code failed to pass mypy test
from dataclasses import dataclass
from typing import Generic, TypeVar
T = TypeVar('T')
class BST(Generic[T]):
@dataclass
class Node:
val: …Run Code Online (Sandbox Code Playgroud) 今天,我遇到了一个用 暗示的函数类型type。
我已经做了一些关于何时应该使用type或键入提示的研究Type,但我找不到满意的答案。根据我的研究,两者之间似乎存在一些重叠。
我的问题:
type和 和有什么区别Type?type显示何时使用vs 的示例用例是什么Type?研究
Type查看(from typingtag 3.7.4.3)的来源,我可以看到:
Run Code Online (Sandbox Code Playgroud)# Internal type variable used for Type[]. CT_co = TypeVar('CT_co', covariant=True, bound=type) # This is not a real generic class. Don't use outside annotations. class Type(Generic[CT_co], extra=type): """A special construct usable to annotate class objects. ```
它看起来Type可能只是 的别名type,但它支持Generic参数化。它是否正确?
例子
这是使用Python==3.8.5和制作的一些示例代码mypy==0.782:
from typing …Run Code Online (Sandbox Code Playgroud) EAFP
请求原谅比请求许可更容易。这种常见的 Python 编码风格假设存在有效的键或属性,并在假设证明错误时捕获异常。这种干净快速的风格的特点是存在许多 try 和 except 语句。该技术与许多其他语言(例如 C)常见的 LBYL 风格形成对比。
米皮
mypy是什么?
Mypy 是 Python 的可选静态类型检查器。您可以向 Python 程序添加类型提示 ( PEP 484 ),并使用 mypy 对它们进行静态类型检查。甚至无需运行程序即可找到程序中的错误!
您可以在程序中混合动态和静态类型。当静态类型不方便时(例如遗留代码),您始终可以回退到动态类型。
这是有关 EAFP 的精彩 YouTube 视频: https: //youtu.be/x3v9zMX1s4s
我正在尝试使用mypy,但基本上每次我编写一些 EAFP 代码时它都会生气。
例如:
from contextlib import suppress
from typing import Optional
class MyClass:
def __init__(self):
self.__name: Optional[str] = None
@property
def name(self) -> Optional[str]:
return self.__name
@name.setter
def name(self, name: str):
self.__name = name
@property
def upper_name(self) -> Optional[str]:
with …Run Code Online (Sandbox Code Playgroud) 这是 Python 扩展或包装函数中的常见模式,用于**kwargs将所有关键字参数传递给扩展函数。
即采取
class A:
def bar(self, *, a: int, b: str, c: float) -> str:
return f"{a}_{b}_{c}"
class B(A):
def bar(self, **kwargs):
return f"NEW_{super().bar(**kwargs)}"
def base_function(*, a: int, b: str, c: float) -> str:
return f"{a}_{b}_{c}"
def extension(**kwargs) -> str:
return f"NEW_{base_function(**kwargs)}"
Run Code Online (Sandbox Code Playgroud)
现在调用extension(not_existing="a")orB().bar(not_existing="a")会导致TypeError, 可以被静态类型检查器检测到。
如何在运行代码之前注释我的extension或B.bar以便检测到此问题?
此注释也有助于 IDE 为我提供有关extensionor 的正确建议B.bar。
python ×10
python-typing ×10
mypy ×4
python-3.x ×3
type-hinting ×2
duck-typing ×1
generics ×1
namedtuple ×1
nonetype ×1
pyre-check ×1
python-mro ×1