ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

我想在 main.py 中使用 user.pydir.py 中的类。
如何将这些 Python 类导入main.py?
此外,如果 user.py 位于子目录中,我如何导入类 User

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

A
Amber

蟒蛇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

蟒蛇 3

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

from .user import User
from .dir import Dir

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

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

from .user import User
from .dir import Dir

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

在您的 main.py 中:

from user import Class

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

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

Class.method

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


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

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

import user

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

from . import user

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


我在 vs 代码中使用 pylint,并且在同一目录导入始终被标记为错误时遇到问题(import user 带有红色下划线);更改为相对导入 (from . import user),并且 linter 不再标记它。
如何找到当前目录
@xiaodai 不知道你的意思。我的第二个片段不适合你吗?要自己回答您的问题,可能使用 os.getcwd() 但这不是必需的
“从狗进口狗”为我工作 3.9.2
从 python3.3 开始更准确。感谢@lucidbrot,有趣的贡献!
A
Andreas Foteas

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

from .user import User
from .dir import Dir

不管用。然后你应该导入为

from . import user
from . import dir

您能否澄清“不包括课程”的含义?
我的意思是在 file.py 中只定义了变量和函数 def 而没有描述的类 here
j
joe

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

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 *
H
Hassan

为了使其更易于理解:

第 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

第五步:运行程序

$ python main.py

输出将是

[Class1 OK]: 
[Class2 OK]:

如果这不起作用并且 main.py 无法读取 class1 或 class2 会发生什么?...我们缺少什么?
Y
Yasith Praharshana

蟒蛇 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()

c
ceth
from user import User 
from dir import Dir 

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

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

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


使用绝对路径。 from bin.user import User 假设 bin 是根目录。这也适用于 python 2 和 python 3。
m
minglyu

对于 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 的所有内容都将在包加载期间初始化。


I
Iceberg

对于python3

从兄弟导入:from .user import User
从侄子导入:from .usr.user import User


k
kobako

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

import filename

我正在使用python3.7


A
Andreas Klein
# 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!

纯代码答案并不是特别有用。请添加一些关于此代码如何解决问题的描述。
i
icharis

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 或完全删除。
H
Hafiz Muhammad Shafiq

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

from classes.myscript import *

仅导入选定的类

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

此答案中看到的通配符导入通常被视为 PEP 8 中所述的不良样式。
r
rojo_hlerr

从同一目录导入

from . import the_file_you_want_to_import 

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

初始化文件

文件而不是你的文件然后

从目录导入 your_file


我不认为这个答案增加了其他答案没有的任何东西,也不是对其他答案的全面总结。所以我想知道你为什么写它