如何在同一目录或子目录中导入类?

Posted

技术标签:

【中文标题】如何在同一目录或子目录中导入类?【英文标题】:How to import the class within the same directory or sub directory? 【发布时间】:2011-05-07 17:29:38 【问题描述】:

我有一个存储所有 .py 文件的目录。

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

我想在 ma​​in.py 中使用来自 user.pydir.py 的类。 如何将这些 Python 类导入 ma​​in.py? 此外,如果 user.py 在子目录中,我如何导入 User 类?

bin/
    dir.py
    main.py
    usr/
        user.py

【问题讨论】:

另见Python: import a file from a subdirectory中的答案。 I answered similar question here 【参考方案1】:

从python3.3开始,__init__.py是no longer necessary。如果控制台的当前目录是python脚本所在的目录,一切正常

import user

但是,如果从不包含 user.py 的不同目录调用,这将不起作用。 在这种情况下,使用

from . import user

即使您想导入整个文件而不是从那里导入一个类,这也有效。

【讨论】:

我在 vs 代码中使用 pylint,并且在同目录导入总是被标记为错误时遇到问题(import user 带有红色下划线);更改为相对导入 (from . import user),linter 不再标记它。 如何找到当前目录 @xiaodai 不明白你的意思。我的第二个 sn-p 不适合你吗?自己回答你的问题,可能是os.getcwd(),但这不是必需的 " from dog import Dog" 为我工作 3.9.2 更准确地说是从 python3.3 开始。感谢@lucidbrot,有趣的贡献!【参考方案2】:

对于 Python 3+,假设你有这样的结构:

A/
  __init__.py
  bar.py
  foo.py

在您的__init__.py 文件中,您可以输入from . import foo

然后你可以在bar文件中导入foo

# A/bar.py
from foo import YourClass

__init__.py 文件的目的是包含可选的初始化代码,这些代码在遇到不同级别的包时运行。您放入 __init__.py 的所有内容都将在包加载期间初始化。

【讨论】:

【参考方案3】:
# My Python version: 3.7
# IDE: Pycharm 2021.1.2 Community

# Have "myLib" in folder "labs":

class Points:
    def __init__(self, x = 0, y = 0):
        self.__x = x
        self.__y = y
    def __str__(self):
        return f"x = self.__x, y = self.__y"

# Have "myFile" in (same) folder "labs":

from myFile import Point

p1 = Point(1, 4)
p2 = Point(1, 4)
print(f"p1: p1, p2: p2")

# Result:
# p1: x = 1, y = 4, p2: x = 1, y = 4

# Good Luck!

【讨论】:

纯代码答案并不是特别有用。请添加一些关于此代码如何解决问题的说明。【参考方案4】:

如果您在同一文件夹中有filename.py,您可以像这样轻松导入:

import filename

我正在使用python3.7

【讨论】:

【参考方案5】:

对于python3

从同级导入:from .user import User 从侄子导入:from .usr.user import User

【讨论】:

【参考方案6】:

我不确定为什么会这样,但使用 Pycharm 构建 from file_in_same_dir import class_name

IDE 抱怨它,但它似乎仍然有效。我正在使用 Python 3.7

【讨论】:

使用绝对路径。 from bin.user import User 假设 bin 是根目录。这也适用于 python 2 和 python 3。【参考方案7】:

Python3

使用

from .user import User inside dir.py file

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

像这样

【讨论】:

这个答案并没有比其他答案已经做的更多,也没有解释。有什么方法可以edit your answer 来添加或改进它吗?因为否则,它将被否决like this answer was 或完全删除。【参考方案8】:

如果 user.py 和 dir.py 不包括类,那么

from .user import User
from .dir import Dir

不工作。然后你应该导入为

from . import user
from . import dir

【讨论】:

您能否澄清一下您所说的“不包括课程”是什么意思? 我的意思是在file.py 中只定义了变量和函数def,没有here 描述的类【参考方案9】:

从同一目录导入

from . import the_file_you_want_to_import 

从子目录导入该目录应包含

初始化.py

文件不是你的文件然后

从目录导入你的文件

【讨论】:

我认为这个答案没有增加其他答案没有的任何内容,也不是其他答案的全面总结。所以我想知道你为什么写它【参考方案10】:

太简短了, 创建一个文件 __init__.py 是 classes 目录,然后将其导入到您的脚本中,如下所示(导入所有大小写)

from classes.myscript import *

仅导入选定的类

from classes.myscript import User
from classes.myscript import Dir

【讨论】:

在这个答案中看到的通配符导入通常被认为是错误的样式,如PEP 8中所述。【参考方案11】:

Python 3


同样的directory

导入文件:log.py

导入类:SampleApp()

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

目录是basic

导入文件:log.py.

导入类:SampleApp()

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

【讨论】:

【参考方案12】:

为了更容易理解:

第 1 步:让我们转到一个目录,其中将包含所有内容

$ cd /var/tmp

第 2 步:现在让我们创建一个 class1.py 文件,该文件具有类名 Class1 和一些代码

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

第 3 步:现在让我们创建一个 class2.py 文件,该文件具有类名 Class2 和一些代码

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

第 4 步:现在让我们创建一个 main.py,该文件将执行一次以使用来自 2 个不同文件的 Class1 和 Class2

$ 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

第 5 步:运行程序

$ python main.py

输出将是

[Class1 OK]: 
[Class2 OK]:

【讨论】:

如果这不起作用并且 main.py 无法读取 class1 或 class2 会发生什么?...我们缺少什么?【参考方案13】:

如果您不想将函数和类与您的混合使用,您可以导入模块并通过其名称进行访问

import util # imports util.py

util.clean()
util.setup(4)

或者你可以将函数和类导入你的代码

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

您可以使用 wildchar * 将该模块中的所有内容导入到您的代码中

from util import *
clean()
setup(4)

【讨论】:

import * 不再推荐【参考方案14】:

Python 2

在与文件相同的目录中创建一个名为 __init__.py 的空文件。这将向 Python 表示“可以从该目录导入”。

那就做吧……

from user import User
from dir import Dir

如果文件位于子目录中,情况也是如此——在子目录中也放置一个__init__.py,然后使用带有点符号的常规导入语句。对于每一级目录,都需要添加到导入路径。

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

所以如果目录被命名为“classes”,那么你应该这样做:

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

Python 3

与之前相同,但如果不使用子目录,则在模块名称前加上 .

from .user import User
from .dir import Dir

【讨论】:

如果__init__.py not 为空,那么__init__.py 中的任何内容都是在您导入包时可用的内容(以及未导入__init__.py 的内容) '根本不可用)。 为什么需要__init__.py 文件?如果我将所有三个文件放在同一个目录中并运行main.py,那么没有它,它就可以从其他两个模块中运行import。我错过了什么? 因为这就是 Python 识别允许从中导入的目录的方式。您正在运行的脚本目录是一个例外 - 您始终可以从中导入。 @nbro & Amber:FWIW,我认为__init__.py 发生了一些微妙的变化,并且能够在同一目录中导入其他模块。特别是 imports 与 __init__.py 文件本身在 Python 2.7.8 中工作的同一目录中的其他模块,在 Python 3.4.1 中失败。为了解决这个问题,我必须在每个文件前面加上子目录的名称和一个点(即 import module 必须更改为 import subdirectory.module)。幸运的是,这样做之后它仍然可以在 Python 2.7.8 中运行。 我可以确认此解决方案不再起作用。您可能希望更正、修改或彻底删除它。【参考方案15】:

在你的main.py:

from user import Class

其中Class 是您要导入的类的名称。

如果要调用Class的方法,可以使用:

Class.method

请注意,同一目录中应该有一个空的__init__.py 文件。

【讨论】:

如果您尝试导入的模块没有类,您会怎么做?只是原始函数?在 python 2 中,我所要做的就是“导入模块”。在 python 3 中不起作用,'import .module' 也不起作用 删除__init__.py后在python3中有效。【参考方案16】:

我刚刚了解到(感谢martineau's comment),为了从同一目录中的文件导入类,您现在需要使用 Python 3 编写:

from .user import User
from .dir import Dir

【讨论】:

如果我尝试这个不我得到以下错误ValueError: Attempted relative import in non-package 但是当我更改为from user import User 时错误消失 我使用 from .fileloader import Fileloader 并得到 ImportError: cannot import name 'Fileloader' @Korpel:在***.com/questions/11536764/… 中的讨论之后,我意识到上述给定的导入是否有效取决于:[1] 如何调用您的脚本(作为包或不作为包)[2 ] 执行时实际工作路径在哪里 [3] 如何填充运行环境的路径变量 为什么很难找到这个问题的明确答案?我要做的就是在一个单独的文件中创建一个类,然后将该类导入到同一目录中的另一个文件中。如果我使用像这个答案这样的相对导入,我也会得到 VlaueError 有人有解决方案吗? @Jiren 你找到了吗?好像你说的这么简单的问题……【参考方案17】:
from user import User 
from dir import Dir 

【讨论】:

这对我有用,但没有 Python 2.7 和 Python 3.6 的 init.py 文件。 @imsrgadich 只要您在包含文件的目录中运行 python,它就可以工作。这是一个例外。见this comment

以上是关于如何在同一目录或子目录中导入类?的主要内容,如果未能解决你的问题,请参考以下文章

Jpype:在jar中导入类时出现ModuleNotFoundError

Typescript:如何从 javascript 文件中导入类?

Python:如何禁止从模块中导入类?

在 JSP 文件中导入类

使用 css 模块,如何从文件中导入类

如何禁用模块中导入类的自动linting?