Jak napisać bardzo długi ciąg zgodny z PEP8 i zapobiec E501

Jak PEP8 sugeruje trzymanie poniżej reguły 80 kolumn dla Twojego programu Pythona, Jak mogę się tego trzymać z długimi łańcuchami, np.

s = "this is my really, really, really, really, really, really, really long string that I'd like to shorten."

Jak bym to rozbudował do następującej linijki, tzn.

s = "this is my really, really, really, really, really, really" + 
    "really long string that I'd like to shorten."
Author: Braiam, 2009-12-09

8 answers

Konkatenacja Implicit może być najczystszym rozwiązaniem:

s = "this is my really, really, really, really, really, really," \
    " really long string that I'd like to shorten."

Edit co do refleksji zgadzam się, że sugestia Todda, aby używać nawiasów zamiast kontynuacji linii, jest lepsza ze wszystkich powodów, które podaje. Jedynym wahaniem, jakie mam, jest to, że stosunkowo łatwo pomylić struny z krotkami.

 83
Author: Michael Dunn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-21 11:13:14

Również, ponieważ sąsiednie stałe łańcuchowe są automatycznie konkatenowane, możesz również kodować w ten sposób:

s = ("this is my really, really, really, really, really, really, "  
     "really long string that I'd like to shorten.")

Uwaga bez znaku plus, I dodałem dodatkowy przecinek i spację, które następują po formatowaniu twojego przykładu.

Osobiście nie lubię odwrotnych ukośników i przypominam sobie, że gdzieś czytałem, że jego użycie jest faktycznie przestarzałe na rzecz tej formy, która jest bardziej wyraźna. Pamiętaj " Explicit jest lepszy niż implicit."

Uważam, że Ukośnik jest mniej wyraźny i mniej użyteczne, ponieważ w rzeczywistości jest to wymykanie się znakowi nowej linii. Nie jest możliwe umieszczenie po nim komentarza końca linii, jeśli jest to konieczne. Można to zrobić ze skonkatenowanymi stałymi łańcuchów:

s = ("this is my really, really, really, really, really, really, " # comments ok
     "really long string that I'd like to shorten.")

Użyłem wyszukiwarki Google "długość linii Pythona", która zwraca link PEP8 jako pierwszy wynik, ale także linki do innego dobrego postu StackOverflow na ten temat: "dlaczego Python PEP-8 powinien określać maksymalną długość linii 79 postacie?"

Kolejna dobra fraza wyszukiwania to "kontynuacja linii Pythona".

 204
Author: Todd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:33

Myślę, że najważniejszym słowem w twoim pytaniu było "sugeruje".

Standardy kodowania to zabawne rzeczy. Często wskazówki, które dostarczają, mają naprawdę dobre podstawy, gdy zostały napisane (np. większość terminali nie jest w stanie pokazać > 80 znaków w linii), ale z czasem stają się funkcjonalnie przestarzałe, ale nadal sztywno przestrzegane. Myślę, że to, co musisz tutaj zrobić, to rozważyć względne zalety "złamania" tej konkretnej sugestii w stosunku do czytelności i zasadności Twojego kodu.

Przepraszam, że to nie odpowiada bezpośrednio na twoje pytanie.

 12
Author: ZombieSheep,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-09 15:24:55

Straciłeś spację i prawdopodobnie potrzebujesz znaku kontynuacji linii, tj. a \.

s = "this is my really, really, really, really, really, really" +  \
    " really long string that I'd like to shorten."

Lub nawet:

s = "this is my really, really, really, really, really, really"  \
    " really long string that I'd like to shorten."

Parens również działałby zamiast kontynuacji wiersza, ale ryzykujesz, że ktoś pomyśli, że zamierzałeś mieć krotkę i właśnie zapomniał przecinka. Weźmy na przykład:

s = ("this is my really, really, really, really, really, really"
    " really long string that I'd like to shorten.")

Kontra:

s = ("this is my really, really, really, really, really, really",
    " really long string that I'd like to shorten.")

Przy dynamicznym pisaniu Pythona, kod może działać w obie strony, ale daje nieprawidłowe wyniki z tym, którego nie zamierzałeś.

 12
Author: retracile,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-09 15:30:29

Backslash:

s = "this is my really, really, really, really, really, really" +  \
    "really long string that I'd like to shorten."

Lub w nawiasie:

s = ("this is my really, really, really, really, really, really" + 
    "really long string that I'd like to shorten.")
 4
Author: recursive,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-09 15:24:01

Za pomocą \ można rozwinąć instrukcje do wielu linii:

s = "this is my really, really, really, really, really, really" + \
"really long string that I'd like to shorten."
Powinno zadziałać.
 1
Author: Ikke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-20 20:38:34

Zazwyczaj używam kilku metod nie wymienionych tutaj do określania dużych ciągów, ale są one dla bardzo konkretnych scenariuszy. YMMV...

  • Wielowierszowe plamy tekstu, często z sformatowanymi tokenami (nie do końca to, o co prosiłeś, ale nadal przydatne):

    error_message = '''
    I generally like to see how my helpful, sometimes multi-line error
    messages will look against the left border.
    '''.strip()
    
  • Rozwijaj zmienną kawałek po kawałku za pomocą dowolnej metody interpolacji łańcuchów:

    var = 'This is the start of a very,'
    var = f'{var} very long string which could'
    var = f'{var} contain a ridiculous number'
    var = f'{var} of words.'
    
  • Przeczytaj to z pliku. PEP-8 nie ogranicza długości łańcuchów w pliku; tylko linie Twojego kodu. :)

  • Użyj brute-force lub edytora, aby podzielić ciąg znaków na managaeble za pomocą nowych linii, a następnie usunąć wszystkie nowe linie. (Podobna do pierwszej techniki, którą wymieniłem):

    foo = '''
    agreatbigstringthatyoudonotwanttohaveanyne
    wlinesinbutforsomereasonyouneedtospecifyit
    verbatimintheactualcodejustlikethis
    '''.replace('\n', '')
    
 0
Author: Larold,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-27 02:45:25

Użyłem texttwrap.dedent w przeszłości. Jest to trochę uciążliwe, więc wolę kontynuacje linii teraz, ale jeśli naprawdę chcesz wcięcie bloku, myślę, że to jest świetne.

Przykładowy kod (gdzie trim ma pozbyć się pierwszego "\n " z plasterkiem):

import textwrap as tw
x = """
       This is a yet another test.
       This is only a test"""
print(tw.dedent(x[1:]))

Wyjaśnienie:

Z tego co wiem, dedent oblicza wcięcia na podstawie białej spacji w pierwszym wierszu tekstu przed nowym wierszem. Więc dodałem nową linię, aby ułatwić wyrównanie kodu. Aby uniknąć nowy wiersz, musisz dodać do pierwszego wiersza tekstu dodatkowe białe spacje, aby kolejne wiersze miały ich wcięcia zmniejszone, jak chcesz. Jeśli chcesz go zmodyfikować, możesz go łatwo zaimplementować za pomocą modułu re.

Ta metoda ma ograniczenia w tym, że bardzo długie linie są nadal dłuższe niż chcesz, w tym przypadku Inne metody, które łączą łańcuchy są bardziej odpowiednie.

 0
Author: MrMas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-22 22:57:55