Python中的文件导入?

6

我该怎样在执行期间导入Python文件?

我创建了3个文件a.pyb.pyc.py,它们位于路径C:\Users\qksr\Desktop\Samples中。

这些文件包含以下代码:

a.py

from c import MyGlobals

def func2():
    print MyGlobals.x
    MyGlobals.x = 2

b.py

import a
from c import MyGlobals

def func1():
    MyGlobals.x = 1      

if __name__ == "__main__":
    print MyGlobals.x
    func1()
    print MyGlobals.x
    a.func2()
    print MyGlobals.x

c.py

class MyGlobals(object):
    x = 0

当我执行b.py代码时,出现了以下错误:
ImportError: No module named a

我相信我的工作目录是默认的,所有的文件a、b、c都是我在samples文件夹中创建的。

在Python中如何导入Python文件?


如果所有文件的路径都相同,那就没问题。 - sharafjaffri
在ImportError发生之前,你能否打印出sys.path的内容? - User
当我打印sys.path时,我得到的是:['C:\Users\qksr\Desktop\Samples','C:\Python27\Lib\idlelib','C:\Windows\system32\python27.zip','C:\Python27\DLLs','C:\Python27\lib','C:\Python27\lib\plat-win','C:\Python27\lib\lib-tk','C:\Python27','C:\Python27\lib\site-packages','C:\Python27\lib\site-packages\win32','C:\Python27\lib\site-packages\win32\lib','C:\Python27\lib\site-packages\Pythonwin','C:\Users\qksr\Desktop']。 - Kaushik
@User 我们可以看到路径被添加了,但我仍然面临着那个特定的问题。 - Kaushik
如果你打开一个命令窗口,使用cd命令切换到该目录,然后启动python.exe并在提示符中键入import a,会发生什么? - Janne Karila
6个回答

7
调整 PYTHONPATH 通常不是一个很好的想法。更好的方法是通过添加名为 __init__.py 的文件使当前目录表现得像一个模块,该文件可以为空。然后,Python解释器允许您从该目录导入文件。

6

有很多方法可以导入Python文件:

不要匆忙选择第一个适合您的导入策略,否则当您发现它不能满足您的需求时,您将不得不重写代码库。

我首先解释最简单的控制台示例#1,然后向最专业和最强大的程序示例#5移动

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

  1. Put this in /home/el/foo/fox.py:

    def what_does_the_fox_say():
      print "vixens cry"
    
  2. Get into the python interpreter:

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

    You invoked the python function what_does_the_fox_say() from within the file fox through the python interpreter.

选项2:在脚本中使用execfile执行另一个Python文件:

  1. Put this in /home/el/foo2/mylib.py:

    def moobar():
      print "hi"
    
  2. Put this in /home/el/foo2/main.py:

    execfile("/home/el/foo2/mylib.py")
    moobar()
    
  3. run the file:

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

    The function moobar was imported from mylib.py and made available in main.py

选项3,使用from ... import ...功能:

  1. Put this in /home/el/foo3/chekov.py:

    def question():
      print "where are the nuclear wessels?"
    
  2. Put this in /home/el/foo3/main.py:

    from chekov import question
    question()
    
  3. Run it like this:

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

    If you defined other functions in chekov.py, they would not be available unless you import *

选项4,如果riaa.py位于导入位置的不同文件位置,则导入它

  1. Put this in /home/el/foo4/bittorrent/riaa.py:

    def watchout_for_riaa_mpaa():
      print "there are honeypot kesha songs on bittorrent that log IP " +
      "addresses of seeders and leechers. Then comcast records strikes against " +
      "that user and thus, the free internet was transmogified into " +
      "a pay-per-view cable-tv enslavement device back in the 20th century."
    
  2. Put this in /home/el/foo4/main.py:

    import sys 
    import os
    sys.path.append(os.path.abspath("/home/el/foo4/bittorrent"))
    from riaa import *
    
    watchout_for_riaa_mpaa()
    
  3. Run it:

    el@apollo:/home/el/foo4$ python main.py 
    there are honeypot kesha songs on bittorrent...
    

    That imports everything in the foreign file from a different directory.

选项5,使用裸导入命令在Python中导入文件:
  1. Make a new directory /home/el/foo5/
  2. Make a new directory /home/el/foo5/herp
  3. Make an empty file named __init__.py under herp:

    el@apollo:/home/el/foo5/herp$ touch __init__.py
    el@apollo:/home/el/foo5/herp$ ls
    __init__.py
    
  4. Make a new directory /home/el/foo5/herp/derp

  5. Under derp, make another __init__.py file:

    el@apollo:/home/el/foo5/herp/derp$ touch __init__.py
    el@apollo:/home/el/foo5/herp/derp$ ls
    __init__.py
    
  6. Under /home/el/foo5/herp/derp make a new file called yolo.py Put this in there:

    def skycake():
      print "SkyCake evolves to stay just beyond the cognitive reach of " +
      "the bulk of men. SKYCAKE!!"
    
  7. The moment of truth, Make the new file /home/el/foo5/main.py, put this in there;

    from herp.derp.yolo import skycake
    skycake()
    
  8. Run it:

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

    The empty __init__.py file communicates to the python interpreter that the developer intends this directory to be an importable package.

如果您想查看如何在目录下包含所有.py文件的文章,请单击此处:https://dev59.com/jHNA5IYBdhLWcg3wL6yx#20753073 额外的技巧是,无论您使用Mac、Linux还是Windows,都需要使用Python的IDLE编辑器,如此描述。它将解锁您的Python世界。http://www.youtube.com/watch?v=DkW5CSZ_VII

6
如果你正在同一个目录中工作,也就是说,b.pya.py在相同的文件夹中,我无法重现此问题(也不知道为什么会出现此问题),但如果您发帖说明b.pyos.getcwd()返回什么将会很有帮助。
如果不是这种情况,请在b.py的顶部添加以下内容。
import sys
sys.path.append('PATH TO a.py')

如果它们位于相同的路径中,

import sys
sys.path.append(os.basename(sys.argv[0])) # It should be there anyway but still..

@Schoolboy C:\Users\qksr\Desktop\Samples 这是我运行 os.getcwd() 后得到的结果。 - Kaushik
就像我之前所说的,我无法在我的系统(Windows 7)上重现这个问题。我做了同样的事情(在桌面上创建一个名为“Samples”的文件夹,并将3个文件放在那里),但是什么都没有出现。(除了0 1 1 2):) 尝试我建议的解决方案。此外,在使用Python时,需要使用模块(除非你有充分的理由不这样做)。 - pradyunsg

1

参考:我想知道如何导入在默认路径之外的任何路径中创建的文件?

import sys

sys.path.append(directory_path) # a.py should be located here

如果所有文件都在同一个文件夹中,则无需添加任何路径,它应该可以正常工作。 - sharafjaffri
@sharafjaffri 所有文件都在同一个文件夹中。该文件夹位于桌面上。 - Kaushik
@User 我尝试了你说的同样的方法,但仍然抛出相同的错误。 - Kaushik
@karthik 我正在使用Linux Mint,已经创建了这三个文件,Python的b.py可以正常工作。 - sharafjaffri
@karthik 对于 Windows 可能会有问题。你可以在 b.py 文件的顶部添加这一行:sys.path.append(os.path.dirname(__file__)) - sharafjaffri
显示剩余2条评论

0

默认情况下,Python不会从当前工作目录导入模块。有两种(或更多)解决方案:

PYTHONPATH=. python my_file.py

这告诉Python在 . 中查找要导入的模块,或者:

sys.path.append(os.path.dirname(__file__))

它在运行时修改导入路径,添加“当前”文件的目录。


1
是的,glglgl是正确的,请参见这里 - pradyunsg
啊,看来你说得对,抱歉,我的经验是受到影响的。我经常会从比模块更高的目录中调用脚本,这会影响到“包含用于调用Python解释器的脚本的目录”。 - akaIDIOT

0

第一种选择:将您的文件路径添加到Python默认查找路径中。

import sys
sys.path.insert(0, 'C:/complete/path/to/my/directory')

第二个选项:将路径添加到您当前环境(当前目录)的根目录相对路径中,使用以下内容代替:

#Learn your current root 
import os
os.getcwd()  

#Change your current root (optional)
os.chdir('C:/new/root')

#Add the path from your current root '.' to your directory
import sys
sys.path.insert(0, './Path/from/current/root/to/my/directory')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接