V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
lanlanye
V2EX  ›  Python

Python 加入类型注解后,父类到子类的强制转换怎么处理?

  •  
  •   lanlanye ·
    laipz8200 · 2022-07-06 17:14:08 +08:00 · 1878 次点击
    这是一个创建于 653 天前的主题,其中的信息可能已经有所发展或是发生改变。

    先贴代码:

    class AbstractMapper(ABC):
    
        def __init__(self):
            self._loaded_map: Dict["ObjectId", "DomainObject"] = {}
    
        def _abstract_find(self, id_: "ObjectId") -> "DomainObject":
            stmt = self.find_statement()
            try:
                rs = cursor.execute(stmt, (id_,)).fetchone()
                res = self._load(rs)
                return res
            except Exception as e:
                ...
            finally:
                ...
    
        def _load(self, rs: tuple) -> "DomainObject":
            if rs[0] in self._loaded_map:
                return self._loaded_map[rs[0]]
            res = self._do_load(rs)
            self._loaded_map[res.id] = res
            return res
    
        @abstractmethod
        def _do_load(self, rs: tuple) -> "DomainObject":
            ...
    
        @abstractmethod
        def find_statement(self) -> str:
            ...
    
    
    class ArtistMapper(AbstractMapper):
    
        def find_statement(self) -> str:
            return "select id, name from artists where id = $1 limit 1"
    
        def _do_load(self, rs: tuple) -> "DomainObject":
            id_ = rs[0]
            name = rs[1]
            return Artist(id_, name)
    
        def find(self, id_) -> "Artist":
            return self._abstract_find(id_)  # Expression of type "DomainObject" cannot be assigned to return type "Artist"   "DomainObject" is incompatible with "Artist"
    

    上面的代码中,_abstract_find() 的返回值标注为 DomainObject 类型,而在 ArtistMapper 中 find 方法需要返回一个 Artist 实例,Artist 是 DomainObject 的子类。

    我看到 Java 代码中这里是通过强制类型转换解决的,Python 中这样的代码虽然可以正确运行,但无法通过静态类型检查,想知道有什么办法可以通过检查?

    shyrock
        1
    shyrock  
       2022-07-06 17:29:26 +08:00
    Artist 跟 DomainObject 什么关系?
    lanlanye
        2
    lanlanye  
    OP
       2022-07-06 17:51:22 +08:00
    @shyrock Artist 继承自 DomainObject
    heqing
        3
    heqing  
       2022-07-06 18:20:50 +08:00   ❤️ 1
    使用 Generic
    hsfzxjy
        4
    hsfzxjy  
       2022-07-06 18:33:10 +08:00 via Android   ❤️ 1
    粗暴点就用 typing.cast ,规范点就给 AbstractMapper 加范型参数
    t2jk4000
        5
    t2jk4000  
       2022-07-08 09:04:59 +08:00
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1211 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 18:09 · PVG 02:09 · LAX 11:09 · JFK 14:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.