É 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?

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 :)


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.


@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


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.


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).


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')

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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.