Não é possível importar meus próprios módulos em Python

141

Estou tendo dificuldade para entender como a importação de módulos funciona em Python (nunca fiz isso em nenhuma outra linguagem antes).

Digamos que eu tenho:

myapp/__init__.py
myapp/myapp/myapp.py
myapp/myapp/SomeObject.py
myapp/tests/TestCase.py

Agora estou tentando obter algo assim:

myapp.py
===================
from myapp import SomeObject
# stuff ...

TestCase.py
===================
from myapp import SomeObject
# some tests on SomeObject

No entanto, definitivamente estou fazendo algo errado, pois o Python não pode ver que myappé um módulo:

ImportError: No module named myapp
n0pe
fonte

Respostas:

95

No seu caso particular, parece que você está tentando importar SomeObjectdos scripts myapp.py e TestCase.py. No myapp.py, faça

import SomeObject

pois está na mesma pasta. Para TestCase.py, faça

from ..myapp import SomeObject

No entanto , isso funcionará apenas se você estiver importando o TestCase do pacote. Se você deseja executar diretamente python TestCase.py, teria que mexer no seu caminho. Isso pode ser feito no Python:

import sys
sys.path.append("..")
from myapp import SomeObject

embora isso geralmente não seja recomendado.

Em geral, se você quiser que outras pessoas usem seu pacote Python, use distutils para criar um script de instalação. Dessa forma, qualquer pessoa pode instalar seu pacote facilmente usando um comando como este python setup.py installe estará disponível em qualquer lugar da máquina. Se você é sério sobre o pacote, pode até adicioná-lo ao Índice de Pacotes Python, PyPI .

David Robinson
fonte
Eu tentei simplesmente usar importno meu, TestCase.pymas ele ainda me deu o mesmo erro. Estou assumindo que é porque está em um subdiretório do __init__.py?
n0pe 21/02/12
Oh espera, eu acho que entendi. Se meus casos de teste estiverem chamando do pacote, eu poderei usar o from ... import ...certo?
n0pe 21/02/12
1
Você somente se o TestCase estiver sendo importado de fora do pacote - por exemplo, se eu executar o from myapp.tests import TestCase from a script outside myapp. If you're running python TestCase.py` dentro da pasta de testes, você não poderá fazer importações relativas
David Robinson
1
Executei "pip install -e." Para instalar o myapp, mas, ao tentar executar o TestCase no código do visual studio, ainda recebo "ImportError: Nenhum módulo chamado myapp". mas se eu executar "python" e depois em python, executar "a partir de myapp import SomeObject", ele funcionará. O que estou fazendo de errado?
dagrun
@DavidRobinson Eu usei o método que você mencionou, que não mostrou erro após a execução from fodername import file_name_of_my_py_code, mas quando tentei acessar o objeto definido, file_name_of_my_py_code.pyele dizNameError: name 'ClassName' is not defined
Kavin Raju S
44

A função importprocura arquivos no seu ambiente PYTHONPATH. variável e seu diretório local. Então você pode colocar todos os seus arquivos no mesmo diretório ou exportar o caminho digitando para um terminal:

export PYTHONPATH="$PYTHONPATH:/path_to_myapp/myapp/myapp/"
Zenon
fonte
2
Então, como posso garantir que funcione para todos os outros que o usariam? Prefiro não precisar dizer a eles para definir determinadas variáveis ​​de ambiente antes de executá-lo.
n0pe 21/02/12
1
o diretório atual está em pythonpath, portanto, enquanto os scripts estiverem na mesma pasta / diretório, ele deverá funcionar. infelizmente, cada um desses scripts está em diretórios separados.
JKirchartz
4
Para usuários do Windows, em vez de exporttermos "definido PYTHONPATH =% PYTHONPATH%; C: \ caminho_para_myapp \ myapp \ myapp \"
loved.by.Jesus
Em vs código que eu era capaz de corrigir isto adicionando PYTHONPATH Env variável ao meu launch.json: "env": { "PYTHONPATH": "$ {workspaceFolder}"}
Michael Armitage
11

exportar caminho é uma boa maneira. Outra maneira é adicionar um .pth ao local dos pacotes de sites. No meu mac, meu python mantém pacotes de sites em / Library / Python, mostrados abaixo

/Library/Python/2.7/site-packages

Criei um arquivo chamado awesome.pth em /Library/Python/2.7/site-packages/awesome.pth e, no arquivo, coloquei o seguinte caminho que referencia meus módulos impressionantes

/opt/awesome/custom_python_modules
jmontross
fonte
1
no caso em que estou trabalhando no windows, como faço para isso
Nwawel A Iroume
Não tenho certeza. No caso de você estar usando o Windows. Encontre algum software vm e use linux. Ou - veja esta resposta sobre a exportação de variáveis ​​no Windows. stackoverflow.com/questions/559816/…
jmontross 8/16
este é exatamente o que eu precisava
Lee88
1
Feliz em saber que @ Lee88 - Levei um tempo para descobrir isso me :)
jmontross
9

Podes tentar

from myapp.myapp import SomeObject

porque o nome do seu projeto é igual ao myapp.py, o que faz com que ele procure primeiro o documento do projeto

阿 东 刘
fonte
3

No seu primeiro diretório myapp, você pode adicionar um arquivo setup.py e adicionar dois códigos python em setup.py

from setuptools import setup
setup(name='myapp')

no seu primeiro diretório myapp na linha de comando, use pip install -e. instalar o pacote

未来 陆家嘴 顶尖 的 投资 人
fonte
2

pip installno Windows 10, o padrão é instalar em 'Arquivos de programas / PythonXX / Lib / site-packages', que é um diretório que requer privilégios administrativos. Por isso, corrigi meu problema executando o pip install como administrador (você deve abrir o prompt de comando como administrador, mesmo se estiver conectado com uma conta de administrador). Além disso, é mais seguro chamar pip do python.
por exemplo, em
python -m pip install <package-name>
vez de
pip install <package-name>

sziraqui
fonte
0

No meu caso, foi surpresa do Windows vs Python, apesar dos nomes de arquivos do Windows não diferenciarem maiúsculas de minúsculas, a importação do Python é. Portanto, se você tiver um Stuff.pyarquivo, precisará importar esse nome como está.

astrowalker
fonte
0

Você precisa ter

__init__.py

em todas as pastas com código com as quais você precisa interagir. Você também precisa especificar o nome da pasta superior do seu projeto em todas as importações, mesmo que o arquivo que você tentou importar esteja no mesmo nível.

Krysalead
fonte