如何从更深目录中的文件导入模块? [英] How to import modules from a file in a deeper directory?

查看:84
本文介绍了如何从更深目录中的文件导入模块?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我的项目结构如下:

let's say my project's structure looks like:

project
├── important.py
└── files
    └── file1.py

,文件Important.py包含重要类. 当file1是正在执行的python文件时,如何从file1导入类(重要)?.

and the file important.py contains the class Important. How can I import the class(Important) from file1, while file1 is the python file which being executed?.

我发现的唯一解决方案是添加以下代码,但我想知道是否有更干净的方法:

The only solution I found was to add this code, but I wonder if there is a cleaner way:

import sys; sys.path.append("..")
from important import Important

我尝试过的事没有成功:

Things I have tried without success:

from project.important import Important
# ModuleNotFoundError: No module named 'project'
# But it does work inside PyCharm (Why is that?)

from ..important import Important
# ValueError: attempted relative import beyond top-level package

即使我在项目目录中添加了__init__.py文件,该错误仍然显示.

And this errors were keep showing even if I added a __init__.py file inside the project's directory.

要说的是,我要寻找一种适用于任何机器的解决方案,因为我想在github上与公众分享这个项目.

import to say is that I am looking for a solution that will fit any machine, as I want to share this project on github to the public.

推荐答案

人们指出了sys.path.append("..")路线.尽管此方法有效,但还有os.chdir('..')

People have pointed out the sys.path.append("..") route. While this works there is also an alternative method with os.chdir('..')

您可以使用以下命令python3 -m site查看路径列表.导入软件包时,Python会检查所有这些路径中的模块.
sys.path中的第一个元素是当前工作目录.

You can view a list of your path with the following command python3 -m site. When importing packages Python checks for modules in all of those paths.
The first element in your sys.path is the current working directory.

在某些情况下,您可能不想使当前工作目录成为路径的一部分,并且希望将一个文件夹结构添加到路径中.

There may be a scenario where you don't want to have your current working directory be part of the path and want to have one folder structure up added to path.

问题"有多种导入同一事物的方法.例如,您有:

An "issue" is there are multiple ways of importing the same thing. For instance you have:

project/
├── important.py
└── files
    ├── file1.py
    └── file2.py

通过执行sys.path.append("..")并通过python3 file1.py运行程序,您可以通过import file2 from files import file2导入file2.这看起来不太好,您可能会开始编写不一致的代码,而又不了解导入的工作原理.

By doing sys.path.append("..") and running the program via python3 file1.py you can import file2 via import file2 or from files import file2. This doesn't look nice and you might start write inconsistent code while not understanding how import properly works.

如果有效,您可以坚持使用sys.path.append("..").你不会做错什么.这是许多人常用的方法.可能只是在一种特殊情况下,您可能会遇到问题,这就是为什么许多人偏爱os.chdir()方法的原因.

You can stick with sys.path.append("..")if it works. You won't do much wrong with it. It is a common approach many people do. There may just be a special scenario where you might run into problems which is why many people prefer the os.chdir() approach.

例如,在文件夹,顶层文件夹和子文件夹中,您都有共享相同名称的python模块.您想从一个文件夹中导入Python模块,而不要从当前文件夹中导入python模块.

For example in both folder, top folder and subfolder, you have python modules which share the same name. You want to import Python modules from one folder up but not the python modules in the current folder.

正在使用os.chdir()的示例:

Tin@ubuntu:~/Desktop/tmp/test$ python3
Python 3.6.8 (default, Oct  7 2019, 12:59:55) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.getcwd()
'/home/Tin/Desktop/tmp/test'
>>> import helloworld
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'helloworld'
>>> os.chdir('..')
>>> import helloworld
hello world!
>>> os.getcwd()
'/home/Tin/Desktop/tmp'

现在您可以从一个目录向上导入,并且导入不再是模棱两可.

Now you can import from one directory up and the import is no longer ambiguous.

请注意,当我写os.chdir('..')时,您可以执行@Tawy的操作.

Note that while I wrote os.chdir('..') you can do what @Tawy did.

import os
os.chdir(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
# OR:
os.chdir(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..'))

这看起来很令人困惑,但是您可以在内部想象当前的工作目录是什么,并基于该目录创建所有import语句.当您从各种子目录执行脚本但希望有一个特定的工作目录时,它还会为您提供一致的当前工作目录.
您可能还会犯两次错误地运行os.chdir('..'),这会使您进入两个文件夹结构.

It looks confusing but with this you can internally imagine what your current working directory is and base all your import statements on that. It also gives you a consistent current working directory when you are executing your script from all sorts of subdirectories but expect a certain working directory.
You may also do the mistake of running os.chdir('..') twice which will make you go two folders structure up.

简而言之:

最不复杂的解决方案是sys.path.append("..").较干净的解决方案是os.chdir(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..')),其中..是所需工作目录的相对位置.

Least complicated solution is sys.path.append(".."). A cleaner solution would be os.chdir(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..')) with the .. being the relative location to your wanted working directory.

这篇关于如何从更深目录中的文件导入模块?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆