假设我们要定义一个继承自 的自定义通用(基)类typing.Generic。
为了简单起见,我们希望它由单个类型变量 T来参数化。所以类的定义是这样开始的:
from typing import Generic, TypeVar
T = TypeVar("T")
class GenericBase(Generic[T]):
...
Run Code Online (Sandbox Code Playgroud)
T 有没有办法访问 的任何特定子类中的类型参数GenericBase?
该解决方案应该足够通用,能够在具有附加基础的子类中工作GenericBase,并且独立于实例化(即在类级别上工作)。
期望的结果是这样的类方法:
class GenericBase(Generic[T]):
@classmethod
def get_type_arg(cls) -> Type[T]:
...
Run Code Online (Sandbox Code Playgroud)
class Foo:
pass
class Bar:
pass
class Specific(Foo, GenericBase[str], Bar):
pass
print(Specific.get_type_arg())
Run Code Online (Sandbox Code Playgroud)
输出应该是<class 'str'>.
如果所有相关的类型注释都已完成,以便静态类型检查器可以正确推断get_type_arg.
我正在尝试理解通用函数。我知道这个话题已经被广泛讨论,但我似乎无法理解一些细节。
我正在尝试类似的事情,但更简单。我只想要一个double将参数乘以二的函数,并且我希望它适用于任何浮点或整数类型。到目前为止我有这个:
use std::convert::From;
use std::ops::Mul;
fn double<A>(x: A) -> A
where A: Mul<Output = A> + From<f32> {
return x * A::from(2f32);
}
Run Code Online (Sandbox Code Playgroud)
当我用 float (f32或f64) 调用它时,效果很好:
println!("{:?}", double(2f64));
Run Code Online (Sandbox Code Playgroud)
这给了我4.0。
但它对于任何整数类型都会失败,例如:
println!("{:?}", double(2i32));
Run Code Online (Sandbox Code Playgroud)
这会产生以下错误:
println!("{:?}", double(2i32));
------ ^^^^ the trait `From<f32>` is not implemented for `i32`
Run Code Online (Sandbox Code Playgroud)
我理解这个错误。没有通用的方法将浮点数转换为整数。如果我想2.5在我的函数内部而不是2.0.
我知道有这个TryFrom特性,但我不知道如何在这种情况下利用它。
我尝试了另一种方式,即需要A实现From<u32>,但这只是将错误从整数发生切换到浮点数发生。但令我惊讶的是,当我使用像 之类的有符号整数调用函数时,它也会导致错误2i32。
我缺少什么?如何实现double任何数字类型的通用函数?
我刚刚阅读了PEP 586。在动机中,作者这样说:
numpy.unique 将返回单个数组或包含两个到四个数组的元组,具体取决于三个布尔标志值。
(...)
目前无法表达这些函数的类型签名:PEP 484 不包含任何用于编写签名的机制,其中返回类型根据传入的值而变化。
我们建议添加文字类型来解决这些差距。
但我真的不明白添加Literal类型对此有什么帮助。而且我也不同意这样的说法
PEP 484 不包含任何用于编写签名的机制,其中返回类型根据传入的值而变化。
据我所理解,Union可以在这种情况下使用。
返回类型如何numpy.unique注释Literal?
以下作品;这是一个成功使用异步生成器作为固定装置的测试。
from collections.abc import AsyncGenerator
import pytest
@pytest.fixture()
async def fixture() -> AsyncGenerator[str, None]:
yield "a"
@pytest.mark.asyncio
async def test(fixture: str):
assert fixture[0] == "a"
Run Code Online (Sandbox Code Playgroud)
但是,假设我想fixture()返回AsyncGenerator由其他函数生成的结果。在这种情况下,我收到错误:
from collections.abc import AsyncGenerator
import pytest
async def _fixture() -> AsyncGenerator[str, None]:
yield "a"
@pytest.fixture()
async def fixture() -> AsyncGenerator[str, None]:
return _fixture()
@pytest.mark.asyncio
async def test(fixture: str):
assert fixture[0] == "a"
Run Code Online (Sandbox Code Playgroud)
错误是:
> assert fixture[0] == "a"
E TypeError: 'async_generator' object is not subscriptable
Run Code Online (Sandbox Code Playgroud)
我缺少什么?
我有一个类型T,namedtuple实际上是:
from collections import namedtuple
T = namedtuple('T', ('a', 'b'))
Run Code Online (Sandbox Code Playgroud)
list[T | None]我有一个接受 a和列表的函数:
def func(arg: list[T | None]):
...
l = [T(1, 2), T(2, 3)]
func(l) # Pylance error
Run Code Online (Sandbox Code Playgroud)
l属于 类型list[T]。
当我将 a 传递l给函数时,我从 Pylance 收到错误,指出 a 与list[T]不兼容,list[T | None]因为T cannot be assigned to T | None.
除了手动指定 mylist[T]实际上是 a之外list[T | None],我还能做些什么来使其正常工作而不出错?当然,在运行时一切都会按预期运行。
给出文档InventoryItem中的示例dataclasses。
from dataclasses import dataclass
@dataclass
class InventoryItem:
"""Class for keeping track of an item in inventory."""
name: str
unit_price: float
quantity_on_hand: int = 0
InventoryItem(name="Banana", unit_price=5, quantity_on_hand=3)
# OUTPUT:
# InventoryItem(name='Banana', unit_price=5, quantity_on_hand=3)
Run Code Online (Sandbox Code Playgroud)
如何覆盖标准输出消息,以便输出字符串
"3 Banana(s) at a unit price of 5."
Run Code Online (Sandbox Code Playgroud)
被展示?