PEP8 ile uyumlu ve E501'i önleyen çok uzun bir dize nasıl yazılır


203

PEP8'in python programınız için 80 sütun kuralının altında kalmasını önerdiği gibi, uzun dizelerle buna nasıl uyabilirim, yani

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

Bunu aşağıdaki satıra genişletmeye nasıl devam edebilirim, yani

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

Yanıtlar:


116

Örtük birleştirme en temiz çözüm olabilir:

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

Düzenleme Yansıtma konusunda Todd'un çizgi devamı yerine parantez kullanma önerisinin verdiği tüm nedenlerle daha iyi olduğunu kabul ediyorum. Sahip olduğum tek tereddüt, parantez dizeleri tuples ile karıştırmanın nispeten kolay olmasıdır.


4
Bu yüzden soruyu gönderen bir aptal gibi hissettim. Şerefe.
Federer

8
Bu, yalnızca örtülü birleştirme değil, son satırdan kaçarak ve PEP8'de çok yakın zamana kadar açıkça yasaklanmış olsa da, şimdi bir izin olmasına rağmen uzun dizeler için DEĞİLDİR. Todd'un aşağıdaki cevabı doğrudur.
Aaron Hall

4
PEP8'i seviyorum, ama bu sevmediğim PEP8'in bir parçası.
Tuples


uzun çizgi çok satırlı uzun bir dizenin ortasındaysa ne olur?
Thayne

299

Ayrıca, komşu dize sabitleri otomatik olarak birleştirildiğinden, bunu şu şekilde de kodlayabilirsiniz:

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

Artı işareti yok ve örneğinizin biçimlendirmesini izleyen fazladan virgül ve boşluk ekledim.

Şahsen ters eğik çizgileri sevmiyorum ve bir yerde okumayı hatırlıyorum, kullanımının aslında daha açık olan bu form lehine onaylanmadığını hatırlıyorum. "Açık, örtük olmaktan daha iyidir."

Ters eğik çizginin daha az net ve daha az kullanışlı olduğunu düşünüyorum çünkü bu aslında satırsonu karakterinden kaçıyor. Gerekirse bir satır sonu yorumu koymak mümkün değildir. Bunu birleştirilmiş dize sabitleriyle yapmak mümkündür:

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

İlk sonuç olarak PEP8 bağlantısını döndüren "python satır uzunluğu" adlı bir Google araması kullandım, ancak bu konuyla ilgili başka bir iyi StackOverflow yayınına da bağlandım: " Python PEP-8 neden maksimum 79 karakterlik bir satır uzunluğu belirtmeli? "

Başka bir iyi arama ifadesi "python satır devam" olacaktır.


8
1: "Kişisel olarak ben ters eğik gibi yap, ben onun kullanımı aslında daha açık olan bu formun lehine önerilmiyor Bu bir yerde okuma hatırlamak unutmayın. 'Açık örtülü daha iyidir'".
Alberto Megía

14
Bir grup alıp nedenini merak eden herkes için. Buradaki satırların sonuna virgül eklemeyin, bu bir dizeyle değil bir demetle sonuçlanır. ;)
bugmenot123

7
+ Karakterini eklemek, verilen örnekten daha açık değil mi? Bunu hala örtük olarak görüyorum. yani "str1" + "str2"yerine"str1" "str2"
user1318135

4
Artı işaretinin daha açık olduğunu kabul ediyorum, ama farklı bir şey yapıyor. Dizeyi, birkaç parçada tek bir dize sabiti belirtmek yerine değerlendirilecek bir ifadeye dönüştürür. Emin değilim ama bu ayrıştırma sırasında yapılır, ancak ifadenin daha sonra yürütülmesi gerekir. Hız farkı, çok sayıda olmadıkça muhtemelen ihmal edilebilir. Ama aynı zamanda estetik olarak, otomatik sıralamayı tercih ediyorum çünkü satır başına daha az karmaşık bir karakter.
Todd

4
Bu sözdizimi ayrıca aşağıdaki gibi dize biçimlendirme uygulama olasılığını korur:('this is my really, really, really, really, really long {} ' 'that I'd really, really, really, like to {}').format(var1, var2))
Tim

16

Bence sorunuzdaki en önemli kelime "öneriler" idi.

Kodlama standartları komik şeylerdir. Genellikle sağladıkları rehberlik yazıldığı zaman gerçekten iyi bir temele sahiptir (örneğin çoğu terminal bir satırda> 80 karakter gösteremez), ancak zamanla işlevsel olarak modası geçmiş, ancak yine de katı bir şekilde bağlı kalırlar. Burada yapmanız gereken, kodunuzun okunabilirliğine ve bakımına karşı belirli bir öneriyi "kırmanın" göreli değerlerini tartmak olduğunu tahmin ediyorum.

Üzgünüz, bu doğrudan sorunuza cevap vermiyor.


Tamamen katılıyorum. Benzer bir Java stili kuralı da eskidir (IMHO).
Iker Jimenez

Evet katılıyorum, ancak bu özel örnekte ona nasıl uyacağımı kafamdan alıyor. Her zaman sınıfları, yöntemleri <80 karakter için tutmaya çalışıyorum, ancak böyle bir dize belki de olumsuz bir etkisi dışında hiçbir etkisi yoktur söyleyebilirim.
Federer

1
Ayrıca kişisel tercihinizi topluluk çapında kodlama standardına göre tartmanız gerekir. Yeni kişilerin içeri girmesini ve ilk günden itibaren kod biçimlendirmesiyle rahat olmasını istersiniz.
15'te geri çekilebilir

1
Kendim için biliyorum, 80 karakter sınırına bağlı kalıyorum, çünkü kodlamamın çoğunu hala IDLE'de yapıyorum ve yatay kaydırmayı işleme şeklini sevmiyorum. (Kaydırma çubuğu yok)
Tofystedeth

@retracile - evet, biliyorsun. Ben "rehberliği görmezden gelmelisin" demiyorum, daha ziyade bazı durumlarda rehberliğin toplumun iyiliği için orada olmadığını ileri sürüyorum. IDLE'nin (Tofystedeth tarafından gönderilen) kısıtlamalarının farkında değildim, ancak bu durumda sözleşmeyi takip etmek için bir striong argümanı var.
ZombieSheep

13

Bir alanı kaybettiniz ve muhtemelen bir satır devam karakterine ihtiyacınız var, yani. a \.

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

ya da:

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

Parens, satırın devamı yerine de çalışacaktı, ancak birisinin bir demet oluşturmayı düşündüğünü ve bir virgül unuttuğunu düşündüğünü düşünüyorsun. Örneğin:

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

karşı:

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

Python'un dinamik yazımıyla kod her iki şekilde de çalışabilir, ancak istemediğiniz kodla yanlış sonuçlar verebilir.


2

backslash:

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

veya parenslere sarın:

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

2
Artı işaretinin gerekli olduğunu unutmayın. Python, birbirini izleyen dize değişmezlerini birleştirir.
bukzor

2

Bunların hepsi harika cevaplar, ama "örtük olarak birleştirilmiş" dizeleri düzenlememe yardımcı olacak bir editör eklentisi bulamadım, bu yüzden beni kolaylaştırmak için bir paket yazdım.

Kim bu eski iş parçacığını dolaşıyorsa pip (paragraflar yükleyin) kontrol etmek istiyorum. Çok satırlı dizeleri html'nin yaptığı gibi biçimlendirir (boşlukları sıkıştır, yeni bir paragraf için iki yeni satır, satırlar arasındaki boşluklar hakkında endişelenme).

from paragraphs import par


class SuddenDeathError(Exception):
    def __init__(self, cause: str) -> None:
        self.cause = cause

    def __str__(self):
        return par(
            f""" Y - e - e - e - es, Lord love you! Why should she die of
            {self.cause}? She come through diphtheria right enough the year
            before. I saw her with my own eyes. Fairly blue with it, she
            was. They all thought she was dead; but my father he kept ladling
            gin down her throat till she came to so sudden that she bit the bowl
            off the spoon. 

            What call would a woman with that strength in her have to die of
            {self.cause}? What become of her new straw hat that should have
            come to me? Somebody pinched it; and what I say is, them as pinched
            it done her in."""
        )


raise SuddenDeathError("influenza")

olur ...

__main__.SuddenDeathError: Y - e - e - e - es, Lord love you! Why should she die of influenza? She come through diphtheria right enough the year before. I saw her with my own eyes. Fairly blue with it, she was. They all thought she was dead; but my father he kept ladling gin down her throat till she came to so sudden that she bit the bowl off the spoon.

What call would a woman with that strength in her have to die of influenza? What become of her new straw hat that should have come to me? Somebody pinched it; and what I say is, them as pinched it done her in.

(Vim) 'gq' ile her şey kolayca sıralanıyor


0

A ile \ifadeleri birden çok satıra genişletebilirsiniz:

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

çalışmalı.


0

Büyük dizeleri belirtmek için burada belirtilmeyen birkaç yöntemi kullanma eğilimindeyim, ancak bunlar çok spesifik senaryolar içindir. YMMV ...

  • Genellikle biçimlendirilmiş jetonlarla çok satırlı metin yığınları (tam olarak sorduğunuz şey değil, ancak yine de kullanışlı):

    error_message = '''
    I generally like to see how my helpful, sometimes multi-line error
    messages will look against the left border.
    '''.strip()
  • Tercih ettiğiniz dize enterpolasyon yöntemiyle değişkeni parça parça büyütün:

    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.'
  • Bir dosyadan okuyun. PEP-8 bir dosyadaki dizelerin uzunluğunu sınırlamaz; sadece kodunuzun satırları. :)

  • Dizgeyi yeni satırları kullanarak manevra satırlarına bölmek için kaba kuvvet veya düzenleyicinizi kullanın ve ardından tüm yeni satırları kaldırın. (Listelediğim ilk tekniğe benzer):

    foo = '''
    agreatbigstringthatyoudonotwanttohaveanyne
    wlinesinbutforsomereasonyouneedtospecifyit
    verbatimintheactualcodejustlikethis
    '''.replace('\n', '')

0

Mevcut seçenekler:

  • ters eğik çizgi :"foo" \ "bar"
  • artı işareti ve ardından ters eğik çizgi :"foo" + \ "bar"
  • parantez :
    • ("foo" "bar")
    • parantez ile artı işareti :("foo" + "bar")
    • PEP8, E502: ters eğik çizgi parantezler arasında yedeklidir

Önlemek

("foo", "bar")Bir demet tanımlayan virgül içeren parantezlerden kaçının .


>>> s = "a" \
... "b"
>>> s
'ab'
>>> type(s)
<class 'str'>
>>> s = "a" + \
... "b"
>>> s
'ab'
>>> type(s)
<class 'str'>
>>> s = ("a"
... "b")
>>> type(s)
<class 'str'>
>>> print(s)
ab
>>> s = ("a",
... "b")
>>> type(s)
<class 'tuple'>
>>> s = ("a" + 
... "b")
>>> type(s)
<class 'str'>
>>> print(s)
ab
>>> 

0

Uzun bir dizgi değişmezi eklemeniz ve flake8'in kapanmasını istiyorsanız, kapatma yönergelerini kullanabilirsiniz . Örneğin, bir test rutininde sahte bir CSV girişi tanımladım. Satırları olan daha fazla çizgiye bölmenin, kafa karıştırıcı olacağını düşündüm, bu yüzden # noqa: E501aşağıdaki gibi bir eklemeye karar verdim :

csv_test_content = """"STATION","DATE","SOURCE","LATITUDE","LONGITUDE","ELEVATION","NAME","REPORT_TYPE","CALL_SIGN","QUALITY_CONTROL","WND","CIG","VIS","TMP","DEW","SLP","AA1","AA2","AY1","AY2","GF1","MW1","REM"
"94733099999","2019-01-03T22:00:00","4","-32.5833333","151.1666666","45.0","SINGLETON STP, AS","FM-12","99999","V020","050,1,N,0010,1","22000,1,9,N","025000,1,9,9","+0260,1","+0210,1","99999,9","24,0000,9,1",,"0,1,02,1","0,1,02,1","01,99,1,99,9,99,9,99999,9,99,9,99,9","01,1","SYN05294733 11/75 10502 10260 20210 60004 70100 333 70000="
"94733099999","2019-01-04T04:00:00","4","-32.5833333","151.1666666","45.0","SINGLETON STP, AS","FM-12","99999","V020","090,1,N,0021,1","22000,1,9,N","025000,1,9,9","+0378,1","+0172,1","99999,9","06,0000,9,1",,"0,1,02,1","0,1,02,1","03,99,1,99,9,99,9,99999,9,99,9,99,9","03,1","SYN04294733 11/75 30904 10378 20172 60001 70300="
"94733099999","2019-01-04T22:00:00","4","-32.5833333","151.1666666","45.0","SINGLETON STP, AS","FM-12","99999","V020","290,1,N,0057,1","99999,9,9,N","020000,1,9,9","+0339,1","+0201,1","99999,9","24,0000,9,1",,"0,1,02,1","0,1,02,1",,"02,1","SYN05294733 11970 02911 10339 20201 60004 70200 333 70000="
"94733099999","2019-01-05T22:00:00","4","-32.5833333","151.1666666","45.0","SINGLETON STP, AS","FM-12","99999","V020","200,1,N,0026,1","99999,9,9,N","000100,1,9,9","+0209,1","+0193,1","99999,9","24,0004,3,1",,"1,1,02,1","1,1,02,1","08,99,1,99,9,99,9,99999,9,99,9,99,9","51,1","SYN05294733 11/01 82005 10209 20193 69944 75111 333 70004="
"94733099999","2019-01-08T04:00:00","4","-32.5833333","151.1666666","45.0","SINGLETON STP, AS","FM-12","99999","V020","070,1,N,0026,1","22000,1,9,N","025000,1,9,9","+0344,1","+0213,1","99999,9","06,0000,9,1",,"2,1,02,1","2,1,02,1","04,99,1,99,9,99,9,99999,9,99,9,99,9","02,1","SYN04294733 11/75 40705 10344 20213 60001 70222="
"""  # noqa: E501

-1

Geçmişte textwrap.dedent kullandım. Biraz hantal, bu yüzden şimdi satır devamlarını tercih ediyorum, ancak blok girintisini gerçekten istiyorsanız, bunun harika olduğunu düşünüyorum.

Örnek Kod (trim, bir dilim ile ilk '\ n' den kurtulmak içindir):

import textwrap as tw
x = """\
       This is a yet another test.
       This is only a test"""
print(tw.dedent(x))

Açıklama:

dedent, yeni satırdan önceki metnin ilk satırındaki beyaz boşluğu temel alan girintiyi hesaplar. Eğer değiştirmek istersen, onu kullanarak kolayca yeniden uygulayabilirsin.re modülü .

Bu yöntemin sınırlamaları vardır, çünkü çok uzun satırlar hala istediğinizden daha uzun olabilir, bu durumda dizeleri birleştiren diğer yöntemler daha uygundur.


1
Düzeltmek yerine ilk satırdan kaçınmak için x[1:]ters eğik çizgi koyabilirsiniz x = """.
Michael Dunn
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.