Eu não sou experiente em python, portanto, se houver algo errado em minhas palavras, apenas me diga. Se sua hierarquia de arquivos estiver organizada assim:
project\
module_1.py
module_2.py
module_1.pydefine uma função chamada func_1(), module_2.py :
from module_1 import func_1
def func_2():
func_1()
if __name__ == '__main__':
func_2()
e você executa python module_2.pyno cmd, ele executa o que func_1()define. Geralmente é assim que importamos os mesmos arquivos de hierarquia. Mas quando você escreve from .module_1 import func_1em module_2.py, interpretador Python vai dizer No module named '__main__.module_1'; '__main__' is not a package. Portanto, para corrigir isso, mantemos a alteração que acabamos de fazer e movemos os dois módulos para um pacote e fazemos um terceiro módulo como chamador para executar module_2.py.
project\
package_1\
module_1.py
module_2.py
main.py
main.py :
from package_1.module_2 import func_2
def func_3():
func_2()
if __name__ == '__main__':
func_3()
Mas a razão por que adicionar um .antes module_1em module_2.pyé que se nós não fazemos isso e correr main.py, interpretador Python vai dizer No module named 'module_1', isso é um pouco complicado, module_1.pyé bem ao lado module_2.py. Agora eu deixo func_1()em module_1.pyfazer alguma coisa:
def func_1():
print(__name__)
que __name__registra quem chama func_1. Agora mantemos o .antes module_1, execute main.py, ele será impresso package_1.module_1, não module_1. Indica que quem telefona func_1()está na mesma hierarquia que main.py, o .que implica que module_1está na mesma hierarquia que module_2.pyele. Portanto, se não houver um ponto, main.pyele reconhecerá module_1na mesma hierarquia que ele, ele poderá reconhecer package_1, mas não o que "está abaixo" dele.
Agora vamos complicar um pouco. Você tem um config.inie um módulo define uma função para lê-la na mesma hierarquia que 'main.py'.
project\
package_1\
module_1.py
module_2.py
config.py
config.ini
main.py
E, por algum motivo inevitável, é necessário chamá-lo com module_2.py, portanto, ele deve ser importado da hierarquia superior. module_2.py :
import ..config
pass
Dois pontos significam importação da hierarquia superior (acesso de três pontos superior a superior e assim por diante). Agora corremos main.py, o intérprete vai dizer: ValueError:attempted relative import beyond top-level package. O "pacote de nível superior" aqui é main.py. Só porque config.pyestá ao lado main.py, eles estão na mesma hierarquia, config.pynão estão "abaixo" main.pyou não são "liderados" por main.py, portanto estão além main.py. Para corrigir isso, a maneira mais simples é:
project\
package_1\
module_1.py
module_2.py
config.py
config.ini
main.py
Eu acho que isso coincide com o princípio de organizar a hierarquia de arquivos do projeto, você deve organizar módulos com funções diferentes em pastas diferentes e deixar apenas um chamador de fora, e importar como quiser.