我试图理解类型注释,我有以下代码:
from typing import TypeVar
T = TypeVar('T')
class MyClass():
x: int = 10
def foo(obj: T) -> None:
print(obj.x)
foo(MyClass())
Run Code Online (Sandbox Code Playgroud)
当我运行 mypy 时,出现以下错误:
main.py:9: error: "T" has no attribute "x"
Found 1 error in 1 file (checked 1 source file)
Run Code Online (Sandbox Code Playgroud)
但是当我添加bound='MyClass'到时TypeVar,它没有显示任何错误。
这种行为的原因是什么?我尝试阅读文档,但没有找到任何关于bound设置为默认值时到底发生了什么的答案。
我的代码看起来像这样,BDW 运行良好,没有任何错误
from typing import Literal
def verify(word: str) -> Literal['Hello XY']:
a = 'Hello ' + word
return a
a = verify('XY')
Run Code Online (Sandbox Code Playgroud)
虽然,当我尝试使用 mypy 进行类型检查时,它会抛出错误error: Incompatible return value type (got "str", expected "Literal['Hello XY']")
注意:要执行类型检查mypy ./filename.py,只需在 pip 安装 mypy 后执行 。
另外,当我这样做时,类型检查工作正常
from typing import Literal
def verify(word: str) -> Literal['Hello XY']:
a = 'Hello ' + word
return 'Hello XY' #changed here
a = verify('XY')
Run Code Online (Sandbox Code Playgroud)
我缺少什么?
在编写代码时,我遇到过表达类型的 linter ~<type>(其中<type>类型不是<type>文学的)。一个例子是self。
class A:
def foo(self):
reveal_type(self) # reveals "~A"
Run Code Online (Sandbox Code Playgroud)
我认为这意味着“A或”的子类A;但是,我在网上找不到任何有关它的信息。
另外,您不能在代码中使用以下语法:
a: ~A # raises an exception: TypeError: bad operand type for unary ~: 'type'
Run Code Online (Sandbox Code Playgroud)
如果a会被揭露的话那就是了Unknown。
所以我知道Python的typing.Optional. 但我编写了自己的粗略代码PyOptional(此处为代码),并希望Optional[T]与我的PyOptionalto结合起来PyOptional[T]。
我目前正在使用 Python 3.7 并尝试扩展typing.Optional.
我的一些PyOptional:
class PyOptional:
T: TypeVar = TypeVar("T")
def __init__(self, obj: T):
self.value: Any = obj
def get(self) -> Optional[T]:
return self.value
def or_else(self, default) -> T:
return self.value or default
Run Code Online (Sandbox Code Playgroud)
我想要的伪代码:
def find_user_by_id(id: int) -> PyOptional[User]:
return PyOptional(db.find_user_by_id(id))
Run Code Online (Sandbox Code Playgroud)
我的目标是让 IDE 能够检查预期的返回类型,并且仍然能够在返回的对象上调用我的方法。因此它必须符合 PEP 要求。
假设我有一个函数do_something:
from typing import Sequence, Tuple, Dict
def do_something(argument: Sequence[Tuple[int, str]]):
pass
Run Code Online (Sandbox Code Playgroud)
假设我还有一个字典 ,D其键仅是ints,其值仅是strs:
D: Dict[int, str] = {1: 'a', 2: 'b', 3: 'c'}
Run Code Online (Sandbox Code Playgroud)
在 PyCharm 中,这将出色地通过类型检查器:
do_something(
((1, 'a'), (2, 'b'), (3, 'c'))
)
Run Code Online (Sandbox Code Playgroud)
但是,根据 PyCharm 的说法,尽管它产生的结果是相同的,但类型检查器却失败了:
do_something(tuple(D.items()))
Run Code Online (Sandbox Code Playgroud)
这是预期的行为吗——我在这里遗漏了什么吗?-- 或者这是 PyCharm 类型检查器的错误?
我有一个对象列表Person,我想根据一个人的名字检查一个人是否存在。除了这个循环之外,还有更简单的方法吗?
class Person:
def __init__(self, name):
self.name = name
found = False
for p in person_list:
if p.name == "Alan":
found = True
break
Run Code Online (Sandbox Code Playgroud) 我有一个代表标准化内存量的类。
class MemoryUnit(enum.Enum):
"""Units of memory."""
GB = 'GB'
TB = 'TB'
PB = 'PB'
Run Code Online (Sandbox Code Playgroud)
class Memory(BaseModel):
"""Normalized amount of memory."""
amount: int
unit: MemoryUnit
Run Code Online (Sandbox Code Playgroud)
现在我想为这个班级实现基本算术。加法、减法和乘法很容易注释:
def __add__(self, other: Memory) -> Memory: ...
def __sub__(self, other: Memory) -> Memory: ...
def __mul__(self, other: int) -> Memory: ...
Run Code Online (Sandbox Code Playgroud)
不过,我对分裂有疑问。我看到除法的两个用例:
Memory并Memory得到 a float(两个存储量之间的比率是多少)。Memory并int得到(如果均匀除以Memory的数量是多少)Memorynmypy 有没有办法用这个特定的签名来注释函数?
我正在编写一个函数来帮助处理一个可选的依赖项(类似于pytest.importorskip),我想输入它,但不确定要使用什么类型。因为我总是返回一个特定的模块或 None,我想我可以比“Any”更具体。
def try_import_pyarrow():
try:
import pyarrow
except ImportError:
pyarrow = None
return pyarrow
Run Code Online (Sandbox Code Playgroud) 当尝试将旧 PyTorch 编写的代码转换为 1.9 时,我收到此错误:
(fashcomp) [jalal@goku fashion-compatibility]$ python main.py --name test_baseline --learned --l2_embed --datadir ../../../data/fashion/
/scratch3/venv/fashcomp/lib/python3.8/site-packages/torchvision/transforms/transforms.py:310: UserWarning: The use of the transforms.Scale transform is deprecated, please use transforms.Resize instead.
warnings.warn("The use of the transforms.Scale transform is deprecated, " +
+ Number of params: 3191808
<class 'torch.utils.data.dataloader.DataLoader'>
/scratch3/venv/fashcomp/lib/python3.8/site-packages/torch/nn/functional.py:718: UserWarning: Named tensors and all their associated APIs are an experimental feature and subject to change. Please do not use them for anything important until they are released as stable. (Triggered internally …Run Code Online (Sandbox Code Playgroud) 我怀疑答案是肯定的,但我想问清楚。例如,如果我有一个函数需要使用一个numpy对象,但我没有numpy直接在我的模块中使用,我可以使用前向引用来键入提示我的参数而不是numpy直接导入吗?
换句话说(假设Python 3.7+),我可以这样做吗
# forward-reference.py
def my_func(arr: "np.ndarray") -> int:
# does some operations with arr
Run Code Online (Sandbox Code Playgroud)
而不是这个
# direct-import.py
import numpy as np
def my_func(arr: np.ndarray) -> int:
# do some operations on arr...
Run Code Online (Sandbox Code Playgroud)
我无法想象核心开发人员会要求程序员仅仅为了类型提示而导入模块。我pylint的或flake8linter 会正确地将它们拾取为未使用的模块,我认为所有这些额外的导入将是相当多余的。
为了测试,我创建了两个文件:demo1.py和demo2.py(都位于同一目录中):
# demo1.py
import numpy as np
from demo2 import my_func
if __name__ == "__main__":
a = np.array([1, 2, 3])
print(my_func(a))
Run Code Online (Sandbox Code Playgroud)
# demo2.py
def my_func(arr: "np.ndarray") -> …Run Code Online (Sandbox Code Playgroud) python ×10
type-hinting ×7
mypy ×4
python-3.x ×3
generics ×1
pycharm ×1
pytorch ×1
tensor ×1
typechecking ×1