我已经将我真正想要注释的代码简化为这个最小版本:
def print_it(numbers_or_nones):
for i, number in enumerate(numbers_or_nones):
if number is None:
numbers_or_nones[i] = 0
print("NOOOO")
else:
print(number)
numbers = [1, 2, 3, 4]
print_it(numbers)
Run Code Online (Sandbox Code Playgroud)
numbers_or_nones我想对的参数进行注释print_it。它需要...
Optional[int]对于这种情况,正确的类型是什么?请注意,无法更改 的类型numbers : List[int]。我能看到的唯一选择是使用typing.overload.
最简单的事情是List[Optional[int]]。然而,这给出了:
error: Argument 1 to "print_it" has incompatible type "List[int]"; expected "List[Optional[int]]"
note: "List" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance
note: Consider using "Sequence" instead, which is covariant
Run Code Online (Sandbox Code Playgroud)
Unsupported target for indexed assignment ("Sequence[Optional[int]]")
Run Code Online (Sandbox Code Playgroud)
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”(抑制了 …
PEP 647引入了类型防护来使用函数执行复杂的类型缩小操作。如果我有一个属性可以具有各种类型的类,是否有一种方法可以对作为函数参数给出的对象的属性执行类似的类型缩小操作?
class MyClass:
"""
If `a` is `None` then `b` is `str`
"""
a: Optional[int]
b: Optional[str]
# Some other things
def someTypeGuard(my_obj: MyClass) -> ???:
return my_obj.a is not None
Run Code Online (Sandbox Code Playgroud)
我想我可能有必要在类型提示中实现一些与方括号有关的东西,但我真的不知道从哪里开始。
我想做这样的事情:
from typing import TypeVar, Generic, TypedDict
T = TypeVar("T")
class Foo(Generic[T], TypedDict):
bar: T
...
foo: Foo[int] = {"bar": 42}
Run Code Online (Sandbox Code Playgroud)
但这会产生类型错误(“不能同时从 TypedDict 和非 TypedDict 基类继承”)。
有什么方法可以达到这个结果吗?
在 Python 3.9+ 中,我可以编写list_of_integers: list[int],但我看到高级开发人员使用旧语法(即使在 Python 3.9 和 3.10 脚本中):
from typing import List
list_of_integers: List[int]
Run Code Online (Sandbox Code Playgroud)
这对于向后兼容性和明确性来说是否优越?
我很好奇Python 3 中是否有一种方法可以提示__getattr__()Python 中方法的返回类型。
我有以下用于测试目的的虚拟代码:
class MyClass:
def __getattr__(self, item: str) -> str:
return 'test'
def __getattribute__(self, item: str) -> str:
return 'test'
c = MyClass()
print(c.hello, type(c.hello)) # test <class 'str'>
Run Code Online (Sandbox Code Playgroud)
不幸的是,Pycharm 无法解析hello上面的属性类型。我不确定,但我认为它目前是按Any类型处理的。
我还对上述代码提出了以下变体,但仍然无法使类型提示按预期工作:
from typing import Callable
ReturnsString = Callable[[], str]
class MyClass:
my_test_fn: ReturnsString = lambda self: 'hello'
__getattr__: ReturnsString = lambda self, _item: 'test'
__getattribute__: ReturnsString
c = MyClass()
# type hinting works as expected - return type is `str` …Run Code Online (Sandbox Code Playgroud) 在Java C#中,泛型方法可以具有带约束的类型参数,以定义必须实现的接口。
static <T extends Iterable<Integer> & Comparable<Integer>> void test(T p) {
}
Run Code Online (Sandbox Code Playgroud)
在Python中,如果我想使用类型提示来指定变量必须继承类A和B,我该怎么做?我检查了输入模块,它只有一个Union,这意味着变量的类型可以是任何提示,而不能是所有提示。
创建一个继承A和B的新类C似乎是一个解决方案,但看起来很麻烦。
我希望能够定义列表子类的内容。该类将如下所示。
class A(list):
def __init__(self):
list.__init__(self)
Run Code Online (Sandbox Code Playgroud)
我想包括打字,以便发生以下情况。
import typing
class A(list: typing.List[str]): # Maybe something like this
def __init__(self):
list.__init__(self)
>> a = A()
>> a.append("a") # No typing error
>> a.append(1) # Typing error
Run Code Online (Sandbox Code Playgroud) 我有一个装饰器,可以将用户添加到 Flask 全局上下文 g:
class User:
def __init__(self, user_data) -> None:
self.username: str = user_data["username"]
self.email: str = user_data["email"]
def login_required(f):
@wraps(f)
def wrap(*args, **kwargs):
user_data = get_user_data()
user = User(user_data)
g.user = User(user_data)
return f(*args, **kwargs)
return wrap
Run Code Online (Sandbox Code Playgroud)
我希望在控制器中访问 g.user 时知道 g.user 的类型(用户)。我怎样才能做到这一点?(我正在使用pyright)
鉴于:
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3
Run Code Online (Sandbox Code Playgroud)
Foo是否存在这样的类型表达式:
Foo[Color] = Literal["RED", "GREEN", "BLUE"]
Run Code Online (Sandbox Code Playgroud) python ×10
python-typing ×10
mypy ×2
python-3.x ×2
enums ×1
flask ×1
getattr ×1
list ×1
pyright ×1
subclass ×1
type-hinting ×1
typeguards ×1