python跨文件调用函数

  • 文件组织形式
  • 场景1--同文件夹下调用(涉及两个文件)
  • 场景2--同文件加下调用(涉及三个文件)
  • 场景3--不同文件夹下调用(涉及两个文件)
  • 场景4--不同文件夹下调用(涉及三个文件)


文件组织形式

函数调用测试
	|---a.py
	|---b.py
	|---main.py
	test
		|---c.py
		|---d.py

图片展示如下:

python怎么从同级文件夹中导入一个文件 python跨文件夹导入_python


每个文件内容如下:

a.py

def a_hello():
    print("a_hello")

b.py

from a import a_hello

def b_hello():
    print("从b中调用a_hello")
    a_hello()

c.py

def c_hello():
    print("c_hello")

d.py

from c import c_hello

def d_hello():
    print("从d调用c_hello")
    c_hello()

场景1–同文件夹下调用(涉及两个文件)

现在main.py文件夹需要调用a.py中的a_hello函数时,直接在程序开头写引用即可:

from a import a_hello

main.py中代码:

from a import a_hello

a_hello()

程序运行结果:

python怎么从同级文件夹中导入一个文件 python跨文件夹导入_程序运行_02

场景2–同文件加下调用(涉及三个文件)

在上述代码中可以看到,b.py文件调用了a.py中的a_hello函数,此时,如果main.py文件想要调用b.py文件中的b_hello函数时,就产生了一个函数调用链:main.py->b.py->a.py
这种情况下,仍然是直接在程序开头写引用即可:

from b import b_hello

main.py中代码:

from b import b_hello

b_hello()

程序运行结果:

python怎么从同级文件夹中导入一个文件 python跨文件夹导入_程序运行_03

场景3–不同文件夹下调用(涉及两个文件)

现在想要从main.py中调用c.py中的c_hello函数,由于c.py在test文件夹中,比较符合正常想法的方法是在程序开头添加上:

from test.c import c_hello

但是这样会报错,程序找不到test.c

python怎么从同级文件夹中导入一个文件 python跨文件夹导入_函数调用_04


此时,需要在test文件夹中新建一个__init__.py文件,用于标识test是一个模块。init.py文件中一般不需要写入内容。

python怎么从同级文件夹中导入一个文件 python跨文件夹导入_python_05


此时,程序即可正常运行

main.py中代码:

from test.c import c_hello

c_hello()

程序运行结果:

python怎么从同级文件夹中导入一个文件 python跨文件夹导入_python_06

场景4–不同文件夹下调用(涉及三个文件)

现在需要在main.py文件中调用d.py中的d_hello函数,此时,又形成了一个函数调用链:main.py->d.py->c.py,并且还是跨文件的函数调用链。如果直接写 from test.d import d_hello ,程序会报错,找不到c模块。这种情况下,即使添加了__init__.py文件也没有用。

python怎么从同级文件夹中导入一个文件 python跨文件夹导入_函数调用_07


该怎么办呢?

这种情况下,需要我们指定python文件的系统路径:

import sys
sys.path.insert(0,"./test")

将test文件夹添加到sys.path中,这样,python程序在执行的过程中,就知道test文件夹的位置,程序可以正常运行。
这种方法虽然可以解决问题,但是在实践中极为脆弱,应尽量避免使用。问题是在于将目录名硬编码到了源代码中。如果代码被移到一个新的位置,会导致维护问题。
更加高明的方法是通过模块精心构造一个绝对路径,方法如下:

import sys
from os.path import abspath, join, dirname
sys.path.insert(0, join(abspath(dirname(__file__)), 'test'))

首先通过os.path.dirname(file)获取当前文件的绝对路径,接着在后面追加当前目录下的test文件夹,接着使用abspath获取test文件夹的绝对路径,最后将路径添加到sys.path中的最前面。

maini.py中代码:

import sys
from os.path import abspath, join, dirname
sys.path.insert(0, join(abspath(dirname(__file__)), 'test'))

from test.d import d_hello
d_hello()

程序运行结果:

python怎么从同级文件夹中导入一个文件 python跨文件夹导入_程序运行_08


值得注意的是,添加sys.path操作需要在调用d中的d_hello之前,首先要添加路径,程序才能够找到相应的文件。