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
xuegy
V2EX  ›  Python

如何分离屎山中 Union 类型的变量

  •  
  •   xuegy · 1 天前 · 499 次点击

    正在处理一座屎山,大概情况是这样的。有一个自定义的class X,需要改掉的东西注释写的是y=Union[X, str],实际情况也是两种类型到处都混在一起根本分不清。后面所有跟X类有关的方法一点注释没写,甚至都不做类型判断,而是大量的使用getattr(y, 'name', y)把水搅得更浑(如果y是字符串,没有name,返回字符串本身。否则返回y.name也是一个字符串)。最离谱的是整座屎山还配了一套 30 分钟才能跑完的 pytest 。

    现在需要把混乱的y分成确定类型的yy_str,使用 pydantic 强制定义数据类型来一点点排错。然而改了几百行以后,所有跟X有关的方法都被迫改出两种版本的。pytest 不再报类型错误了,却开始出现各种离奇的 bug 挂掉。

    有什么更强大的工具可以搞定这件事吗?比如同步检测两个版本的代码,看从哪一步开始两边的数据变得不一致了?

    第 1 条附言  ·  1 天前

    项目背景是一个生物博士毕设的Python代码商业化后形成的屎山。所以写成这样不意外,能跑起来才是意外。

    chaoshui
        1
    chaoshui  
       1 天前
    交给 AI
    xuegy
        2
    xuegy  
    OP
       1 天前
    @chaoshui 用 GPT o4-mini-high 也无力回天
    huangyezhufeng
        3
    huangyezhufeng  
       1 天前
    其实从开始用`Union`开始,就已经把潘多拉魔盒打开了一半。再用`getattr`,几乎是不可避免地成为屎山了。

    为了避免误解,补充说明一下,用`Union`和`getattr`都没问题,前提是会用。从这个半个钟的单测来看,似乎并不是如此。
    Syiize
        4
    Syiize  
       18 小时 25 分钟前
    可以重写 class X 中的魔术方法 __getattribute__,如果要访问的属性是 "name",就 raise RuntimeError 。然后运行代码,再根据 Python 的 traceback 定位到对应的位置修改。
    xuegy
        5
    xuegy  
    OP
       15 小时 36 分钟前 via iPad
    @huangyezhufeng 字里行间甚至能看出来原作者对于 getattr 这个小聪明还挺自豪的
    xuegy
        6
    xuegy  
    OP
       15 小时 29 分钟前 via iPad
    @Syiize 这个不行吧,是真的需要查询 y.name 。我隐约感觉整个代码的真实运行逻辑就是建立在 getattr 大乱炖的基础之上。
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5593 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 02:35 · PVG 10:35 · LAX 19:35 · JFK 22:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.