O que há de errado com importações relativas em Python?

88

Atualizei recentemente versões do pylint , um popular verificador de estilo do Python.

Ele foi balístico em todo o meu código, apontando locais onde eu importo módulos no mesmo pacote, sem especificar o caminho completo do pacote.

A nova mensagem de erro é W0403.

W0403: Relative import %r, should be %r

Used when an import relative to the package directory is detected.

Exemplo

Por exemplo, se meus pacotes estiverem estruturados assim:

/cake
  /__init__.py
  /icing.py
  /sponge.py
/drink

e no pacote de esponjas eu escrevo:

import icing

em vez de

import cake.icing

Eu recebo este erro.

Embora eu entenda que nem todas as mensagens Pylint são de igual importância, e não tenho medo de descartá-las, não entendo por que tal prática é considerada uma idéia ruim.

Espero que alguém possa explicar as armadilhas, para que eu possa melhorar meu estilo de codificação, em vez de (como pretendo fazer atualmente) desativar esse aviso aparentemente falso.

    
por Oddthinking 04.08.2012 / 17:29
fonte

2 respostas

93

O problema de import icing é que você não sabe se é uma importação absoluta ou uma importação relativa. icing poderia um módulo no caminho do python ou um pacote no módulo atual. Isso é bastante irritante quando um pacote local tem o mesmo nome de um pacote de biblioteca padrão python.

Você pode fazer from __future__ import absolute_import , o que desativa as importações relativas implícitas. É descrito, inclusive com essa justificativa sobre ambiguidade, no PEP 328 . Acredito que o Python 3000 tenha importações relativas implícitas desativadas completamente.

Você ainda pode fazer importações relativas, mas precisa explicitamente, assim:

from . import icing
    
por 04.08.2012 / 17:36
fonte
47

Existem algumas boas razões:

  1. As importações relativas são facilmente quebradas quando você move um módulo.

    Imagine que você tenha um módulo foo.bar , a foo.baz e baz em seu pacote. foo.bar imports foo.baz , mas usando uma importação relativa.

    Agora, se você mover foo.bar para bar , seu módulo de repente importará um% diferente% co_de!

  2. As importações relativas são ambíguas. Mesmo sem mover o módulo baz no exemplo acima, um novo desenvolvedor vindo ao seu projeto pode ser perdoado por não perceber que bar é realmente baz em vez do pacote foo.baz do nível raiz.

    Importações absolutas tornam explícito o módulo que está sendo usado. E como baz prega, explícito é melhor que implícito.

  3. O Python 3 desativou completamente as importações relativas implícitas; Agora, as importações são sempre interpretadas como absolutas, o que significa que, no exemplo acima, import this sempre importará o módulo de nível superior. Você terá que usar a sintaxe de importação explícita ( import baz ).

    Portar o exemplo do Python 2 para o 3 levaria, assim, a problemas inesperados. Agora, usar importações absolutas tornará seu código à prova do futuro.

por 04.08.2012 / 17:43
fonte