Como importar a classe dentro do mesmo diretório ou subdiretório?

675

Eu tenho um diretório que armazena todos os arquivos .py .

bin/
   main.py
   user.py # where class User resides
   dir.py # where class Dir resides

Eu quero usar as classes de user.py e dir.py em main.py .
Como posso importar essas classes Python para main.py ?
Além disso, como posso importar a classe Userse user.py estiver em um subdiretório?

bin/
    dir.py
    main.py
    usr/
        user.py
Bin Chen
fonte

Respostas:

935

Python 2

Crie um arquivo vazio chamado __init__.pyno mesmo diretório que os arquivos. Isso significa para o Python que está "ok para importar deste diretório".

Então apenas faça ...

from user import User
from dir import Dir

O mesmo vale se os arquivos estiverem em um subdiretório - coloque um __init__.pyno subdiretório também e use instruções de importação regulares, com notação de ponto. Para cada nível de diretório, você precisa adicionar ao caminho de importação.

bin/
    main.py
    classes/
        user.py
        dir.py

Portanto, se o diretório tiver o nome "classes", faça o seguinte:

from classes.user import User
from classes.dir import Dir

Python 3

O mesmo que o anterior, mas prefixe o nome do módulo com a .se não estiver usando um subdiretório:

from .user import User
from .dir import Dir
Âmbar
fonte
14
Se não__init__.py estiver vazio, o que estiver dentro será o que estará disponível quando você importar o pacote (e as coisas que não foram importadas não estarão disponíveis). __init__.py__init__.py
22613 Amber
23
Por que um __init__.pyarquivo é necessário? Se eu colocar todos os três arquivos no mesmo diretório e executar main.py, ele poderá executar importos outros dois módulos sem ele. o que estou perdendo?
22613 martineau
30
Porque é assim que o Python identifica diretórios dos quais você pode importar. O diretório do script que você está executando é uma exceção - você sempre pode importar dele.
22613 Amber
20
@ nbro & Amber: FWIW, acho que algo sutil mudou no que diz respeito __init__.pye poder importar outros módulos no mesmo diretório. Especificamente, imports de outros módulos no mesmo diretório que o __init__.pypróprio arquivo que funcionava no Python 2.7.8, falhou no Python 3.4.1. Para corrigi-lo, tive que prefixar cada um deles com o nome do subdiretório e um ponto (ou seja, import moduletive que mudar para import subdirectory.module). Felizmente, ele ainda funcionou no Python 2.7.8 depois de fazer isso.
martineau
4
Posso confirmar que esta solução não está mais funcional. Você pode corrigir, alterar ou excluí-lo completamente.
Luís de Sousa
137

Acabei de aprender (graças ao comentário de martineau ) que, para importar classes de arquivos dentro do mesmo diretório, você agora escreveria em Python 3:

from .user import User
from .dir import Dir
ecp
fonte
7
se eu tentar isso não, eu recebo o seguinte erro ValueError: Attempted relative import in non-package, mas erro desaparece quando eu mudar parafrom user import User
Korpel
Eu uso do .fileloader import Fileloader e obtenho ImportError: não é possível importar o nome 'Fileloader'
#
3
@Korpel: Após as discussões em stackoverflow.com/questions/11536764/… , percebo que se a importação acima mencionada funciona ou não depende de: [1] como o seu script é chamado (como pacote ou não) [2] o caminho de trabalho real é quando você executá-lo [3] como a variável de caminho do seu ambiente de execução é povoada
ECP
@ Korpel: Eu notei que o. antes que o nome do módulo seja necessário apenas quando um arquivo .py init estiver presente, se não o. pode / deve ser omitido.
MUG4N
39

No seu main.py:

from user import Class

onde Classé o nome da classe que você deseja importar.

Se você deseja chamar um método de Class, pode chamá-lo usando:

Class.method

Observe que deve haver um __init__.pyarquivo vazio no mesmo diretório.

user225312
fonte
1
O que você faz se o módulo que você está tentando importar não possui classes? Apenas funções brutas? No python 2, tudo o que eu precisava fazer era 'módulo de importação'. Não funciona em python 3, nem o '.module importação'
Frikster
2
Isso funciona em python3 depois de excluído o arquivo __init__.py.
engineforce
13

Você pode importar o módulo e ter acesso pelo nome, se não quiser misturar funções e classes com as suas.

import util # imports util.py

util.clean()
util.setup(4)

ou você pode importar as funções e classes para o seu código

from util import clean, setup
clean()
setup(4)

você pode usar wildchar * para importar tudo nesse módulo para o seu código

from util import *
clean()
setup(4)
A.Zaben
fonte
10

No python3, não__init__.py é mais necessário . Se o diretório atual do console for o diretório em que o script python está localizado, tudo funcionará bem com

import user

No entanto, isso não funcionará se chamado de um diretório diferente, que não contém user.py.
Nesse caso, use

from . import user

Isso funciona mesmo se você quiser importar o arquivo inteiro em vez de apenas uma classe a partir daí.

lucidbrot
fonte
2
Estou usando o pylint no código vs e estava tendo problemas com uma importação no mesmo diretório sempre sendo sinalizada como um erro ( import usersublinhada em vermelho); alterado para a importação relativa ( from . import user) e o linter não o sinalizou mais.
rbatt
9

Para facilitar a compreensão:

Etapa 1: vamos para um diretório, onde tudo será incluído

$ cd /var/tmp

Etapa 2: agora vamos criar um arquivo class1.py com um nome de classe Class1 com algum código

$ cat > class1.py <<\EOF
class Class1:
    OKBLUE = '\033[94m'
    ENDC = '\033[0m'
    OK = OKBLUE + "[Class1 OK]: " + ENDC
EOF

Etapa 3: agora vamos criar um arquivo class2.py com um nome de classe Class2 com algum código

$ cat > class2.py <<\EOF
class Class2:
    OKBLUE = '\033[94m'
    ENDC = '\033[0m'
    OK = OKBLUE + "[Class2 OK]: " + ENDC
EOF

Etapa 4: agora vamos criar um main.py que será executado uma vez para usar Class1 e Class2 a partir de 2 arquivos diferentes

$ cat > main.py <<\EOF
"""this is how we are actually calling class1.py and  from that file loading Class1"""
from class1 import Class1 
"""this is how we are actually calling class2.py and  from that file loading Class2"""
from class2 import Class2

print Class1.OK
print Class2.OK
EOF

Etapa 5: executar o programa

$ python main.py

A saída seria

[Class1 OK]: 
[Class2 OK]:
Hassan Nadeem
fonte
4
E o que acontece se isso não funcionar e o main.py não puder ler a classe1 ou a classe2? ... o que estamos perdendo?
darkgaze
6

Python 3


O mesmo directory.

importar arquivo:log.py

classe de importação: SampleApp().

import log
if __name__ == "__main__":
    app = log.SampleApp()
    app.mainloop()

ou

diretório é basic.

importar no arquivo: log.py.

classe de importação: SampleApp().

from basic import log
if __name__ == "__main__":
    app = log.SampleApp()
    app.mainloop()
Yasith Praharshana
fonte
5
from user import User 
from dir import Dir 
demas
fonte
Isso funcionou para mim sem ter o arquivo init .py para o Python 2.7 e o Python 3.6.
Imgifray> <imsrgadich>
1
@imsrgadich funciona desde que você esteja executando o python no diretório que contém os arquivos. Isso é uma exceção. Ver este comentário
Ciprian Tomoiagă
5

Se user.py e dir.py não estiverem incluindo classes,

from .user import User
from .dir import Dir

não está funcionando. Você deve importar como

from . import user
from . import dir
Andreas Foteas
fonte
0

Não sei por que esse trabalho, mas usando o Pycharm build from file_in_same_dir import class_name

O IDE reclamou, mas parece que ainda funcionou. Estou usando Python 3.7

stingMantis
fonte
-2

Brevemente, Criar um arquivo __init__.pyé diretório de classes e importá-lo para o seu script, como a seguir (Importar todos os casos)

from classes.myscript import *

Importar apenas classes selecionadas

from classes.myscript import User
from classes.myscript import Dir
Shafiq
fonte
4
As importações de curingas, como vistas nesta resposta, são geralmente consideradas como estilo incorreto, conforme descrito no PEP 8 .
V02460 26/07/2018
-3

importar do mesmo diretório

from . import the_file_you_want_to_import 

Para importar do subdiretório, o diretório deve conter

init .py

arquivo diferente de você arquivos então

do diretório import your_file

rojo_hlerr
fonte
3
Acho que essa resposta não acrescenta nada que outras respostas não acrescentaram e também não é um resumo abrangente das outras respostas. Então eu me pergunto por que você escreveu
lucidbrot
-3

Python3

usar

from .user import User inside dir.py file

e

use from class.dir import Dir inside main.py
or from class.usr import User inside main.py

igual a

icharis
fonte
3
Essa resposta realmente não adiciona nada mais do que a outra resposta já faz e não tem explicação. Existe alguma maneira de editar sua resposta para adicioná-la ou melhorá-la? Porque, caso contrário, deve ser votado como esta resposta foi ou foi removida inteiramente.
Das_Geek 5/12/19