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

Bin*_*hen 582 python python-import

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

bin/
   main.py
   user.py # where class User resides
   dir.py # where class Dir resides
Run Code Online (Sandbox Code Playgroud)

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

bin/
    dir.py
    main.py
    usr/
        user.py
Run Code Online (Sandbox Code Playgroud)

Amb*_*ber 817

Python 2

在与文件__init__.py相同的目录中创建一个空文件.这将表明Python"可以从这个目录导入".

那就做......

from user import User
from dir import Dir
Run Code Online (Sandbox Code Playgroud)

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

bin/
    main.py
    classes/
        user.py
        dir.py
Run Code Online (Sandbox Code Playgroud)

因此,如果目录名为"classes",那么你会这样做:

from classes.user import User
from classes.dir import Dir
Run Code Online (Sandbox Code Playgroud)

Python 3

与上一个相同,但在模块名称前加上.if不使用子目录:

from .user import User
from .dir import Dir
Run Code Online (Sandbox Code Playgroud)

  • 因为这就是Python识别允许导入的目录的方式.您正在运行的脚本目录是一个例外 - 您始终可以从中导入. (26认同)
  • 为什么需要一个`__init __.py`文件?如果我将所有三个文件放在同一个目录中并运行`main.py`,它就可以从其他两个模块中"导入",没有它.我错过了什么? (21认同)
  • 我认为这个解决方案不适用于Python 3 (16认同)
  • @nbro和Amber:FWIW,我认为关于`__init __.py`的一些微妙变化,并且能够在同一目录中导入其他模块.特别是```````````````````````````````````````````````````````````````````````' 要解决这个问题,我必须在每个子目录的名称和一个点前面加上前缀(即`import module`必须更改为`import subdirectory.module`).幸运的是,在执行此操作后,它仍然在Python 2.7.8中工作. (15认同)
  • 如果`__init __.py`是*not*empty,那么`__init __.py`中的任何内容都是导入包时可用的内容(未导入到__init __.py`的内容根本不可用) . (11认同)
  • @martineau完全正确,它是一种更加面向对象的导入模块的方式. (3认同)
  • 我可以确认这个解决方案不再有效.您可能希望更正,修改或彻底删除它. (3认同)
  • 啊,是的,我解决了。用途:从 . 如果您的模块没有类,请导入文件加载器 (3认同)
  • 抱歉 Amber,我在我拥有的 2 个子目录(gui/ 和 logic/)中放置了一个空的 `__init__.py` 文件,但我仍然遇到导入问题 `ImportError: No module named 'player'` ,这个 `player.py ` 在`logic/` 里面,还有`__init__.py`,正如我告诉你的。可能是什么问题呢? (2认同)
  • @nbo:由于其他模块与`__init __.py`位于同一目录中并且它曾经在没有前缀的情况下工作,我认为它是一个bug ...也许是Python 2之间发生的其他事情的意外后果.x到3.x关于模块和包的输入. (2认同)
  • 我也看不到这在 Python 3 中工作了。我认为这是因为我的模块只包含函数,没有类。 (2认同)
  • python 3.9.2 没有“.” 必需的。例如“from dog import Dog”,其中 Dog 类驻留在dog.py 中 (2认同)
  • 也许是时候将 Python 3 的东西移到顶部了? (2认同)

ecp*_*ecp 122

刚学会了(感谢martineau的评论),为了从同一目录中的文件导入类,你现在可以用Python 3编写:

from .user import User
from .dir import Dir
Run Code Online (Sandbox Code Playgroud)

  • 为什么这个问题很难找到明确的答案?我想要做的就是在单独的文件中创建一个类,然后将该类导入到同一目录中的另一个文件中。如果我使用像这个答案这样的相对导入,我也会得到 VlaueError (26认同)
  • 如果我尝试这个没有我得到以下错误`ValueError:在非包中尝试相对导入`但当我从用户导入用户更改为`时错误消失 (3认同)
  • @Korpel:在http://stackoverflow.com/questions/11536764/how-to-fix-attempted-relative-import-in-non-package-even-with-init-py的讨论之后,我逐渐意识到这一点.上面给出的导入是否有效取决于:[1]你的脚本是如何被调用的(如包或不是)[2]其中实际工作路径是你执行它时[3]如何填充运行环境的路径变量 (3认同)

luc*_*rot 39

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

import user
Run Code Online (Sandbox Code Playgroud)

但是,如果从不包含user.py.
在这种情况下,请使用

from . import user
Run Code Online (Sandbox Code Playgroud)

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

  • 我在 vs code 中使用 pylint,并且遇到了同一目录导入总是被标记为错误的问题(“导入用户”用红色下划线表示);更改为相对导入(“from .import user”),并且 linter 不再标记它。 (3认同)

use*_*312 36

在你的main.py:

from user import Class
Run Code Online (Sandbox Code Playgroud)

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

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

Class.method

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

  • 如果您尝试导入的模块没有类,您会怎么做?只是原始函数?在 python 2 中,我所要做的就是“导入模块”。在 python 3 中不起作用,“import .module”也不起作用 (3认同)
  • 在删除`__init __。py`之后,它可以在python3中工作。 (2认同)

And*_*eas 13

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

from .user import User
from .dir import Dir
Run Code Online (Sandbox Code Playgroud)

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

from . import user
from . import dir
Run Code Online (Sandbox Code Playgroud)


小智 12

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

import util # imports util.py

util.clean()
util.setup(4)
Run Code Online (Sandbox Code Playgroud)

或者您可以将函数和类导入到代码中

from util import clean, setup
clean()
setup(4)
Run Code Online (Sandbox Code Playgroud)

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

from util import *
clean()
setup(4)
Run Code Online (Sandbox Code Playgroud)


min*_*lyu 10

对于 Python 3+,假设您有以下结构:

A/
  __init__.py
  bar.py
  foo.py
Run Code Online (Sandbox Code Playgroud)

在您的__init__.py文件中,您可以放置from . import foo

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

# A/bar.py
from foo import YourClass
Run Code Online (Sandbox Code Playgroud)

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


小智 9

为了使它更容易理解:

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

$ cd /var/tmp
Run Code Online (Sandbox Code Playgroud)

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

$ cat > class1.py <<\EOF
class Class1:
    OKBLUE = '\033[94m'
    ENDC = '\033[0m'
    OK = OKBLUE + "[Class1 OK]: " + ENDC
EOF
Run Code Online (Sandbox Code Playgroud)

第3步:现在让我们创建一个class2.py文件,它的类名为Class2,带有一些代码

$ cat > class2.py <<\EOF
class Class2:
    OKBLUE = '\033[94m'
    ENDC = '\033[0m'
    OK = OKBLUE + "[Class2 OK]: " + ENDC
EOF
Run Code Online (Sandbox Code Playgroud)

第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
Run Code Online (Sandbox Code Playgroud)

第5步:运行程序

$ python main.py
Run Code Online (Sandbox Code Playgroud)

输出将是

[Class1 OK]: 
[Class2 OK]:
Run Code Online (Sandbox Code Playgroud)

  • 如果这不起作用并且main.py无法读取class1或class2会发生什么?...我们缺少什么? (4认同)

dem*_*mas 5

from user import User 
from dir import Dir 
Run Code Online (Sandbox Code Playgroud)

  • @imsrgadich 只要您在包含文件的目录中运行 python,它就可以工作。这是一个例外。见[此评论](/sf/ask/289950601/#comment27915014_4142178) (2认同)

Yas*_*ana 5

Python 3


一样directory

导入文件:log.py

导入类:SampleApp()

import log
if __name__ == "__main__":
    app = log.SampleApp()
    app.mainloop()
Run Code Online (Sandbox Code Playgroud)

要么

目录是basic

导入文件:log.py

导入类:SampleApp()

from basic import log
if __name__ == "__main__":
    app = log.SampleApp()
    app.mainloop()
Run Code Online (Sandbox Code Playgroud)