# 一般的 Python 工程目录结构

image-20211210180853081

image-20211210181004740

这个参考👉 Python 工程目录结构,目录之间自定义包模块文件的引用

对于这种模块依赖我做了以下实验:

# 测试结构:

image-20211210171407310

my_test 作为主模块, 里面有 sub01 和 sub02 两个子模块,其中 sub01 还有 sub01_sub01 这个子模块。

对于这些 sub*fc.py 的 python 文件,全部内容都是:

def sub*():
    print(__name__)

所有的 __init__.py 文件都初始为: print(__package__)

# 同级导入

# test.py
import my_test

image-20211210170355194

import my_test.my_testfc as my_test
my_test.my_test()

image-20211210170620645

# 导入子模块

import my_test.sub01

image-20211210170825934

# 导入两层子模块

import my_test.sub01.sub01_sub01

image-20211210170940022

ok,证明我们的导入方法没有太大问题。

# 存在的问题

import my_test
my_test.my_testfc.my_test()

发现报错了。。。

image-20211210171911791

# 解决办法:
import my_test.my_testfc as my_test
my_test.my_test()

image-20211210172030179

可以看到,这样就可以使用 my_testfc.py 这个文件了。

也就是说,如果想用啥文件要一级一级导入,这太麻烦了。

# 一次性导入

我觉得导入这个过程还是太麻烦了,想要一次性 my_test 下的所有包。

设置 my_test 下的一级__init__.py

print(__package__)
from . import my_testfc

那么我们导入时候,就可以直接

import my_test
my_test.my_testfc.my_test()

image-20211210172551526

看来没有任何问题。。。

同样我们还可以用__init__.py 的 __all__属性。

print(__package__)
__all__=['my_testfc']

这样就可以直接导入了。

from my_test import *
my_testfc.my_test()

image-20211210172856055

ok,我现在想要导入子模块,一样地方式设置__init__.py 。

/my_test/__init__.py

print(__package__)
from . import sub01
from . import sub02
from . import my_testfc
__all__=['my_testfc', 'sub01', 'sub02']

/my_test/sub01/__init__.py

print(__package__)
from . import sub01fc
from . import sub01_sub01
__all__ = ['sub01fc','sub01_sub01']

/my_test/sub01/sub01_sub01/__init__.py

print(__package__)
from . import sub01_sub01fc
__all__=['sub01_sub01fc']

/my_test/sub02/__init__.py

print(__package__)
from . import sub02fc
__all__=['sub02fc']

这里有个神奇的操作:

init.py 的神奇用法 - 酸痛鱼的文章 - 知乎 https://zhuanlan.zhihu.com/p/115350758

/my_test/__init__.py

print(__package__)
from . import sub01
from . import sub02
from . import my_testfc
__all__=['my_testfc', 'sub01', 'sub02']
sub01fc = sub01.sub01fc.sub01()

test.py

from my_test import *
sub01fc()

image-20211210174839844

通过命名可以使得函数直接使用。

# 不同文件夹下导入

image-20211210175259919

现在我想要 sub01 的 sub01.fc 用上 sub02 的 sub02fc.py 文件

/my_test/sub01/sub01fc.py

def sub01():
    print(__name__)
from .. import sub02
def sub01_sub02():
    sub02.sub02fc.sub02()
    print(__name__)

test.py

from my_test import *
sub01.sub01fc.sub01_sub02()

image-20211210175503555

看来没有问题

# sub02 引用 sub01 下的 sub01_sub01:

/my_test/sub02/sub02fc.py

def sub02():
    print(__name__)
    
from .. import sub01
def sub02_sub01_sub01():
    sub01.sub01_sub01.sub01_sub01fc.sub01_sub01()
    print(__name__)

test.py

from my_test import *
sub02.sub02fc.sub02_sub01_sub01()

image-20211210180441518

可以看到成功打印了 sub01_sub01fc

# 总结

模板的工作路径 os.getcwd() 就是当前执行文件的工作路径,所以当确定好了模块后,就不要 run 了。

这个模块有点搞,如果不注意,会有很多很多错误问题,这个绝对路径和相对路径还有一堆有待解决的问题,先这样了。