我应该让我的Python代码降低容错性以提高可读性吗?

6 投票
10 回答
1575 浏览
提问于 2025-04-15 17:22

我想让我的代码尽量不出错,但我发现这样写代码花了很多时间,读代码也变得更费劲。

比如,我本来可以这样写:

class TextServer(object):
    def __init__(self, text_values):
        self.text_values = text_values
        # <more code>
    # <more methods>

但我更倾向于这样写:

class TextServer(object):
    def __init__(self, text_values):
        for text_value in text_values:
            assert isinstance(text_value, basestring), u'All text_values should be str or unicode.'
            assert 2 <= len(text_value), u'All text_values should be at least two characters long.'
        self.__text_values = frozenset(text_values) # <They shouldn't change.>
        # <more code>
    @property
    def text_values(self):
        # <'text_values' shouldn't be replaced.>
        return self.__text_values
    # <more methods>

我这样写的风格是不是太过于小心翼翼了?有没有什么办法可以在保持代码不出错的同时,让它更容易读呢?

  • 注意 1:我在<>之间加的注释只是为了让大家更明白。
  • 注意 2:我最想防止的“傻瓜”就是未来的我自己

10 个回答

3

你的代码有点过于“小心翼翼”(特别是当你只是想保护自己时)。

在Python的圈子里,LBYL(即“先检查再使用”)通常(但并不总是)不太受欢迎。不过,还有一个(通常没有明说的)假设,就是大家都有(良好的)单元测试。

就我个人而言?我觉得代码的可读性非常重要。我的意思是,如果你自己觉得代码难以阅读,那别人会怎么想呢?而且可读性差的代码更容易出现错误。更不用说,这样的代码让你在处理时变得更加困难和耗时(你得花时间去弄清楚代码到底在做什么,因为有太多的LBYL)。

9

“我的Python编码风格是不是太小心翼翼了?有没有办法在保持代码安全的同时提高可读性?”

你在保护自己免受谁的伤害呢?

是你自己吗?你是不是担心自己忘记了自己写的API?

是同事吗?你是不是担心隔壁的同事会故意通过API传递错误的信息?其实你可以和他们沟通一下,这样能解决很多问题。如果你提供了文档,代码也会简洁很多。

还是说是个完全不负责任的人,他下载了你的代码,却不看API文档,然后用错误的参数调用所有方法?你能给他们提供什么帮助呢?

所谓的“防傻”编码其实并没有太大用处,因为这些情况可以用其他更简单的方法来解决。

如果你是为了防止自己出错,那可能就不太合理了。

如果是为了同事或伙伴,那你应该和他们沟通,确保他们理解API文档。

如果你是为了防范一个假想中的不负责任的程序员,他们想要破坏API,那你也无能为力。毕竟这是Python,他们可以直接查看源代码。既然可以直接修改源代码来搞事情,为什么还要费力去错误使用API呢?

12

这里有一些关于Python编程风格的好建议,来自这个页面


与其在代码中提前处理各种特殊情况,不如直接捕捉错误。这个编程风格叫做EAFP(“先请求原谅,而不是请求许可”),和LBYL(“先看再跳”)相对。这样做通常能让代码更易读。例如:

糟糕的写法:

#check whether int conversion will raise an error
if not isinstance(s, str) or not s.isdigit:
    return None
elif len(s) > 10:    #too many digits for int conversion
    return None
else:
    return int(str)

更好的写法:

try:
    return int(str)
except (TypeError, ValueError, OverflowError): #int conversion failed
    return None

(注意,在这个例子中,第二种写法要好得多,因为它能正确处理前面的+和-符号,以及32位机器上2到100亿之间的值。不要在代码中提前考虑所有可能出错的情况:直接尝试一下,并使用合适的错误处理方式。)

撰写回答