É possível usar traços nos arquivos Python ao tentar importá-los?

149

Basicamente, quando eu tenho um arquivo python como:

python-code.py

E use:

import (python-code)

o intérprete me dá erro de sintaxe.

Alguma idéia de como corrigi-lo? Os traços são ilegais nos nomes de arquivos python?

Joan Venge
fonte

Respostas:

167

Você deve conferir o PEP 8 , o Guia de Estilo para Código Python:

Nomes de pacotes e módulos Os módulos devem ter nomes curtos e todos em minúsculas. Sublinhados podem ser usados ​​no nome do módulo se melhorar a legibilidade. Os pacotes Python também devem ter nomes curtos, todos em minúsculas, embora o uso de sublinhados seja desencorajado.

Como os nomes dos módulos são mapeados para os nomes de arquivos e alguns sistemas de arquivos não diferenciam maiúsculas de minúsculas e truncam nomes longos, é importante que os nomes dos módulos sejam escolhidos para serem bem curtos - isso não será um problema no Unix, mas pode ser um problema. problema quando o código é transportado para versões mais antigas de Mac ou Windows ou DOS.

Em outras palavras: renomeie seu arquivo :)

Paolo Bergantino
fonte
75
o problema não tem nada a ver com estilo, é uma sintaxe de erro
4
Como mostrado abaixo, ainda é possível ter um arquivo com esse nome, portanto o guia de estilo é muito relevante.
Paolo Bergantino
5
Pode ser muito útil usar hífens nos diretórios e nomes de arquivos Python quando você desejar explicitamente impedir importações. Por exemplo, em (digamos) um projeto Django, você pode ter scripts escritos em Python que não devem ser endereçáveis ​​como aplicativos. Você pode colocá-los em uma pasta como ops-scriptse saber que eles não podem ser importados usando uma abordagem de namespace de pacote normal. Ou um único script pode ser nomeado stop-website.pypara um efeito semelhante. Qualquer um desses ainda pode ser importado via runpye alguns outros métodos, é claro, mas isso ajuda a evitar alguns erros comuns.
Chris Johnson
Renomear um módulo pode ser problemático, especialmente se você estiver confiando em outro padrão. No meu caso, estou usando arquivos python cgi na cgi-binpasta (fazendo unitttests neles), o que é bastante comum. A menos que você tenha um caso raro como esse, renomeie seu módulo definitivamente se você tiver controle sobre ele.
NuclearPeon
1
Acabei de descobrir que o PyDev permitirá nomes de diretórios com hífens, mas não mostrará as classes e / ou variáveis ​​internas nos arquivos .py contidos nesse diretório.
user5920660
122

Outra coisa a ser observada no seu código é que a importação não é uma função. Assim import(python-code)deve ser o import python-codeque, como alguns já mencionaram, é interpretado como "importar python menos código", não o que você pretendia. Se você realmente precisar importar um arquivo com um traço no nome, faça o seguinte:

python_code = __import__('python-code')

Mas, como também mencionado acima, isso não é realmente recomendado. Você deve alterar o nome do arquivo se for algo que você controla.

Rick Copeland
fonte
@KevinAudleman, você tem um exemplo de como usar a importação import com um arquivo hifenizado? Eu tentei e falhei.
Tom Hale
@TomHale importlib.import_module ('abmodule-1') deve funcionar. Se o seu import_module não funcionar, acho que uma importação normal também não funcionará.
Ian Lin
63

TLDR

Os traços não são ilegais, mas você não deve usá-los por três motivos:

  1. Você precisa de sintaxe especial para importar arquivos com traços
  2. Ninguém espera um nome de módulo com um traço
  3. É contra as recomendações do Python Style Guide

Se você definitivamente precisar importar um nome de arquivo com um traço, a sintaxe especial é esta:

module_name = __import__('module-name')

Curioso para saber por que precisamos de sintaxe especial?

O motivo da sintaxe especial é que, ao escrever, import somenamevocê cria um objeto de módulo com identificador somename(para que você possa usá-lo posteriormente, por exemplo somename.funcname). Obviamente, module-namenão é um identificador válido e, portanto, a sintaxe especial que fornece um identificador válido.

Você não entende por que module-name não é um identificador válido?

Não se preocupe - eu também não. Aqui vai uma dica para ajudá-lo: Olhe para esta linha python: x=var1-var2. Você vê uma subtração no lado direito da atribuição ou um nome de variável com um traço?

PS

Nada original na minha resposta, exceto incluindo o que eu considerava as informações mais relevantes de todas as outras respostas em um só lugar

ndemou
fonte
Estou tentando usar esse pacote de importação de pip com um hífen. psycopg2_binary = import_module('psycopg2-binary'). Erro => ModuleNotFoundError: No module named 'psycopg2-binary'. Mas psycopg2-binaryestá instalado. Não faço ideia de como incluí-lo.
Mote Zart
Talvez seja uma questão de caminho. Veja chrisyeh96.github.io/2017/08/08/…
ndemou 1/10/19
32

O problema é que python-codenão é um identificador. O analisador vê isso como pythonmenos code. Claro que isso não fará o que você está pedindo. Você precisará usar um nome de arquivo que também seja um identificador python válido. Tente substituir o -por um sublinhado.

SingleNegationElimination
fonte
4
+1. Nunca pensei que o nome do arquivo do código fonte do Python fosse um identificador válido, pois o nome do arquivo será usado para se referir ao objeto do módulo.
Andy
5

Você provavelmente poderia importá-lo através de algum __import__hack, mas se você ainda não sabe, não deveria. Os nomes dos módulos do Python devem ser nomes de variáveis ​​válidos ("identificadores") - ou seja, se você tiver um módulo foo_bar, poderá usá-lo no Python ( print foo_bar). Você não seria capaz de fazê-lo com um nome estranho ( print foo-bar-> erro de sintaxe).

John Millikin
fonte
5

No Python 3, use import_module :

from importlib import import_module
python_code = import_module('python-code')

De forma geral,

import_module('package.subpackage.module')
e18r
fonte
1

Embora a nomeação adequada de arquivos seja o melhor caminho, se python-codenão estiver sob nosso controle, um uso de hack __import__é melhor do que copiar, renomear ou mexer com o código de outros autores. No entanto, tentei e não funcionou, a menos que renomeie o arquivo adicionando a .pyextensão. Depois de examinar o documento para obter uma descrição .py, acabei com o seguinte:

import imp

try:
    python_code_file = open("python-code")
    python_code = imp.load_module('python_code', python_code_file, './python-code', ('.py', 'U', 1))
finally:
    python_code_file.close()

Ele criou um novo arquivo python-codecna primeira execução.

Ale
fonte