简体   繁体   English

从不同文件夹导入文件

[英]Importing files from different folder

I have this folder structure:我有这个文件夹结构:

application
├── app
│   └── folder
│       └── file.py
└── app2
    └── some_folder
        └── some_file.py

How can I import a function from file.py , from within some_file.py ?如何从file.py中的 file.py 导入some_file.py I tried:我试过了:

from application.app.folder.file import func_name

but it doesn't work.但它不起作用。

Note: This answer was intended for a very specific question.注意:此答案旨在解决一个非常具体的问题。 For most programmers coming here from a search engine, this is not the answer you are looking for.对于大多数从搜索引擎来到这里的程序员来说,这不是您要寻找的答案。 Typically you would structure your files into packages (see other answers) instead of modifying the search path.通常,您会将文件构造成包(请参阅其他答案),而不是修改搜索路径。


By default, you can't.默认情况下,您不能。 When importing a file, Python only searches the directory that the entry-point script is running from and sys.path which includes locations such as the package installation directory (it's actually a little more complex than this, but this covers most cases).导入文件时,Python 仅搜索运行入口点脚本的目录和sys.path ,其中包括包安装目录等位置(实际上比这要复杂一些,但这涵盖了大多数情况)。

However, you can add to the Python path at runtime:但是,您可以在运行时添加到 Python 路径:

# some_file.py
import sys
# insert at 1, 0 is the script path (or '' in REPL)
sys.path.insert(1, '/path/to/application/app/folder')

import file

Nothing wrong with:没有错:

from application.app.folder.file import func_name

Just make sure folder also contains an __init__.py , this allows it to be included as a package.只需确保folder还包含一个__init__.py ,这允许它作为一个包包含。 Not sure why the other answers talk about PYTHONPATH .不知道为什么其他答案谈论PYTHONPATH

When modules are in parallel locations, as in the question:当模块位于并行位置时,如问题所示:

application/app2/some_folder/some_file.py
application/app2/another_folder/another_file.py

This shorthand makes one module visible to the other:此简写使一个模块对另一个模块可见:

import sys
sys.path.append('../')

First import sys in name-file.py首先在 name-file.py 中导入 sys

 import sys

Second append the folder path in name-file.py其次在 name-file.py 中附加文件夹路径

sys.path.insert(0, '/the/folder/path/name-package/')

Third Make a blank file called __ init __.py in your subdirectory (this tells Python it is a package)第三在您的子目录中创建一个名为 __ init __.py 的空白文件(这告诉 Python 它是一个包)

  • name-file.py名称文件.py
  • name-package名称包
    • __ init __.py __ 初始化 __.py
    • name-module.py名称-module.py

Fourth import the module inside the folder in name-file.py、在name-file.py文件夹内导入模块

from name-package import name-module

I think an ad-hoc way would be to use the environment variable PYTHONPATH as described in the documentation: Python2 , Python3我认为一种特别的方法是使用文档中描述 的环境变量PYTHONPATHPython2Python3

# Linux & OSX
export PYTHONPATH=$HOME/dirWithScripts/:$PYTHONPATH

# Windows
set PYTHONPATH=C:\path\to\dirWithScripts\;%PYTHONPATH%

Your problem is that Python is looking in the Python directory for this file and not finding it.您的问题是 Python 正在 Python 目录中查找此文件,但没有找到它。 You must specify that you are talking about the directory that you are in and not the Python one.您必须指定您正在谈论的是您所在的目录,而不是 Python 目录。

To do this you change this:为此,您需要更改:

from application.app.folder.file import func_name

to this:对此:

from .application.app.folder.file import func_name

By adding the dot you are saying look in this folder for the application folder instead of looking in the Python directory.通过添加点,您要在此文件夹中查找应用程序文件夹,而不是在 Python 目录中查找。

The answers here are lacking in clarity, this is tested on Python 3.6这里的答案不够清晰,这是在 Python 3.6 上测试的

With this folder structure:使用此文件夹结构:

main.py
|
---- myfolder/myfile.py

Where myfile.py has the content: myfile.py的内容在哪里:

def myfunc():
    print('hello')

The import statement in main.py is: main.py中的导入语句为:

from myfolder.myfile import myfunc
myfunc()

and this will print hello .这将打印hello

In Python 3.4 and later, you can import from a source file directly (link to documentation) .在 Python 3.4 及更高版本中,您可以直接从源文件导入(链接到文档) This is not the simplest solution, but I'm including this answer for completeness.这不是最简单的解决方案,但为了完整起见,我将这个答案包括在内。

Here is an example.这是一个例子。 First, the file to be imported, named foo.py :首先,要导入的文件,名为foo.py

def announce():
    print("Imported!")

The code that imports the file above, inspired heavily by the example in the documentation:导入上述文件的代码深受文档中示例的启发:

import importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

foo = module_from_file("foo", "/path/to/foo.py")

if __name__ == "__main__":
    print(foo)
    print(dir(foo))
    foo.announce()

The output:输出:

<module 'foo' from '/path/to/foo.py'>
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!

Note that the variable name, the module name, and the filename need not match.请注意,变量名、模块名和文件名不必匹配。 This code still works:此代码仍然有效:

import importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

baz = module_from_file("bar", "/path/to/foo.py")

if __name__ == "__main__":
    print(baz)
    print(dir(baz))
    baz.announce()

The output:输出:

<module 'bar' from '/path/to/foo.py'>
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!

Programmatically importing modules was introduced in Python 3.1 and gives you more control over how modules are imported.以编程方式导入模块是在 Python 3.1 中引入的,让您可以更好地控制模块的导入方式。 Refer to the documentation for more information.有关详细信息,请参阅文档。

Try Python's relative imports:尝试 Python 的相对导入:

from ...app.folder.file import func_name

Every leading dot is another higher level in the hierarchy beginning with the current directory.每个前导点都是从当前目录开始的层次结构中的另一个更高级别。


Problems?问题? If this isn't working for you then you probably are getting bit by the many gotcha's relative imports has.如果这对您不起作用,那么您可能会被许多 gotcha 的相对导入所吸引。 Read answers and comments for more details: How to fix "Attempted relative import in non-package" even with __init__.py阅读答案和评论以获取更多详细信息: 即使使用 __init__.py,如何修复“尝试在非包中进行相对导入”

Hint: have __init__.py at every directory level.提示:在每个目录级别都有__init__.py You might need python -m application.app2.some_folder.some_file (leaving off .py) which you run from the top level directory or have that top level directory in your PYTHONPATH.您可能需要从顶级目录运行的python -m application.app2.some_folder.some_file (不包括 .py),或者在 PYTHONPATH 中有该顶级目录。 Phew!呸!

据我所知,直接在要导入的函数的文件夹中添加一个__init__.py文件就可以了。

Using sys.path.append with an absolute path is not ideal when moving the application to other environments.将应用程序移动到其他环境时,将sys.path.append与绝对路径一起使用并不理想。 Using a relative path won't always work because the current working directory depends on how the script was invoked.使用相对路径并不总是有效,因为当前工作目录取决于脚本的调用方式。

Since the application folder structure is fixed, we can use os.path to get the full path of the module we wish to import.由于应用程序文件夹结构是固定的,我们可以使用os.path来获取我们希望导入的模块的完整路径。 For example, if this is the structure:例如,如果这是结构:

/home/me/application/app2/some_folder/vanilla.py
/home/me/application/app2/another_folder/mango.py

And let's say that you want to import the mango module.假设您要导入mango模块。 You could do the following in vanilla.py :您可以在vanilla.py中执行以下操作:

import sys, os.path
mango_dir = (os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
+ '/another_folder/')
sys.path.append(mango_dir)
import mango

Of course, you don't need the mango_dir variable.当然,您不需要mango_dir变量。

To understand how this works look at this interactive session example:要了解其工作原理,请查看此交互式会话示例:

>>> import os
>>> mydir = '/home/me/application/app2/some_folder'
>>> newdir = os.path.abspath(os.path.join(mydir, '..'))
>>> newdir
    '/home/me/application/app2'
>>> newdir = os.path.abspath(os.path.join(mydir, '..')) + '/another_folder'
>>> 
>>> newdir
'/home/me/application/app2/another_folder'
>>> 

And check the os.path documentation.并检查os.path文档。

Also worth noting that dealing with multiple folders is made easier when using packages , as one can use dotted module names.另外值得注意的是,使用packages时处理多个文件夹会更容易,因为可以使用带点的模块名称。

I was faced with the same challenge, especially when importing multiple files, this is how I managed to overcome it.我面临着同样的挑战,尤其是在导入多个文件时,这就是我设法克服的方法。

import os, sys

from os.path import dirname, join, abspath
sys.path.insert(0, abspath(join(dirname(__file__), '..')))

from root_folder import file_name

Worked for me in python3 on linux在 Linux 上的 python3 中为我工作

import sys  
sys.path.append(pathToFolderContainingScripts)  
from scriptName import functionName #scriptName without .py extension  

Considering application as the root directory for your python project, create an empty __init__.py file in application , app and folder folders.application视为 python 项目的根目录,在applicationappfolder文件夹中创建一个空的__init__.py文件。 Then in your some_file.py make changes as follows to get the definition of func_name:然后在您的some_file.py中进行如下更改以获得 func_name 的定义:

import sys
sys.path.insert(0, r'/from/root/directory/application')

from application.app.folder.file import func_name ## You can also use '*' wildcard to import all the functions in file.py file.
func_name()

The best practice for creating a package can be running and accessing the other modules from a module like main_module.py at highest level directory.创建包的最佳实践可以是从最高级别目录中的main_module.py等模块运行和访问其他模块。

This structure demonstrates you can use and access sub package, parent package, or same level packages and modules by using a top level directory file main_module.py .该结构展示了您可以通过使用顶级目录文件main_module.py来使用和访问子包、父包或同级包和模块。

Create and run these files and folders for testing:创建并运行这些文件和文件夹以进行测试:

 package/
    |
    |----- __init__.py (Empty file)
    |------- main_module.py (Contains: import subpackage_1.module_1)        
    |------- module_0.py (Contains: print('module_0 at parent directory, is imported'))
    |           
    |
    |------- subpackage_1/
    |           |
    |           |----- __init__.py (Empty file)
    |           |----- module_1.py (Contains: print('importing other modules from module_1...')
    |           |                             import module_0
    |           |                             import subpackage_2.module_2
    |           |                             import subpackage_1.sub_subpackage_3.module_3)
    |           |----- photo.png
    |           |
    |           |
    |           |----- sub_subpackage_3/
    |                        |
    |                        |----- __init__.py (Empty file)
    |                        |----- module_3.py (Contains: print('module_3 at sub directory, is imported')) 
    |
    |------- subpackage_2/
    |           |
    |           |----- __init__.py (Empty file)
    |           |----- module_2.py (Contains: print('module_2 at same level directory, is imported'))

Now run main_module.py现在运行main_module.py

the output is输出是

>>>'importing other modules from module_1...'
   'module_0 at parent directory, is imported'
   'module_2 at same level directory, is imported'
   'module_3 at sub directory, is imported'

Opening pictures and files note:打开图片和文件注意:

In a package structure if you want to access a photo, use absolute directory from highest level directory.在包结构中,如果要访问照片,请使用最高级别目录中的绝对目录。

let's Suppose you are running main_module.py and you want to open photo.png inside module_1.py .假设您正在运行main_module.py并且您想在module_1.py photo.png

what module_1.py must contain is: module_1.py必须包含的是:

Correct:正确的:

image_path = 'subpackage_1/photo.png'
cv2.imread(image_path)

Wrong:错误的:

image_path = 'photo.png'
cv2.imread(image_path)

although module_1.py and photo.png are at same directory.尽管module_1.pyphoto.png位于同一目录中。

├───root
│   ├───dir_a
│   │   ├───file_a.py
│   │   └───file_xx.py
│   ├───dir_b
│   │   ├───file_b.py
│   │   └───file_yy.py
│   ├───dir_c
│   └───dir_n

You can add the parent directory to PYTHONPATH , in order to achieve that, you can use OS depending path in the "module search path" which is listed in sys.path .您可以将父目录添加到PYTHONPATH ,为了实现这一点,您可以在sys.path中列出的“模块搜索路径”中使用取决于操作系统的路径。 So you can easily add the parent directory like following:因此,您可以轻松添加父目录,如下所示:

# file_b.py

import sys
sys.path.insert(0, '..')

from dir_a.file_a import func_name

This works for me on windows这在 Windows 上对我有用

# some_file.py on mainApp/app2 
import sys
sys.path.insert(0, sys.path[0]+'\\app2')

import some_file

In my case I had a class to import.就我而言,我有一个要导入的课程。 My file looked like this:我的文件看起来像这样:

# /opt/path/to/code/log_helper.py
class LogHelper:
    # stuff here

In my main file I included the code via:在我的主文件中,我通过以下方式包含了代码:

import sys
sys.path.append("/opt/path/to/code/")
from log_helper import LogHelper

I'm quite special : I use Python with Windows !我很特别:我在 Windows 上使用 Python!

I just complete information : for both Windows and Linux, both relative and absolute path work into sys.path (I need relative paths because I use my scripts on the several PCs and under different main directories).我只是完成了信息:对于 Windows 和 Linux,相对路径和绝对路径都适用于sys.path (我需要相对路径,因为我在几台 PC 上和不同的主目录下使用我的脚本)。

And when using Windows both \ and / can be used as separator for file names and of course you must double \ into Python strings,在使用 Windows 时, \/都可以用作文件名的分隔符,当然你必须将\加倍到 Python 字符串中,
some valid examples :一些有效的例子:

sys.path.append('c:\\tools\\mydir')
sys.path.append('..\\mytools')
sys.path.append('c:/tools/mydir')
sys.path.append('../mytools')

(note : I think that / is more convenient than \ , event if it is less 'Windows-native' because it is Linux-compatible and simpler to write and copy to Windows explorer) (注意:我认为/\更方便,如果它不那么“Windows-native”,因为它与 Linux 兼容并且更易于编写和复制到 Windows 资源管理器)

I bumped into the same question several times, so I would like to share my solution.我多次碰到同样的问题,所以我想分享我的解决方案。

Python Version: 3.X Python版本:3.X

The following solution is for someone who develops your application in Python version 3.X because Python 2 is not supported since Jan/1/2020 .以下解决方案适用于在 Python 版本 3.X 中开发您的应用程序的人,因为自 2020 年 1 月 1 日起不支持 Python 2

Project Structure项目结构

In python 3, you don't need __init__.py in your project subdirectory due to the Implicit Namespace Packages .在 python 3 中,由于Implicit Namespace Packages ,您的项目子目录中不需要__init__.py See Is init .py not required for packages in Python 3.3+请参阅Python 3.3+ 中的包不需要init .py

Project 
├── main.py
├── .gitignore
|
├── a
|   └── file_a.py
|
└── b
    └── file_b.py

Problem Statement问题陈述

In file_b.py , I would like to import a class A in file_a.py under the folder a.file_b.py中,我想在文件夹 a 下的file_a.py中导入一个类A

Solutions解决方案

#1 A quick but dirty way #1 快速但肮脏的方式

Without installing the package like you are currently developing a new project无需像您当前正在开发新项目那样安装软件包

Using the try catch to check if the errors.使用try catch检查是否有错误。 Code example:代码示例:

import sys
try:
    # The insertion index should be 1 because index 0 is this file
    sys.path.insert(1, '/absolute/path/to/folder/a')  # the type of path is string
    # because the system path already have the absolute path to folder a
    # so it can recognize file_a.py while searching 
    from file_a import A
except (ModuleNotFoundError, ImportError) as e:
    print("{} fileure".format(type(e)))
else:
    print("Import succeeded")

#2 Install your package #2 安装你的包

Once you installed your application (in this post, the tutorial of installation is not included)一旦你安装了你的应用程序(在这篇文章中,安装教程不包括在内)

You can simply你可以简单地

try:
    from __future__ import absolute_import
    # now it can reach class A of file_a.py in folder a 
    # by relative import
    from ..a.file_a import A  
except (ModuleNotFoundError, ImportError) as e:
    print("{} fileure".format(type(e)))
else:
    print("Import succeeded")

Happy coding!快乐编码!

If the purpose of loading a module from a specific path is to assist you during the development of a custom module, you can create a symbolic link in the same folder of the test script that points to the root of the custom module.如果从特定路径加载模块的目的是在开发自定义模块期间为您提供帮助,您可以在测试脚本的同一文件夹中创建一个指向自定义模块根目录的符号链接。 This module reference will take precedence over any other modules installed of the same name for any script run in that folder.对于在该文件夹中运行的任何脚本,此模块引用将优先于安装的任何其他同名模块。

I tested this on Linux but it should work in any modern OS that supports symbolic links.我在 Linux 上对此进行了测试,但它应该适用于任何支持符号链接的现代操作系统。

One advantage to this approach is that you can you can point to a module that's sitting in your own local SVC branch working copy which can greatly simplify the development cycle time and reduce failure modes of managing different versions of the module.这种方法的一个优点是您可以指向位于您自己的本地 SVC 分支工作副本中的模块,这可以大大简化开发周期时间并减少管理模块不同版本的故障模式。

I was working on project a that I wanted users to install via pip install a with the following file list:我正在处理我希望用户通过pip install a项目a并带有以下文件列表:

.
├── setup.py
├── MANIFEST.in
└── a
    ├── __init__.py
    ├── a.py
    └── b
        ├── __init__.py
        └── b.py

setup.py安装程序.py

from setuptools import setup

setup (
  name='a',
  version='0.0.1',
  packages=['a'],
  package_data={
    'a': ['b/*'],
  },
)

MANIFEST.in清单文件

recursive-include b *.*

a/ init .py一个/初始化.py

from __future__ import absolute_import

from a.a import cats
import a.b

a/a.py a/a.py

cats = 0

a/b/ init .py a/b/初始化.py

from __future__ import absolute_import

from a.b.b import dogs

a/b/b.py a/b/b.py

dogs = 1

I installed the module by running the following from the directory with MANIFEST.in :我通过使用MANIFEST.in从目录运行以下命令来安装模块:

python setup.py install

Then, from a totally different location on my filesystem /moustache/armwrestle I was able to run:然后,从我的文件系统/moustache/armwrestle上一个完全不同的位置,我能够运行:

import a
dir(a)

Which confirmed that a.cats indeed equalled 0 and abdogs indeed equalled 1, as intended.这证实了a.cats确实等于 0 而abdogs确实等于 1,正如预期的那样。

Instead of just doing an import ... , do this :而不是仅仅做一个import ... ,这样做:

from <MySubFolder> import <MyFile>

MyFile is inside the MySubFolder. MyFile 位于 MySubFolder 中。

Wow, I did not expect to spend so much time on this.哇,我没想到会花这么多时间在这上面。 The following worked for me:以下对我有用:

OS : Windows 10操作系统:Windows 10

Python : v3.10.0蟒蛇:v3.10.0

Note : Since I am Python v3.10.0, I am not using __init__.py files, which did not work for me anyway.注意:由于我是 Python v3.10.0,我没有使用__init__.py文件,这对我来说无论如何都不起作用。

application
├── app
│   └── folder
│       └── file.py
└── app2
    └── some_folder
        └── some_file.py

WY Hsu's 1st solution worked for me. WY Hsu 的第一个解决方案对我有用。 I have reposted it with an absolute file reference for clarity:为了清楚起见,我已经用绝对文件参考重新发布了它:

import sys
sys.path.insert(1, 'C:\\Users\\<Your Username>\\application')
import app2.some_folder.some_file

some_file.hello_world()

Alternative Solution : However, this also worked for me:替代解决方案:但是,这也对我有用:

import sys
sys.path.append( '.' )
import app2.some_folder.some_file

some_file.hello_world()

Although, I do not understand why it works.虽然,我不明白为什么它会起作用。 I thought the dot is a reference to the current directory.我认为点是对当前目录的引用。 However, when printing out the paths to the current folder, the current directory is already listed at the top:但是,当打印出当前文件夹的路径时,当前目录已经列在顶部:

for path in sys.path:
    print(path)

Hopefully, someone can provide clarity as to why this works in the comments.希望有人可以在评论中说明为什么这样做有效。 Nevertheless, I also hope it helps someone.不过,我也希望它对某人有所帮助。

The code below imports the Python script given by it's path, no matter where it is located, in a Python version-safe way:下面的代码以 Python 版本安全的方式导入由其路径给出的 Python 脚本,无论它位于何处:

def import_module_by_path(path):
    name = os.path.splitext(os.path.basename(path))[0]
    if sys.version_info[0] == 2:   
        # Python 2
        import imp
        return imp.load_source(name, path)
    elif sys.version_info[:2] <= (3, 4):  
        # Python 3, version <= 3.4
        from importlib.machinery import SourceFileLoader
        return SourceFileLoader(name, path).load_module()
    else:                            
        # Python 3, after 3.4
        import importlib.util
        spec = importlib.util.spec_from_file_location(name, path)
        mod = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(mod)
        return mod

I found this in the codebase of psutils , at line 1042 in psutils.test.__init__.py ( most recent commit as of 09.10.2020 ).我在 psutils 的代码库中发现了这一点,位于psutils.test.__init__.py的第 1042 psutils.test.__init__.py最近一次提交为 09.10.2020 )。

Usage example:使用示例:

script = "/home/username/Documents/some_script.py"
some_module = import_module_by_path(script)
print(some_module.foo())

Important caveat: The module will be treated as top-level;重要警告:该模块将被视为顶级; any relative imports from parent packages in it will fail.从其中的父包中进行的任何相对导入都将失败。

In case anyone still looking for a solution.以防有人仍在寻找解决方案。 This worked for me.这对我有用。

Python adds the folder containing the script you launch to the PYTHONPATH, so if you run Python 将包含您启动的脚本的文件夹添加到 PYTHONPATH,因此如果您运行

python application/app2/some_folder/some_file.py

Only the folder application/app2/some_folder is added to the path (not the base dir that you're executing the command in).只有文件夹 application/app2/some_folder 被添加到路径中(不是您正在执行命令的基本目录)。 Instead, run your file as a module and add a __init__.py in your some_folder directory.相反,将文件作为模块运行并在 some_folder 目录中添加 __init__.py 。

python -m application.app2.some_folder.some_file

This will add the base dir to the python path, and then classes will be accessible via a non-relative import.这会将基本目录添加到 python 路径,然后可以通过非相对导入访问类。

You can use importlib to import modules where you want to import a module from a folder using a string like so:您可以使用 importlib 将模块导入到您希望使用如下字符串从文件夹中导入模块的位置:

import importlib

scriptName = 'Snake'

script = importlib.import_module('Scripts\\.%s' % scriptName)

This example has a main.py which is the above code then a folder called Scripts and then you can call whatever you need from this folder by changing the scriptName variable.这个例子有一个 main.py ,它是上面的代码,然后是一个名为 Scripts 的文件夹,然后您可以通过更改scriptName变量从该文件夹中调用您需要的任何内容。 You can then use script to reference to this module.然后,您可以使用script来引用此模块。 such as if I have a function called Hello() in the Snake module you can run this function by doing so:例如,如果我在 Snake 模块中有一个名为Hello()的函数,则可以通过以下方式运行此函数:

script.Hello()

I have tested this in Python 3.6我已经在 Python 3.6 中对此进行了测试

I usually create a symlink to the module I want to import.我通常会为要导入的模块创建一个符号链接。 The symlink makes sure Python interpreter can locate the module inside the current directory (the script you are importing the other module into);符号链接确保 Python 解释器可以在当前目录中找到模块(您将另一个模块导入到的脚本); later on when your work is over, you can remove the symlink.稍后当您的工作结束时,您可以删除符号链接。 Also, you should ignore symlinks in .gitignore, so that, you wouldn't accidentally commit symlinked modules to your repo.此外,您应该忽略 .gitignore 中的符号链接,这样您就不会意外地将符号链接模块提交到您的存储库。 This approach lets you even successfully work with modules that are located parallel to the script you are executing.这种方法甚至可以让您成功地使用与您正在执行的脚本平行的模块。

ln -s ~/path/to/original/module/my_module ~/symlink/inside/the/destination/directory/my_module

If you have multiple folders and sub folders, you can always import any class or module from the main directory .如果您有多个文件夹和子文件夹,您始终可以从主目录导入任何类或模块。

For example: Tree structure of the project例如:项目的树形结构

Project 
├── main.py
├── .gitignore
|
├── src
     ├────model
     |    └── user_model.py
     |────controller
          └── user_controller.py

Now, if you want to import "UserModel" class from user_model.py in main.py file, you can do that using:现在,如果你想从main.py文件中的 user_model.py 导入“UserModel”类,你可以使用:

from src.model.user_model.py import UserModel

Also, you can import same class in user_controller.py file using same line:此外,您可以使用同一行在user_controller.py文件中导入相同的类:

from src.model.user_model.py import UserModel

Overall, you can give reference of main project directory to import classes and files in any python file inside Project directory.总的来说,您可以参考主项目目录来导入项目目录内任何 python 文件中的类和文件。

This problem may be due Pycharm这个问题可能是由于 Pycharm

I had the same problem while using Pycharm.我在使用 Pycharm 时遇到了同样的问题。 I had this project structure我有这个项目结构

skylake\
   backend\
      apps\
          example.py
      configuration\
          settings.py
   frontend\
      ...some_stuff

and code from configuration import settings in example.py raised import error和 example.py 中from configuration import settings的代码引发了导入错误

the problem was that when I opened Pycharm, it considered that skylake is root path and ran this code问题是当我打开Pycharm时,它认为skylake是根路径并运行了这段代码

sys.path.extend(['D:\\projects\\skylake', 'D:/projects/skylake'])

To fix this I just marked backend directory as source root为了解决这个问题,我只是将后端目录标记为源根目录在此处输入图像描述

And it's fixed my problem它解决了我的问题

You can refresh the Python shell by pressing f5, or go to Run-> Run Module.您可以按 f5 刷新 Python shell,或转到 Run-> Run Module。 This way you don't have to change the directory to read something from the file.这样,您不必更改目录即可从文件中读取内容。 Python will automatically change the directory. Python 会自动更改目录。 But if you want to work with different files from different directory in the Python Shell, then you can change the directory in sys, as Cameron said earlier.但是如果你想在 Python Shell 中处理来自不同目录的不同文件,那么你可以更改 sys 中的目录,正如 Cameron之前所说。

So I had just right clicked on my IDE, and added a new folder and was wondering why I wasn't able to import from it.所以我刚刚右键单击了我的 IDE,并添加了一个新folder ,我想知道为什么我无法从中导入。 Later I realized I have to right click and create a Python Package, and not a classic file system folder.后来我意识到我必须右键单击并创建一个 Python 包,而不是一个经典的文件系统文件夹。 Or a post-mortem method being adding an __init__.py (which makes python treat the file system folder as a package) as mentioned in other answers.或者像其他答案中提到的那样,添加一个__init__.py (这使得 python 将文件系统文件夹视为一个包)的事后方法。 Adding this answer here just in case someone went this route.在这里添加这个答案,以防有人走这条路。

I've had these problems a number of times.我曾多次遇到这些问题。 I've come to this same page a lot.我经常来这个页面。 In my last problem I had to run the server from a fixed directory, but whenever debugging I wanted to run from different sub-directories.在我的最后一个问题中,我必须从固定目录运行server ,但每当调试时我想从不同的子目录运行。

import sys
sys.insert(1, /path) 

did NOT work for me because at different modules I had to read different *.csv files which were all in the same directory.对我不起作用,因为在不同的模块中,我必须读取不同的*.csv文件,这些文件都在同一个目录中。

In the end, what worked for me was not pythonic, I guess, but:最后,我猜对我有用的不是pythonic,而是:

I used a if __main__ on top of the module I wanted to debug , that is run from a different than usual path.在要调试的模块上使用了if __main__ ,它从不同于通常的路径运行。

So:所以:

# On top of the module, instead of on the bottom
import os
if __name__ == '__main__':
    os.chdir('/path/for/the/regularly/run/directory')

如果您只想运行脚本而不是实际导入它,则 exec 命令将完成工作

exec(open('/full/or/relative/path').read())

My solution for people.我为人们提供的解决方案。 who have all the necessary __init__.py in the package, but import still doesn't work.谁在包中有所有必要的__init__.py ,但导入仍然不起作用。

import sys
import os
sys.path.insert(0, os.getcwd())

import application.app.folder.file as file

You can use pip 's pip install -e.您可以使用pippip install -e. command.命令。 You must create a file called setup.py in the root of the project's directory which contains the following:您必须在项目目录的根目录中创建一个名为setup.py的文件,其中包含以下内容:

from setuptools import find_packages, setup

setup(
    name='src',
    packages=find_packages(),
    version='0.1.0',
    description='my_project',
    author='author',
    license='MIT',
)

Afterwards, enter pip install -e.然后输入pip install -e. while in your project's root directory.在项目的根目录中。 This will enable all directories to be called with their name as a module.这将使所有目录都以其名称作为模块被调用。 For example, if your root directory contains the subdirectories module1 and module2 , each with scripts inside them, you will be able to access them from any subdirectories with the following command, for module1 :例如,如果您的根目录包含子目录module1module2 ,每个子目录中都有脚本,您将能够使用以下命令从任何子目录访问它们,对于module1

import module1.script1 as script1

Just in case anyone still needs a solution and hasn't found one in the answers above.以防万一有人仍然需要解决方案并且没有在上面的答案中找到解决方案。 This worked for me:这对我有用:

I have this folder structure:我有这个文件夹结构:

a
└── b
    ├── c1
    |   └── d
    |       └── a_script.py
    └── c2
        └── a_lib.py

And I needed the a_lib.py to be included in the a_script.py .我需要将a_lib.py包含在a_script.py中。 This is how I resolved the error that c2 is not recognized:这就是我解决无法识别c2的错误的方法:

import sys
from pathlib import Path
path_scripts = Path(__file__).resolve().parents[2]
sys.path.append(str(path_scripts))
from c2 import a_lib

Just use change dir function from os module:只需使用 os 模块中的更改目录功能:

os.chdir("Here new director")

than you can import normally More Info比你可以正常导入更多信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM