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

如何优雅解决业务代码中必须要重复的嵌套检查返回结果是否为 None?

  •  
  •   onelsas · 2017-03-06 16:09:03 +08:00 · 2388 次点击
    这是一个创建于 2819 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在改进学校学长学姐的一些项目,感觉代码结构组织的一团糟,现在又不好做大的修改。

    他们的代码一个明显的问题就是很多函数或者方法的调用,如果相关结果不对,就直接返回 None(或者 False)。这样的后果是,等程序真正出了问题的时候,除了一步步 debug我很难找到这个 None 到底是哪个地方返回的

    我现在的想法是重新修改代码,在有可能返回 None 的地方,我自己重新检查一遍返回结果是否为 None ,如果返回结果是 None 我自己另外再做处理。但是这样感觉写出的代码太丑陋了,代码里面充满if xxx is None式检查语句。

    请问 V 站各位前辈对于上面这种情况我应该如何优雅处理?

    12 条回复    2017-03-07 09:21:40 +08:00
    SpicyCat
        1
    SpicyCat  
       2017-03-06 16:58:02 +08:00
    这是异常处理?
    如果出异常了,需要中断处理,那么就抛异常。
    如果出异常了,可以继续执行,那么就忽略异常,一般就返回 None 了。
    Abirdcfly
        2
    Abirdcfly  
       2017-03-06 17:06:35 +08:00
    关键步骤记日志?
    onelsas
        3
    onelsas  
    OP
       2017-03-06 17:52:33 +08:00
    @SpicyCat @Abirdcfly
    他们的代码的本意应该就是出了异常,认为可以忽略异常,然后就返回 None 。但是这样的做法假设有一个函数或者方法,它被**嵌套**调用了多次,所以在一系列嵌套调用的过程必须每一次都要检查 None ,要不然等出了错就不知道异常到底是哪一步骤抛出来的。

    我现在有两种做法:
    1. 原本返回 None 的地方我不兼容异常,全部抛出
    2. 在返回 None 的地方做检查,并且记录日志,但是这样的话代码结构会很丑

    请问上面做法是否合理?
    linkdesu
        4
    linkdesu  
       2017-03-06 18:21:50 +08:00
    这个问题,我觉得可以等同于:请问 V 站各位前辈不得不吃屎时是如何优雅处理的?

    其中的煎熬难以言喻,其路漫漫,其修远兮~
    huigeer
        5
    huigeer  
       2017-03-06 19:05:30 +08:00
    @linkdesu 把鼻子堵上,
    lhw45202
        6
    lhw45202  
       2017-03-06 19:12:33 +08:00
    先为现有的业务逻辑建立一些测试用例,然后再开始修改现有实现,保证前面的测试用例通过,逐步修改
    guyskk
        7
    guyskk  
       2017-03-06 21:07:45 +08:00 via Android
    把需要用到的代码封装一下再用
    lxy
        8
    lxy  
       2017-03-06 21:20:01 +08:00
    装饰器不就是在这时候用的吗。
    cabing
        9
    cabing  
       2017-03-06 21:24:16 +08:00
    1 可以把一些逻辑拆出来。然后写单元测试~
    2 抛出异常,捕获异常写日志~~
    billgreen1
        10
    billgreen1  
       2017-03-06 21:30:32 +08:00
    try catch 就是这个时候用的啊。我一般是喜欢 在关键部分: try: except KeyError xxx except IndexError.....
    yunshansimon
        11
    yunshansimon  
       2017-03-06 22:20:53 +08:00
    Python 不熟,但 script 类语言应该都可以写一个调用函数的函数解决:_call_func 有 3 个参数,函数名,参数个数,参数对象数组(或集合什么的能放下所有种类对象的)。 用这个函数调用所有的其他函数,在这个函数里面检查返回值,如果是 none ,就抛出异常,或者打印函数名称。 对象方法也可以,重载_call_func 第一个参数是对象,第二个参数是对象的方法,其他一样。然后把所有直接调用都改成调用函数调用。
    lrh3321
        12
    lrh3321  
       2017-03-07 09:21:40 +08:00
    用日志打印出来吧,出问题 返回 None 之前,先把 当前的函数名打印出来,再返回。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1200 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 18:28 · PVG 02:28 · LAX 10:28 · JFK 13:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.