如何用长串干净地保持80-字符宽度?

时间:2013-03-27 16:28:04

标签: python coding-style readability code-readability

我现在试图将我的代码保持在80个或更少的字符,因为我认为它在大多数情况下看起来更美观。但有时,如果我必须在奇怪的地方放置换行符,代码最终会变得更糟。

有一件事我还没弄清楚如何处理非常好的长串。例如:

#0.........1........2........3........4.........5.........6.........7.........8xxxxxxxxx9xxxxxx
def foo():
    if conditional():
        logger.info("<Conditional's meaning> happened, so we're not setting up the interface.")
        return

    #.....

结束了!把它放在下一行也无济于事:

#0.........1........2........3........4.........5.........6.........7.........8xxxxxxxxx9xxxxxx
def foo():
    if conditional():
        logger.info(
            "<Conditional's meaning> happened, so we're not setting up the interface.")
        return

    #.....

我可以使用换行符,但看起来很糟糕:

#0.........1........2........3........4.........5.........6.........7.........8
def foo():
    if conditional():
        logger.info(
            "<Conditional's meaning> happened, so we're not setting \
up the interface.")
        return

    #.....

怎么办?缩短字符串是一种选择,但我不希望我的消息的可读性受到与该代码恰好有多少缩进级别一样任意的影响。

1 个答案:

答案 0 :(得分:38)

您可以将字符串拆分为两个:

def foo():
    if conditional():
        logger.info("<Conditional's meaning> happened, so we're not "
                    "setting up the interface.")

同一表达式中的多个连续字符串会自动concatenated into one, at compile time

>>> def foo():
...     if conditional():
...         logger.info("<Conditional's meaning> happened, so we're not "
...                     "setting up the interface.")
... 
>>> import dis
>>> dis.dis(foo)
  2           0 LOAD_GLOBAL              0 (conditional)
              3 CALL_FUNCTION            0
              6 POP_JUMP_IF_FALSE       25

  3           9 LOAD_GLOBAL              1 (logger)
             12 LOAD_ATTR                2 (info)
             15 LOAD_CONST               1 ("<Conditional's meaning> happened, so we're not setting up the interface.")
             18 CALL_FUNCTION            1
             21 POP_TOP             
             22 JUMP_FORWARD             0 (to 25)
        >>   25 LOAD_CONST               0 (None)
             28 RETURN_VALUE        

注意第3行的LOAD_CONST,该函数的字节码包含已连接的一个字符串。

如果要在表达式中添加+,则会创建两个单独的常量:

>>> def foo():
...     if conditional():
...         logger.info("<Conditional's meaning> happened, so we're not " + 
...                     "setting up the interface.")
... 
>>> dis.dis(foo)
  2           0 LOAD_GLOBAL              0 (conditional)
              3 CALL_FUNCTION            0
              6 POP_JUMP_IF_FALSE       29

  3           9 LOAD_GLOBAL              1 (logger)
             12 LOAD_ATTR                2 (info)
             15 LOAD_CONST               1 ("<Conditional's meaning> happened, so we're not ")

  4          18 LOAD_CONST               2 ('setting up the interface.')
             21 BINARY_ADD          
             22 CALL_FUNCTION            1
             25 POP_TOP             
             26 JUMP_FORWARD             0 (to 29)
        >>   29 LOAD_CONST               0 (None)
             32 RETURN_VALUE        

Python在编译时(在+*-等)对字节编译器的窥孔优化进行了对常量的二进制运算。因此,对于某些字符串连接,编译器可能也将+常量字符串连接替换为连接结果。请参阅peephole.c,对于序列(包括字符串),仅当结果限制为20个项目(字符)或更少时才应用此优化。