python 使用数据模型对象实现运算符并使用PyRight进行检查

piv4azn7  于 2024-01-05  发布在  Python
关注(0)|答案(1)|浏览(133)

我正在处理一个类,我必须实现算术运算符(+-*/),其中每个运算符都有多个重载,但重载都是相同的。我想我应该将其实现为数据模型对象,而不是将重载复制到每个运算符,沿着这样的路线:

  1. from typing import Callable as Fn, Any, overload
  2. import operator
  3. class Apply:
  4. """Apply an operator to an object."""
  5. def __init__(self, op: Fn[[Any, Any], Any], obj: Any) -> None:
  6. self.op = op
  7. self.obj = obj
  8. # Two mock overloads...
  9. @overload
  10. def __call__(self, x: int) -> str: ...
  11. @overload
  12. def __call__(self, x: str) -> int: ...
  13. def __call__(self, x: int | str) -> str | int:
  14. ...
  15. class Op:
  16. """Data model object for an operator."""
  17. def __init__(self, op: Fn[[Any, Any], Any]) -> None:
  18. self.op = op
  19. def __get__(self, obj: Any, _: Any) -> Apply:
  20. return Apply(self.op, obj)
  21. class Foo:
  22. __add__ = Op(operator.add)
  23. __mul__ = Op(operator.mul)
  24. foo = Foo()
  25. a: str = foo.__add__(2) # works fine
  26. b: int = foo.__mul__("2") # works fine
  27. _ = foo + 1 # type error
  28. _ = foo * "2" # type error

字符串
这个想法是让所有的操作符重载实现一次,并将动态行为分派到operator。这样,我就避免了样板代码的多个副本,并且我仍然可以获得所有带有重载类型注解的操作符。
但最后两行给予我类型错误,当我检查与pyright(playground).它似乎是工作与mypy,但我使用pylance+pyright为我的项目,宁愿不改变类型检查.
有没有办法让派莱特也能接受?

nzrxty8p

nzrxty8p1#

看起来pyright只需要一点额外的帮助(参见Pyright playground):

  1. class Op:
  2. """Data model object for an operator."""
  3. def __init__(self, op: Fn[[Any, Any], Any]) -> None:
  4. self.op = op
  5. def __get__(self, obj: Any, _: Any) -> Apply:
  6. return Apply(self.op, obj)
  7. __call__: Apply # Helper annotation

个字符

相关问题