Existe um formato recomendado para importações de várias linhas?

114

Eu li que existem três maneiras de codificar importações de várias linhas em python

Com barras:

from Tkinter import Tk, Frame, Button, Entry, Canvas, Text, \
    LEFT, DISABLED, NORMAL, RIDGE, END

Duplicando senteces:

from Tkinter import Tk, Frame, Button, Entry, Canvas, Text
from Tkinter import LEFT, DISABLED, NORMAL, RIDGE, END

Com parênteses:

from Tkinter import (Tk, Frame, Button, Entry, Canvas, Text,
    LEFT, DISABLED, NORMAL, RIDGE, END)

Existe um formato recomendado ou uma forma mais elegante para essas declarações?

Manuel Alvarez
fonte
3
com tantas importações, por que não apenas from Tkinter import *?
Inbar Rose de
2
Isto é um exemplo. A verdadeira afirmação é, from data.forms import AddressEmbeddedField, PhoneEmbeddedField, MailEmbeddedField, \ WebEmbeddedFieldmas não quero importar todo o resto dos campos incorporados em data.forms
Manuel Alvarez
19
Muitas razões. Por exemplo, você pode sobrescrever muitas variáveis ​​das quais não tem conhecimento. Você conhece todos os nomes importados por from Tkinter import *? Eu não estou. E os IDEs não saberão se esses nomes (talvez), portanto, eles não são capazes de dizer se você inseriu um nome inválido.
Thorsten Kranz
2
@InbarRose É um mau habbit, olhe para stackoverflow.com/questions/3615125/…
Yuval Pruss de

Respostas:

161

Pessoalmente, eu uso parênteses ao importar mais de um componente e os classifico em ordem alfabética. Igual a:

from Tkinter import (
    Button,
    Canvas,
    DISABLED,
    END,
    Entry,
    Frame,
    LEFT,
    NORMAL,
    RIDGE,
    Text,
    Tk,
)

Isso tem a vantagem adicional de ver facilmente quais componentes foram adicionados / removidos em cada commit ou PR.

No geral, porém, é uma preferência pessoal e eu o aconselho a ir com o que parecer melhor para você.

Brendan Maguire
fonte
3
Acho que o importante é ser consistente (pelo menos, dentro de um determinado projeto). Isso tornará mais fácil para alguém ler o código encontrar o que está sendo importado sem muita dificuldade.
Blckknght
1
isort pode ser usado para formatar automaticamente importações multilinhas em estilos diferentes, consulte github.com/timothycrosley/isort#multi-line-output-modes
Motin
16

Seus exemplos parecem originar-se do PEP 328 . Lá, a notação de parênteses é proposta exatamente para esse problema, então provavelmente eu escolheria este.

Thorsten Kranz
fonte
4

Eu iria com a notação de parênteses do PEP328 com novas linhas adicionadas antes e depois dos parênteses:

from Tkinter import (
    Tk, Frame, Button, Entry, Canvas, Text, 
    LEFT, DISABLED, NORMAL, RIDGE, END
)

Este é o formato que o Django usa:

from django.test.client import Client, RequestFactory
from django.test.testcases import (
    LiveServerTestCase, SimpleTestCase, TestCase, TransactionTestCase,
    skipIfDBFeature, skipUnlessAnyDBFeature, skipUnlessDBFeature,
)
from django.test.utils import (
    ignore_warnings, modify_settings, override_settings,
    override_system_checks, tag,
)
Max Malysh
fonte
Não há novas linhas adicionadas depois / antes do parêntese no PEP 328?
Gandalf Saxe
@GandalfSaxe PEP 328 foi sobre semântica (adicionar um novo recurso à linguagem), não sobre formatação.
Max Malysh
Eu não entendo muito bem então. Você cita o PEP 328 como tendo parênteses para importações de várias linhas, mas eles não têm nenhum? "Eu iria com a notação de parênteses do PEP328 com novas linhas adicionadas antes e depois dos parênteses:"
Gandalf Saxe
O PEP 328 adicionou notação de parênteses ao idioma. Notação parêntesis é a capacidade de importar vários módulos como este: from foo import (bar, baz). PEP 328 não diz nada sobre formatação.
Max Malysh
Ah ok, entendo o que você quer dizer agora :)
Gandalf Saxe
-4

Normalmente com o Tkinter, não há problema em apenas usar, from Tkinter import *pois o módulo exportará apenas nomes que sejam claramente widgets.

O PEP 8 não lista nenhuma convenção para esse caso, então acho que cabe a você decidir qual é a melhor opção. É tudo uma questão de legibilidade, então escolha o que deixar claro que você está importando coisas de um único módulo.

Como todos esses nomes estão disponíveis em seu escopo, eu pessoalmente acho que a opção 2 é a mais clara, pois você pode ver os nomes importados da melhor forma. Você pode até mesmo dividir mais para talvez agrupar os nomes que pertencem uns aos outros. Em seu exemplo, eu poderia colocar Tk, Framee Canvasseparadamente, pois eles agrupam widgets juntos, embora tenham Buttone Textseparadamente, pois são componentes menores em uma visualização.

cutucar
fonte
11
Nunca está OK para usar do X import *
Tolo Palmer
1
@ToloPalmer Normalmente isso é verdade, mas para Tkinter isso geralmente é normal, já que você só importa widgets; está até listado dessa forma na referência da biblioteca . E se você listar a importação como a primeira, estará especialmente protegido contra quaisquer conflitos.
cutucar
1
Para referência, o problema com from X import *até mesmo para pacotes que usam __all__corretamente é que os analisadores de código estático como pyflakesnão podem detectar nomes indefinidos se houver algum, import *uma vez que tem que assumir que quaisquer nomes indefinidos foram importados pelo *.
RubenLaguna