¿Existe un formato recomendado para las importaciones de varias líneas?

114

He leído que hay tres formas de codificar importaciones de varias líneas en Python

Con barras:

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

Duplicación de sentencias:

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

Entre paréntesis:

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

¿Existe un formato recomendado o una forma más elegante para estas declaraciones?

Manuel Alvarez
fuente
3
con tantas importaciones, ¿por qué no solo from Tkinter import *?
Inbar Rose
2
Esto es un ejemplo. La declaración real es, from data.forms import AddressEmbeddedField, PhoneEmbeddedField, MailEmbeddedField, \ WebEmbeddedFieldpero no quiero importar todo el resto de campos incrustados en data.forms
Manuel Alvarez
19
Muchas razones. Por ejemplo, puede sobrescribir muchas variables que no conoce. ¿Conoce todos los nombres importados por from Tkinter import *? No soy. Y los IDE no sabrán si estos nombres (tal vez), por lo que no pueden saber si ingresó un nombre no válido.
Thorsten Kranz
2
@InbarRose Es un mal hábito, mira stackoverflow.com/questions/3615125/…
Yuval Pruss

Respuestas:

161

Personalmente, voy entre paréntesis al importar más de un componente y los ordeno alfabéticamente. Al igual que:

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

Esto tiene la ventaja adicional de ver fácilmente qué componentes se han agregado / eliminado en cada confirmación o PR.

En general, es una preferencia personal y le aconsejo que elija lo que le parezca mejor.

Brendan Maguire
fuente
3
Creo que lo importante es ser coherente (al menos, dentro de un proyecto determinado). Eso facilitará que alguien que lea el código encuentre lo que se está importando sin demasiada dificultad.
Blckknght
1
isort se puede utilizar para formatear automáticamente importaciones de varias líneas en diferentes estilos, consulte github.com/timothycrosley/isort#multi-line-output-modes
Motin
16

Sus ejemplos parecen provenir de PEP 328 . Allí, se propone la notación entre paréntesis exactamente para este problema, por lo que probablemente elegiría este.

Thorsten Kranz
fuente
4

Iría con la notación de paréntesis del PEP328 con nuevas líneas agregadas antes y después de los paréntesis:

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

Este es el formato que usa Django :

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
fuente
¿No se agregan nuevas líneas después / antes del paréntesis en PEP 328?
Gandalf Saxe
@GandalfSaxe PEP 328 se trataba de semántica (añadiendo una nueva característica al idioma), no de formateo.
Max Malysh
Entonces no entiendo bien. ¿Cita que PEP 328 tiene paréntesis para las importaciones de varias líneas, pero no tienen ninguno? "Yo iría con la notación entre paréntesis del PEP328 con nuevas líneas agregadas antes y después de los paréntesis:"
Gandalf Saxe
PEP 328 agregó notación entre paréntesis al lenguaje. Notación entre paréntesis es la capacidad de importar varios módulos de la siguiente manera: from foo import (bar, baz). PEP 328 no dice nada sobre el formateo.
Max Malysh
Ah, está bien, ya veo lo que quieres decir ahora :)
Gandalf Saxe
-4

Por lo general, con Tkinter, está bien usarlo, from Tkinter import *ya que el módulo solo exportará nombres que sean claramente widgets.

PEP 8 no enumera convenciones para tal caso, así que supongo que depende de usted decidir cuál es la mejor opción. Todo se trata de legibilidad, así que elija lo que le indique claramente que está importando cosas de un solo módulo.

Como todos esos nombres están disponibles en su alcance, personalmente creo que la opción 2 es la más clara, ya que puede ver mejor los nombres importados. Luego, incluso podría dividirlo más para quizás agrupar esos nombres que pertenecen entre sí. En su ejemplo, podría poner Tk, Framey por Canvasseparado, ya que agrupan los widgets, mientras que tienen Buttony por Textseparado, ya que son componentes más pequeños en una vista.

dar un toque
fuente
11
Nunca está bien usar desde la importación X *
Tolo Palmer
1
@ToloPalmer Por lo general, eso es cierto, pero para Tkinter esto generalmente está bien, ya que solo importa widgets; incluso aparece de esa manera en la referencia de la biblioteca . Y si enumera la importación como la primera, debería estar especialmente a salvo de cualquier conflicto.
empuje el
1
Como referencia, el problema from X import *incluso para los paquetes que se usan __all__correctamente es que los analizadores de código estático como pyflakesno pueden detectar nombres indefinidos, si los hay, import *ya que se asume que los nombres indefinidos tal vez fueron importados por *.
RubenLaguna