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


675

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

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

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

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


Answers:


932

Python 2

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

然后做...

from user import User
from dir import Dir

如果文件位于子目录中,则同样适用-也将一个__init__.py放在子目录中,然后使用带点标记的常规import语句。对于每个级别的目录,您都需要添加到导入路径。

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

14
如果__init__.py不是空的,那么无论是在__init__.py是会是什么时,可以使用导入的包(而不是导入到事情__init__.py将无法使用在所有)。
2013年

23
为什么根本__init__.py需要一个文件?如果我将所有三个文件放在同一目录中并运行main.py,则import无需另外两个模块就可以正常运行。我想念什么?
martineau 2013年

30
因为这就是Python识别允许导入目录的方式。您正在运行的脚本目录是一个例外-始终允许您从中导入脚本。
2013年

20
@nbro和Amber:FWIW,关于__init__.py能够导入同一目录中的其他模块,我认为有些细微的变化。具体来说import,与__init__.py文件本身在同一目录中的其他模块(在Python 2.7.8中工作)在Python 3.4.1中失败。为了解决这个问题,我必须在每个子目录的前面加上子目录的名称和一个点(即import module必须更改为import subdirectory.module)。幸运的是,这样做之后,它仍然可以在Python 2.7.8中工作。
martineau 2014年

4
我可以确认此解决方案不再起作用。您可能希望更正,修改或完全删除它。
路易斯·德索萨

137

我刚刚了解到(感谢martineau的评论),为了从同一目录中的文件导入类,您现在应该使用Python 3编写代码:

from .user import User
from .dir import Dir

7
如果我尝试不,我会收到以下错误,ValueError: Attempted relative import in non-package但是当我更改为from user import User
Korpel

我从.fileloader进口Fileloader使用,并得到导入错误:无法导入名称“Fileloader”
Frikster

3
@Korpel:经过stackoverflow.com/questions/11536764/…中的讨论,我逐渐认识到上述给定导入是否起作用取决于:[1]脚本的调用方式(是否作为包)[2]其中实际的工作路径是在执行时[3]如何填充运行环境的路径变量
ecp 2016年

39

在您的main.py

from user import Class

Class您要导入的类的名称在哪里。

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

Class.method

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


1
如果要导入的模块没有类,该怎么办?只是原始功能?在python 2中,我所要做的就是“导入模块”。在python 3中不起作用,'import .module'也不起作用
Frikster

2
删除时,此功能在python3中有效__init__.py
引擎力量

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)

10

在python3,__init__.py不再需要。如果控制台的当前目录是python脚本所在的目录,则一切正常

import user

但是,如果从不包含的其他目录中调用,则此方法将无效user.py
在这种情况下,请使用

from . import user

即使您要导入整个文件,而不是仅从那里导入一个类,也可以使用该方法。


2
我在vs代码中使用了pylint,并且在同目录导入始终被标记为错误时遇到麻烦(import user用红色下划线标记);更改为相对导入(from . import user),并且短绒棉不再标记它。
rbatt

9

为了更容易理解:

第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]:

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

6

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



0

我不确定为什么可以使用Pycharm build from file_in_same_dir import class_name

IDE对此有所抱怨,但似乎仍然可以使用。我正在使用Python 3.7


-2

太简单了,创建一个文件__init__.py为classes目录,然后将其导入到脚本中,如下所示(全部导入)

from classes.myscript import *

仅导入选定的类

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

4
如答案中所示,通配符导入通常被认为是不良样式,如PEP 8中所述
V02460

-3

从同一目录导入

from . import the_file_you_want_to_import 

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

初始化 .py

档案以外的档案,然后

从目录导入your_file


3
我认为此答案不会添加其他答案没有的任何内容,也不是其他答案的全面摘要。所以我想知道您为什么写它
lucidbrot

-3

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

像这样


3
与其他答案相比,该答案实际上没有添加任何内容,也没有任何解释。有什么方法可以编辑答案以增加或改善答案?因为否则,它将像该答案被删除或被完全删除一样被否决。
Das_Geek '19
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.