python泛型类型提示+;用户定义的容器+;对实现_添加_方法的类型的约束
我想在Python3.8中实现一个Liste类,它采用Lisp方式,带有head和tail、car()、cdr()和nil。我想在列表中定义一个接受T类型对象的泛型类型python泛型类型提示+;用户定义的容器+;对实现_添加_方法的类型的约束,python,type-hinting,abstract-data-type,generic-type-argument,Python,Type Hinting,Abstract Data Type,Generic Type Argument,我想在Python3.8中实现一个Liste类,它采用Lisp方式,带有head和tail、car()、cdr()和nil。我想在列表中定义一个接受T类型对象的泛型类型 from __future__ import annotations from typing import TypeVar, Callable, Generic T = TypeVar('T') class Liste(Generic[T]): def __init__(self, h: T, t: Liste[T]
from __future__ import annotations
from typing import TypeVar, Callable, Generic
T = TypeVar('T')
class Liste(Generic[T]):
def __init__(self, h: T, t: Liste[T]) -> None:
self.head = h
self.tail = t
@staticmethod
def nil() -> Liste[T]:
return Liste(None, None)
def est_vide(self) -> bool:
return (self.head is None) and (self.tail is None)
def cdr(self)->Liste[T]:
if self.tail is None: return Liste.nil()
else: return self.tail
def sum(self)->T:
if self.est_vide():
return 0
else:
return self.head + self.cdr().sum()
一直以来,我在打字提示方面都玩得很开心。但mypy指出了4个错误
liste_sof.py:13: error: Argument 1 to "Liste" has incompatible type "None"; expected "T"
liste_sof.py:13: error: Argument 2 to "Liste" has incompatible type "None"; expected "Liste[T]"
liste_sof.py:23: error: Incompatible return value type (got "int", expected "T")
liste_sof.py:25: error: Unsupported left operand type for + ("T")
Found 4 errors in 1 file (checked 1 source file)
问题1是能够指定实现\uuuuu添加\uuuu
方法的T对象。我不知道怎么做
问题2是处理我的类的特殊Liste.nil()
empty对象
谢谢你的建议。Mypy抱怨是因为如果你想
h
或t
能够None
,你就需要使用可选的,否则,你就意味着一切都必须是None
,这不是通用的
您可以使用带有协议的结构化键入来表示“has\uuuuu add\uuuu
”
最后,没有干净的方法来获取“空对象”。对于内置类型,type(self)(
可能会起作用,但老实说,我会强制API采用初始值
from __future__ import annotations
from typing import TypeVar, Callable, Generic, Protocol, Optional
T = TypeVar('T')
class SupportsAdd(Protocol[T]):
def __add__(self: T, other: T) -> T:
...
A = TypeVar('A', bound=SupportsAdd)
class Liste(Generic[A]):
def __init__(self, h: Optional[A], t: Optional[Liste[A]]) -> None:
self.head = h
self.tail = t
@staticmethod
def nil() -> Liste[A]:
return Liste(None, None)
def est_vide(self) -> bool:
return (self.head is None) and (self.tail is None)
def cdr(self)->Liste[A]:
if self.tail is None: return Liste.nil()
else: return self.tail
def sum(self, init: A) -> A:
if self.head is None or self.tail is None:
return init
else:
return self.head + self.cdr().sum(init)
正如我在评论中所说,这门课非常学术,你可能不应该实际使用它。这将是低效的。至少,您不应该对sum
使用递归,问题3是找到实现\uuuuuuuuuuu添加\uuuuuuuu
方法的类t的空对象。对于str,我想要“”,对于int或float,0将是单独的问题。对于t
和h
,您需要使用可选,并且您可以使用协议来描述结构类型“supports add”。对于所有支持add的类型,没有干净的方法可以找到“空对象”。因此,您可以对想要支持的类型使用受限typevar,而不是通用协议。老实说,这个类将非常学术化。例如,sum
的实现对于大型列表不起作用。Python不是Lisp,它们是完全不同的语言。在python中,应该使用迭代而不是递归来实现这一点。另外,您不希望支持str
,因为这只会创建一个隐藏的二次时间算法,而在Pythonit中,用于连接str
对象的线性时间算法是微不足道的,这实际上是一个学术性的算法,并且还没有考虑到效率。谢谢你的回答!我猜是类列表(Generic[A]):
而不是类列表(Generic[T]):
在你的命题中?还是我遗漏了什么?@smeden大叫。对