22

ほとんどの場合、見た目がより美しく見えると思うので、最近はコードを 80 文字以下に抑えようとしています。ただし、変な場所に改行を入れなければならない場合、コードの見栄えが悪くなってしまうことがあります。

まだうまく処理する方法を理解していないことの 1 つは、長い文字列です。例えば:

#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 つのオプションですが、メッセージの読みやすさが、その時点でたまたまコードにいくつのインデント レベルがあったかという恣意的なものによって影響を受けることを望んでいません。

4

1 に答える 1

38

文字列を 2 つに分割できます。

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

同じ式内の複数の連続する文字列は、コンパイル時に自動的に 1 つに連結されます

>>> 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関数のバイトコードには、既に連結された1 つの文字列が含まれています。

式にa を追加する+と、2 つの別個の定数が作成されます。

>>> 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 は、バイト コンパイラのピープホール最適化で、コンパイル時に定数 ( so 、 など) のバイナリ操作を折りたたみ+ます。そのため、特定の文字列連結の場合、コンパイラは定数の文字列連結を連結結果に置き換えることもあります。を参照してください。シーケンス (文字列を含む) の場合、この最適化は、結果が 20 項目 (文字) 以下に制限されている場合にのみ適用されます。*-+peephole.c

于 2013-03-27T16:28:54.903 に答える