如何导入其他Python文件?


796

如何在Python中导入其他文件?

  1. 我到底该如何导入特定的python文件import file.py呢?
  2. 如何导入文件夹而不是特定文件?
  3. 我想根据用户输入在运行时动态加载Python文件。
  4. 我想知道如何从文件中仅加载一个特定部分。

例如,在main.py我有:

from extra import * 

尽管这给了我中的所有定义extra.py,但也许我只想要一个定义:

def gap():
    print
    print

我要从import语句中添加什么?gapextra.py


Answers:


441

importlib已添加到Python 3中,以编程方式导入模块。它只是一个包装__import__,请参阅文档

import importlib

moduleName = input('Enter module name:')
importlib.import_module(moduleName)

注意:.py扩展名应从中删除moduleName。该函数还package为相对导入定义了一个参数。


更新:以下答案已过时。使用上面的最新替代方法。

  1. 只是import file没有'.py'扩展名。

  2. 您可以通过添加一个名为的空文件来将文件夹标记为包__init__.py

  3. 您可以使用该__import__功能。它以模块名称作为字符串。(同样:模块名称不带“ .py”扩展名。)

    pmName = input('Enter module name:')
    pm = __import__(pmName)
    print(dir(pm))
    

    输入help(__import__)以获取更多详细信息。


7
如果将init添加import filenameinit .py,则可以直接将模块作为文件夹名称导入。
CornSmith 2013年

9
来自help(__import__)Because this function is meant for use by the Python interpreter and not for general use it is better to use importlib.import_module() to programmatically import a module.
塔德格·麦克唐纳·詹森

6
如果它不是包而是脚本文件,该怎么办?
乔纳森

3
对于在同一路径中导入脚本文件(也许它也适用于Python搜索路径中的脚本文件),import filenamenoext对于我来说,使用Python 3.4.8很好。
亚历克斯·霍尔

7
它在2019年仍然准确吗?是python3还是2?
桑德堡

1030

导入python文件的方法有很多,各有利弊。

不要只是匆忙地选择适合您的第一个导入策略,否则您将不得不在以后发现无法满足您的需要时重写代码库。

我将首先说明最简单的示例#1,然后将介绍最专业,最可靠的示例#7

示例1,使用python解释器导入python模块:

  1. 将其放在/home/el/foo/fox.py中:

    def what_does_the_fox_say():
      print("vixens cry")
  2. 进入python解释器:

    el@apollo:/home/el/foo$ python
    Python 2.7.3 (default, Sep 26 2013, 20:03:06) 
    >>> import fox
    >>> fox.what_does_the_fox_say()
    vixens cry
    >>> 

    您通过python解释器导入了fox,并what_does_the_fox_say()从fox.py中调用了python函数。

示例2,在脚本中使用execfile或(exec在Python 3中)在适当的位置执行另一个python文件:

  1. 将其放在/home/el/foo2/mylib.py中:

    def moobar():
      print("hi")
  2. 将其放在/home/el/foo2/main.py中:

    execfile("/home/el/foo2/mylib.py")
    moobar()
  3. 运行文件:

    el@apollo:/home/el/foo$ python main.py
    hi

    功能moobar是从mylib.py导入的,并在main.py中可用

示例3,从...使用...导入...功能:

  1. 将其放在/home/el/foo3/chekov.py中:

    def question():
      print "where are the nuclear wessels?"
  2. 将其放在/home/el/foo3/main.py中:

    from chekov import question
    question()
  3. 像这样运行它:

    el@apollo:/home/el/foo3$ python main.py 
    where are the nuclear wessels?

    如果您在chekov.py中定义了其他函数,除非您定义了这些函数,否则它们将不可用。 import *

示例4,如果导入的riaa.py与导入的文件位于不同的文件位置

  1. 将其放在/home/el/foo4/stuff/riaa.py中:

    def watchout():
      print "computers are transforming into a noose and a yoke for humans"
  2. 将其放在/home/el/foo4/main.py中:

    import sys 
    import os
    sys.path.append(os.path.abspath("/home/el/foo4/stuff"))
    from riaa import *
    watchout()
  3. 运行:

    el@apollo:/home/el/foo4$ python main.py 
    computers are transforming into a noose and a yoke for humans

    那会从另一个目录导入外部文件中的所有内容。

示例5,使用 os.system("python yourfile.py")

import os
os.system("python yourfile.py")

示例6,通过piggy带python startuphook导入文件:

更新:此示例曾经同时适用于python2和3,但现在仅适用于python2。python3摆脱了此用户启动钩子功能集,因为它被低技能的python库编写者滥用,使用它在所有用户定义的程序之前不礼貌地将其代码注入到全局名称空间中。如果您希望此功能适用于python3,则必须变得更有创意。如果我告诉您如何做,python开发人员也会禁用该功能集,因此您是一个人。

参见:https : //docs.python.org/2/library/user.html

将此代码放入您的主目录中 ~/.pythonrc.py

class secretclass:
    def secretmessage(cls, myarg):
        return myarg + " is if.. up in the sky, the sky"
    secretmessage = classmethod( secretmessage )

    def skycake(cls):
        return "cookie and sky pie people can't go up and "
    skycake = classmethod( skycake )

将此代码放入您的main.py(可以在任何地方):

import user
msg = "The only way skycake tates good" 
msg = user.secretclass.secretmessage(msg)
msg += user.secretclass.skycake()
print(msg + " have the sky pie! SKYCAKE!")

运行它,您应该获得以下信息:

$ python main.py
The only way skycake tates good is if.. up in the sky, 
the skycookie and sky pie people can't go up and  have the sky pie! 
SKYCAKE!

如果您在这里遇到错误:ModuleNotFoundError: No module named 'user'这意味着您正在使用python3,默认情况下会禁用启动钩。

值得一提的是:https : //github.com/docwhat/homedir-examples/blob/master/python-commandline/.pythonrc.py随便 发送。

示例7,最健壮:使用裸导入命令在python中导入文件:

  1. 建立一个新目录 /home/el/foo5/
  2. 建立一个新目录 /home/el/foo5/herp
  3. 制作一个以__init__.pyherp 命名的空文件:

    el@apollo:/home/el/foo5/herp$ touch __init__.py
    el@apollo:/home/el/foo5/herp$ ls
    __init__.py
  4. 新建一个目录/ home / el / foo5 / herp / derp

  5. 在derp下,制作另一个__init__.py文件:

    el@apollo:/home/el/foo5/herp/derp$ touch __init__.py
    el@apollo:/home/el/foo5/herp/derp$ ls
    __init__.py
  6. 在/ home / el / foo5 / herp / derp下,创建一个名为yolo.pyPut this 的新文件:

    def skycake():
      print "SkyCake evolves to stay just beyond the cognitive reach of " +
      "the bulk of men. SKYCAKE!!"
  7. 关键时刻,创建新文件/home/el/foo5/main.py,并将其放入其中;

    from herp.derp.yolo import skycake
    skycake()
  8. 运行:

    el@apollo:/home/el/foo5$ python main.py
    SkyCake evolves to stay just beyond the cognitive reach of the bulk 
    of men. SKYCAKE!!

    __init__.py文件会通知python解释器开发人员打算将此目录作为可导入包。

如果您想查看我的帖子,如何在目录下包含所有.py文件,请参见此处:https : //stackoverflow.com/a/20753073/445131


6
您还应该添加示例6:使用__import__(py_file_name)。无论如何还是
很棒的

4
每次遇到导入问题时,我都会遇到这个问题,并且总是能够解决我的问题。如果每次您帮助我都可以投票赞成,我会的。
dgBP '16

4
所有这些之间的最大区别是什么,为什么一个要比其他任何一个更好?例如,您编写了“使用裸导入命令在python中导入文件”的示例5,但是在示例1,示例3和示例4中也使用了(裸?)导入命令,不是吗?
HelloGoodbye

33
很好的答案,但是您始终使用不同的导入文件作为示例的事实使阅读变得很麻烦。
gentl

2
我想强调一点,即使您在Windows上工作,导入也区分大小写。因此,您不能拥有Module.py,也不能拥有代码导入模块
radato

66

要在“运行时”以已知名称导入特定的Python文件:

import os
import sys

...

scriptpath = "../Test/"

# Add the directory containing your module to the Python path (wants absolute paths)
sys.path.append(os.path.abspath(scriptpath))

# Do the import
import MyModule

我的朋友今天检查了一下,很幸运-看起来文件名不应该存在。他在父目录中使用本地文件,最后使用“ ./”作为父目录(..)。帖子中的修复问题被拒绝-可能引起误会(?),如果不确定,则打印sys.path并比较记录...
汤姆(Tom)

29

您没有很多复杂的方法可以将python文件从一个文件夹导入到另一个文件夹。只需创建一个__init__.py文件,以声明此文件夹为python软件包,然后转到要导入的主机文件即可,只需键入

from root.parent.folder.file import variable, class, whatever


14
如果我想要相对路径怎么办?
domih

21

导入文档..-链接以供参考

__init__.py需要这些文件才能使Python将目录视为包含软件包的目录,这样做是为了防止具有通用名称(例如字符串)的目录无意间隐藏了稍后在模块搜索路径中出现的有效模块。

__init__.py可以只是一个空文件,但也可以执行包的初始化代码或设置__all__变量。

mydir/spam/__init__.py
mydir/spam/module.py
import spam.module
or
from spam import module

19

第一种情况:您要在file A.py中导入文件B.py,这两个文件位于同一文件夹中,如下所示:

. 
├── A.py 
└── B.py

您可以在file中执行此操作B.py

import A

要么

from A import *

要么

from A import THINGS_YOU_WANT_TO_IMPORT_IN_A

然后,您将可以使用文件A.py中文件的所有功能B.py


第二种情况:您要在file folder/A.py中导入文件B.py,这两个文件不在同一文件夹中,如下所示:

.
├── B.py
└── folder
     └── A.py

您可以在文件B中执行此操作:

import folder.A

要么

from folder.A import *

要么

from folder.A import THINGS_YOU_WANT_TO_IMPORT_IN_A

然后,您将可以使用文件A.py中文件的所有功能B.py


摘要:在第一种情况下,file A.py是您在file中导入的模块,B.py使用了语法import module_name。在第二种情况下,使用的语法folder是包含模块的软件包。A.pyimport package_name.module_name

有关软件包和模块的更多信息,请参考此链接


我尝试了一些变化,然后成功了。from folder_a.script import *Script.py在文件夹a下。
贾斯汀

+1这就是我想要的。无法理解其他答案,但您使用目录进行了解释。
Black Thunder

如果要导入父目录中的py文件怎么办?
bytedev

1
@bytedev将import sys和添加sys.path.append("..")到文件的开头。据此:stackoverflow.com/a/48341902/6057480 。经过测试,完美运行,完成此操作后,您将能够在父目录中导入py文件,并且仍然能够在同一目录和子目录中导入py文件。
李伯浩

17
from file import function_name  ######## Importing specific function
function_name()                 ######## Calling function

import file              ######## Importing whole package
file.function1_name()    ######## Calling function
file.function2_name()    ######## Calling function

这是到目前为止我已经了解的两种简单方法,请确保要导入为库的“ file.py”文件仅存在于当前目录中。


9

如果定义的函数在文件中x.py

def greet():
    print('Hello! How are you?')

在要导入函数的文件中,编写以下代码:

from x import greet

如果您不希望将所有功能导入文件中,这将很有用。


7

导入.py文件的最佳方法是通过__init__.py。最简单的操作是__init__.py在your.py文件所在的目录中创建一个名为空文件。

Mike Grouchy的这篇文章很好地解释了__init__.py它在制作,导入和设置python包中的用途。


1
@GhostCat我已更新我的回复。感谢您的链接“这将是可取的”。
至高

并且了解并非每个人都生活在您所在的时区。
GhostCat

4
您应该已经发布了Mike Grouchy帖子的内容,尤其是因为链接现在是404s。web.archive.org/web/20190309045451/https://mikegrouchy.com/blog/…–
qwr

6

我的导入方式是导入文件并使用其名称的缩写。

import DoStuff.py as DS
DS.main()

不要忘记您的导入文件必须以.py扩展名命名


3
会不会import DoStuff.py as DS尝试导入pyDoStuff

5

我想在其他地方加一个不太清楚的注释。在模块/软件包内部,从文件加载时,模块/软件包名称必须带有前缀mymodule。想象一下mymodule这样的布局:

/main.py
/mymodule
    /__init__.py
    /somefile.py
    /otherstuff.py

从内容中加载somefile.py/ 时应如下所示:otherstuff.py__init__.py

from mymodule.somefile import somefunc
from mymodule.otherstuff import otherfunc

2

如果要导入的模块不在子目录中,请尝试以下操作并app.py从最深的公共父目录中运行:

目录结构:

/path/to/common_dir/module/file.py
/path/to/common_dir/application/app.py
/path/to/common_dir/application/subpath/config.json

在中app.py,将客户端路径附加到sys.path:

import os, sys, inspect

sys.path.append(os.getcwd())
from module.file import MyClass
instance = MyClass()

可选(如果您加载例如configs)(对于我的用例,检查似乎是最可靠的一种)

# Get dirname from inspect module
filename = inspect.getframeinfo(inspect.currentframe()).filename
dirname = os.path.dirname(os.path.abspath(filename))
MY_CONFIG = os.path.join(dirname, "subpath/config.json")

user@host:/path/to/common_dir$ python3 application/app.py

此解决方案在cli和PyCharm中都对我有效。


2

有几种方法可以包含名称为abc.py的python脚本

  1. 例如,如果您的文件名为abc.py(导入abc),则限制是文件应位于与您的调用python脚本相同的位置。

导入abc

  1. 例如,如果您的python文件位于Windows文件夹中。Windows文件夹位于您调用Python脚本的位置。

从文件夹导入abc

  1. 如果abc.py脚本在文件夹中存在的Insider Internal_folder内部可用

从folder.internal_folder导入abc

  1. 如上文James所述,如果您的文件位于某个固定位置

import os
import sys
scriptpath =“ ../Test/MyModule.py”
sys.path.append(os.path.abspath(scriptpath))
import MyModule

如果您的python脚本已更新并且不想上传,请使用这些语句进行自动刷新。奖金:)

%load_ext autoreload 
%autoreload 2

1

只是为了将python文件导入另一个python文件

可以说我有一个具有显示功能的helper.py python文件,

def display():
    print("I'm working sundar gsv")

现在在app.py中,您可以使用显示功能,

import helper
helper.display()

输出,

I'm working sundar gsv

注意:无需指定.py扩展名。


1

这听起来很疯狂,但是如果您只是要为其创建包装脚本,则可以仅创建指向要导入文件的符号链接。


1

您也可以这样做: from filename import something

示例:from client import Client 请注意,您不需要.py .pyw .pyui扩展名。


1

这就是我从python文件中调用函数的方式,这对我来说可以灵活地调用任何函数。

import os, importlib, sys

def callfunc(myfile, myfunc, *args):
    pathname, filename = os.path.split(myfile)
    sys.path.append(os.path.abspath(pathname))
    modname = os.path.splitext(filename)[0]
    mymod = importlib.import_module(modname)
    result = getattr(mymod, myfunc)(*args)
    return result

result = callfunc("pathto/myfile.py", "myfunc", arg1, arg2)

与直接使用功能相比,如何使新功能更好?
qwr

@qwr新函数callfunc()只是代码的包装,可以动态调用python文件中的目标函数。给出的示例是python文件“ pathto / myfile.py”中的目标“ myfunc”。“直接使用功能”是什么意思?
萧锋锂

为我完美地工作。在我的示例中,我将替换from mypath import PathPath = callfunc("/folder/to/mypath.py", "Path")。感谢@ Xiao-FengLi
user319436 '19

@ user319436很高兴我的回答终于可以帮助某人。:)
晓丰利

谢谢@ xiao-feng-li !! 好答案!
Altieres de Matos

0

如上所述,有很多方法,但是我发现我只想导入他文件的内容,而不想要写行和输入其他模块。因此,我想出了一种方法来获取文件的内容,即使使用点语法(file.property)也是如此,而不是将导入的文件与您的文件合并。
首先,这是我要导入的文件,data.py

    testString= "A string literal to import and test with"


注意:您可以改用.txt扩展名。
在中mainfile.py,首先打开并获取内容。

    #!usr/bin/env python3
    Data=open('data.txt','r+').read()

现在,您已将内容作为字符串保存,但是尝试访问data.testString将导致错误,就像该类data的实例一样str,即使它确实具有属性testString,也无法实现您期望的效果。
接下来,创建一个类。例如(双关语意图),ImportedFile

    class ImportedFile:

并放入其中(带有适当的缩进):

    exec(data)


最后,data像这样重新分配:

    data=ImportedFile()

就是这样!就像访问其他模块一样进行访问,print(data.testString)将在控制台上输入内容A string literal to import and test with
但是,如果您from mod import *只想删除类,实例分配并取消缩进,则等效于exec

希望这会
有所帮助:)-Benji


您认真地认为,当人们发布了所有其他解决方案时,将文件内容作为字符串读取然后执行它是一个很好的解决方案?
qwr

@qwr Erm是的,我知道。许多其他答案在某些情况下不起作用。这就是为什么我需要一种可以保证正常工作的简单方法。如果您无法从他人的角度看事物,则需要尝试使用官方的IDLE。
Benj

0

Python的一个非常未知的功能是能够导入zip文件:

library.zip
|-library
|--__init__.py

__init__.py软件包的文件包含以下内容:

def dummy():
    print 'Testing things out...'

我们可以编写另一个脚本,该脚本可以从zip存档中导入包。仅需要将zip文件添加到sys.path。

import sys
sys.path.append(r'library.zip')

import library

def run():
    library.dummy()

run()

压缩文件有什么好处?
qwr
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.