2013-03-27 6 views
21

Próbuję zachować mój kod do 80 znaków lub mniej obecnie, ponieważ myślę, że wygląda bardziej estetycznie, w przeważającej części. Czasami jednak kod kończy się wyglądać gorzej, jeśli muszę wstawiać podziały linii w dziwnych miejscach.Jak zachować czystość poniżej 80-znakowej szerokości przy długich łańcuchach?

Jedna rzecz, której nie zrozumiałem, jak radzić sobie bardzo ładnie, ale to długie struny. Na przykład:

#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 

    #..... 

To już koniec! Wprowadzenie go w następnej linii nie pomoże albo:

#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 

    #..... 

mogę używać podziałów wierszy, ale że wygląda okropnie:

#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 

    #..... 

Co robić? Skrócenie łańcucha jest jedną z opcji, ale nie chcę, aby na czytelność moich wiadomości wpływało coś tak arbitralnego, jak wiele poziomów wcięć, które kod miał w tym momencie.

Odpowiedz

37

można podzielić ciąg na dwie części:

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

wiele kolejnych ciągów w tej samej wypowiedzi są automatycznie 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   

Zanotuj LOAD_CONST dla linii 3, kod bajtowy dla funkcji zawiera jeden ciąg znaków, już połączony.

Jeśli było dodać + do wyrażenia, dwie oddzielne stałe tworzone są:

>>> 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 robi krotnie operacje binarne na stałe w czasie kompilacji (tak +, *, - itd.), W optymalizacja peephole dla kompilatora bajtów. Tak więc dla niektórych konkatenacji ciągów kompilator może także zastąpić ciąg konkatenacji stałych ze złączonym wynikiem. Zobacz peephole.c, dla sekwencji (w tym ciągi) ta optymalizacja jest stosowana tylko wtedy, gdy wynik jest ograniczony do 20 elementów (znaków) lub mniej.

+0

Chociaż jest automatyczne łączenie, nadal wolę dodawać "+" dla jasności. W każdym razie +1. – orlp

+0

Ach, miło, to może być to. Czy z ciekawości jest to robione w czasie parsowania lub w czasie wykonywania? – Claudiu

+4

@ noccracker: * kompilator * scala ciągi. Za pomocą '+' przeniesiesz konkatenację do czasu wykonania. –

Powiązane problemy