Jaki jest właściwy sposób sformatowania wielowierszowego dykta w Pythonie?

184

W Pythonie chcę napisać w moim kodzie wielowierszowy dykt. Istnieje kilka sposobów formatowania. Oto kilka, o których mogłem pomyśleć:

  1. mydict = { "key1": 1,
               "key2": 2,
               "key3": 3, }
  2. mydict = { "key1": 1,
               "key2": 2,
               "key3": 3,
             }
  3. mydict = {
        "key1": 1,
        "key2": 2,
        "key3": 3,
    }

Wiem, że którykolwiek z powyższych jest poprawny pod względem składniowym, ale zakładam, że istnieje jeden preferowany styl wcięcia i podziału linii dla słowników Python. Co to jest?

Uwaga: nie jest to kwestia składni. Wszystkie powyższe są (o ile mi wiadomo) prawidłowymi instrukcjami języka Python i są sobie równoważne.

Ryan C. Thompson
źródło
12
Dla 1 i 2: Brak spacji bezpośrednio w nawiasach klamrowych, patrz PEP 8.
Sven Marnach
3
Chcę powiedzieć, że w pythonowym module pprint używa pierwszego przykładu, bez spacji bezpośrednio w nawiasach klamrowych.
charmoniumQ

Odpowiedzi:

239

Używam # 3. To samo dotyczy długich list, krotek itp. Nie wymaga dodawania żadnych dodatkowych spacji poza wcięciami. Jak zawsze bądź konsekwentny.

mydict = {
    "key1": 1,
    "key2": 2,
    "key3": 3,
}

mylist = [
    (1, 'hello'),
    (2, 'world'),
]

nested = {
    a: [
        (1, 'a'),
        (2, 'b'),
    ],
    b: [
        (3, 'c'),
        (4, 'd'),
    ],
}

Podobnie oto mój preferowany sposób dołączania dużych ciągów bez wprowadzania białych znaków (tak jak w przypadku ciągów wieloliniowych o potrójnym cudzysłowie):

data = (
    "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABG"
    "l0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAEN"
    "xBRpFYmctaKCfwrBSCrRLuL3iEW6+EEUG8XvIVjYWNgJdhFjIX"
    "rz6pKtPB5e5rmq7tmxk+hqO34e1or0yXTGrj9sXGs1Ib73efh1"
    "AAAABJRU5ErkJggg=="
)
FogleBird
źródło
Czy możesz podać jakieś odniesienie, mam problem ze znalezieniem wiarygodnego źródła na ten temat. (Zgadzam się z tobą).
Trufa,
82
Hmm, znalazłem to: stackoverflow.com/questions/6388187/…
FogleBird
6
Nie mów mu, ale ten użytkownik nie ma pojęcia, o czym on mówi; P
Trufa,
3
lol, poważniej, nie mogłem znaleźć „autorytatywnego” odniesienia. Dam ci znać, jeśli to zrobię! Być może ktoś powinien skontaktować się z Guido.
FogleBird
2
To pasuje do PEP 8: python.org/dev/peps/pep-0008/#indentation . Na dole sekcji dotyczącej wcięć znajduje się kilka przykładów list.
AMS
31

Przede wszystkim, jak powiedział Steven Rumbalski, „PEP8 nie zajmuje się tym pytaniem”, więc jest to kwestia osobistych preferencji.

Użyłbym podobnego, ale nie identycznego formatu, jak twój format 3. Oto mój i dlaczego.

my_dictionary = { # Don't think dict(...) notation has more readability
    "key1": 1, # Indent by one press of TAB (i.e. 4 spaces)
    "key2": 2, # Same indentation scale as above
    "key3": 3, # Keep this final comma, so that future addition won't show up as 2-lines change in code diff
    } # My favorite: SAME indentation AS ABOVE, to emphasize this bracket is still part of the above code block!
the_next_line_of_code() # Otherwise the previous line would look like the begin of this part of code

bad_example = {
               "foo": "bar", # Don't do this. Unnecessary indentation wastes screen space
               "hello": "world" # Don't do this. Omitting the comma is not good.
} # You see? This line visually "joins" the next line when in a glance
the_next_line_of_code()

btw_this_is_a_function_with_long_name_or_with_lots_of_parameters(
    foo='hello world',  # So I put one parameter per line
    bar=123,  # And yeah, this extra comma here is harmless too;
              # I bet not many people knew/tried this.
              # Oh did I just show you how to write
              # multiple-line inline comment here?
              # Basically, same indentation forms a natural paragraph.
    ) # Indentation here. Same idea as the long dict case.
the_next_line_of_code()

# By the way, now you see how I prefer inline comment to document the very line.
# I think this inline style is more compact.
# Otherwise you will need extra blank line to split the comment and its code from others.

some_normal_code()

# hi this function is blah blah
some_code_need_extra_explanation()

some_normal_code()
RayLuo
źródło
podoba mi się komentarz w linii. mój pierwszy profesor programistyczny (programowałem już od lat) nalegał na komentarze, ale nigdy skutecznie nie wyjaśnił dlaczego. objaśniłeś teraz praktykę, z której korzystam od około 20 lat.
Joshua K
Aha, dzięki. Mamy podobny wiek, doświadczenie i „przebieg” w zakresie programowania. Więc jeśli już zacząłeś tę praktykę komentowania 20 lat temu (co jest imponujące!), Dlaczego nadal potrzebowałeś wyjaśnień swojego profesora prawdopodobnie 10 lat temu, kiedy byłeś na uniwersytecie? Po prostu ciekawy. :-)
RayLuo
bardzo dobre pytanie :) ATARI BASIC i GWbasic praktycznie narzuciły to, będąc kompilatorami opartymi na odgórnej linii przepływu. to coś, co przyjąłem, gdy czytałem BASIC Petera Nortona (a później kod ASM) w czasopismach papierowych. nauczyłem się Turbo Pascala pomiędzy nimi, ale nauczyłem się już z przykładów w czasopismach papierowych i dostosowałem się do ograniczeń BASIC.
Joshua K
PEP8 nieco to rozwiązuje, ponieważ odradza dodawanie spacji bezpośrednio po nawiasie otwierającym, więc opcje 1 i 2 w OP są wyłączone.
Daniel Serodio
9

Ponieważ twoje klucze są ciągami, a ponieważ mówimy o czytelności, wolę:

mydict = dict(
    key1 = 1,
    key2 = 2,
    key3 = 3,
)
dugres
źródło
6
Wolę nie używać spacji podczas definiowania kwargs. c = function(a=1, b=2)jest bardziej „pytoniczny”.
Steve K
1

Zwykle, jeśli masz duże obiekty Pythona, bardzo trudno je sformatować. Osobiście wolę używać do tego niektórych narzędzi.

Oto python-beautifier - www.cleancss.com/python-beautify, który natychmiast zamienia twoje dane w dostosowywalny styl.

Max
źródło
0
dict(rank = int(lst[0]),
                grade = str(lst[1]),
                channel=str(lst[2])),
                videos = float(lst[3].replace(",", " ")),
                subscribers = float(lst[4].replace(",", "")),
                views = float(lst[5].replace(",", "")))
gaurav raj
źródło
To nie odpowiada na pytanie
bagerard
-1

Z mojego doświadczenia z samouczkami i innymi rzeczami numer 2 zawsze wydaje się preferowany, ale jest to osobisty wybór preferencji bardziej niż cokolwiek innego.

Jake
źródło
-6

Zasadniczo nie wprowadzasz przecinka po ostatnim wpisie, ale Python poprawi to za Ciebie.

Joe
źródło
34
Nie! Zawsze dołączaj ostatni przecinek, więc jeśli dodasz nowy ostatni element, nie musisz zmieniać linii przed nim. Jest to jedna z wielkich zalet Pythona: praktyczność nad czystością.
Ned Batchelder,
2
Ponadto ta odpowiedź nie dotyczy zadanego pytania.
RKD314,