有没有一种方法可以输入提示元素元组,而不必多次定义每个内部元素?
例子:
a = ((1, 2), (2, 3), (3, 4), (4, 5))
a: Tuple[Tuple[int, int], Tuple[int, int], Tuple[int, int], Tuple[int, int]]
Run Code Online (Sandbox Code Playgroud)
我正在寻找看起来像这样的东西
a: Tuple[5*Tuple[int, int]]
Run Code Online (Sandbox Code Playgroud)
否则我的代码会变得非常冗长,以便指示类似的内容(包含 5 个 4 个整数的元组的元组)
我有一个函数fun()接受 NumPy ArrayLike和“矩阵”,并返回 numpy 数组。
from numpy.typing import ArrayLike
import numpy as np
def fun(A, x: ArrayLike) -> np.ndarray:
return (A @ x) ** 2 - 27.0
Run Code Online (Sandbox Code Playgroud)
type对于有业务的实体,正确的是什么@?请注意,fun()也可以接受scipy.sparse;也许更多。
我有以下Foo基类,并且Bar继承自它:
class Foo:
def __init__(self, x: int) -> None:
self._x = x
def do(self, x: int) -> None:
pass
class Bar(Foo):
pass
Run Code Online (Sandbox Code Playgroud)
如果我重写Foo.doin Bar,并将参数的类型更改x为不兼容的内容(即不比 更通用int),那么 Mypy 将返回错误 - 这当然是我所期望的。
class Bar(Foo):
def do(self, x: str) -> None:
pass
Run Code Online (Sandbox Code Playgroud)
错误:
test.py:10: error: Argument 1 of "do" is incompatible with supertype "Foo"; supertype defines the argument type as "int"
test.py:10: note: This violates the Liskov substitution principle
test.py:10: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides …Run Code Online (Sandbox Code Playgroud) python types liskov-substitution-principle mypy python-typing
在以下代码中some_method已通过元类添加:
from abc import ABC
from abc import ABCMeta
from typing import Type
def some_method(cls, x: str) -> str:
return f"result {x}"
class MyMeta(ABCMeta):
def __new__(mcs, *args, **kwargs):
cls = super().__new__(mcs, *args, **kwargs)
cls.some_method = classmethod(some_method)
return cls
class MyABC(ABC):
@classmethod
def some_method(cls, x: str) -> str:
return x
class MyClassWithSomeMethod(metaclass=MyMeta):
pass
def call_some_method(cls: Type[MyClassWithSomeMethod]) -> str:
return cls.some_method("A")
if __name__ == "__main__":
mc = MyClassWithSomeMethod()
assert isinstance(mc, MyClassWithSomeMethod)
assert call_some_method(MyClassWithSomeMethod) == "result A"
Run Code Online (Sandbox Code Playgroud)
然而,MyPy对此很不满意:
minimal_example.py:27: error: …Run Code Online (Sandbox Code Playgroud) 这个问题是为了澄清我对 python 打字的疑问
from typing import Union
class ParentClass:
parent_prop = 1
class ChildA(ParentClass):
child_a_prop = 2
class ChildB(ParentClass):
child_b_prop = 3
def method_body(val) -> ParentClass:
if val:
return ChildA()
else:
return ChildB()
def another_method() -> ChildA:
return method_body(True)
print(another_method().child_a_prop)
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我使用的 linting 工具打印错误如下
error: Incompatible return value type (got "ParentClass", expected "ChildA")
Run Code Online (Sandbox Code Playgroud)
(我在哪里做method_body(True))
我还将method_body返回类型设置为 Union[ChildA, ChildB]. 这将导致error: Incompatible return value type (got "Union[ChildA, ChildB]", expected "ChildA")
我正在寻找更好的方法来做到这一点。如果有人知道解决方案,我们将非常感谢您的帮助。
下面的类有一个类方法create(),它作为返回类型的类型提示,用于创建该类的实例。
class X:
@classmethod
def create(cls) -> X:
pass
Run Code Online (Sandbox Code Playgroud)
然而,却出现了以下错误?
名称错误:名称“X”未定义
我遇到了以下代码:
def func(self, v: Tuple[Hashable]):
...
Run Code Online (Sandbox Code Playgroud)
我知道v: Tuple这意味着变量 v 必须是 Tuple 类型,但这Tuple[Hashable]意味着什么?Python 中的元组不是总是可哈希的吗?
Python 3.6之后,我们有了typing.NamedTuple,它是 的类型化版本collections.namedtuple(),我们可以像类一样继承它:
class Employee(NamedTuple):
name: str
id: int
Run Code Online (Sandbox Code Playgroud)
相比之下collections.namedtuple,这个语法更漂亮,但是我还是看不懂它的实现,无论是看typing.py文件,还是做一些简单的测试,我们都会发现它是一个函数而不是一个类:
# Python 3.10.6 typing.py
def NamedTuple(typename, fields=None, /, **kwargs):
"""..."""
if fields is None:
fields = kwargs.items()
elif kwargs:
raise TypeError("Either list of fields or keywords"
" can be provided to NamedTuple, not both")
try:
module = sys._getframe(1).f_globals.get('__name__', '__main__')
except (AttributeError, ValueError):
module = None
return _make_nmtuple(typename, fields, module=module)
Run Code Online (Sandbox Code Playgroud)
>>> type(NamedTuple)
<class 'function'>
Run Code Online (Sandbox Code Playgroud)
我知道它使用了一些元类魔法,但我不明白使用时会发生什么class MyClass(NamedTuple)。为此,我尝试自定义一个函数来继承:
>>> def func_for_inherit(*args, **kwargs):
... …Run Code Online (Sandbox Code Playgroud) 假设我有一个自定义用例,我需要动态创建或定义__init__数据类的方法。
例如,假设我需要像这样装饰它,@dataclass(init=False)然后修改__init__()方法以采用关键字参数,例如**kwargs. 但是,在kwargs对象中,我仅检查已知数据类字段是否存在,并相应地设置这些属性(下面的示例)
我想向我的 IDE (PyCharm) 键入提示,修改后的内容__init__仅接受列出的数据类字段作为参数或关键字参数。我不确定是否有办法解决这个问题,使用typing库或其他方式。我知道 PY3.11 已计划进行数据类转换,这可能会也可能不会满足我的要求(我的直觉是否定的)。
这是我正在使用的示例代码,这是一个基本案例,说明了我遇到的问题:
from dataclasses import dataclass
# get value from input source (can be a file or anything else)
def get_value_from_src(_name: str, tp: type):
return tp() # dummy value
@dataclass
class MyClass:
foo: str
apple: int
def __init__(self, **kwargs):
for name, tp in self.__annotations__.items():
if name in kwargs:
value = kwargs[name]
else:
# here …Run Code Online (Sandbox Code Playgroud) @dataclass(frozen=True, eq=True, order=True)
class C:
x: int
l = [C(1), C(2), C(1)]
print(sorted(l))
Run Code Online (Sandbox Code Playgroud)
上面的代码可以工作,但会发出警告:
Expected type 'Iterable' (matched generic type 'Iterable[SupportsLessThanT]'), got 'list[C]' instead。
我认为order=True传递给的参数@dataclass应该导致生成__lt__等,从而确认SupportsLessThanT?
显式实现可以__lt__使警告静音,但是如果不这样做,我该如何使其静音呢?
python ×10
python-typing ×10
type-hinting ×4
mypy ×3
liskov-substitution-principle ×1
metaclass ×1
namedtuple ×1
numpy ×1
pylint ×1
types ×1