声明:在人工智能技术教学期间,不少学生向我提一些python相关的问题,所以为了让同学们掌握更多扩展知识更好地理解AI技术,我让助理负责分享这套python系列教程,希望能帮到大家!由于这套python教程不是由我所写(有时候有空也会参与编写),所以不如我的AI技术教学风趣幽默,学起来比较枯燥;但它的知识点还是讲到位的了,也值得阅读!想要学习AI技术的同学可以点击跳转到我的教学网站。PS:看不懂本篇文章的同学请先看前面的文章,循序渐进每天学一点就不会觉得难了!

为什么要使用包导入技术?

有同学不理解包导入存在的意义,觉得它是多此一举~~

其实,万事万物都有其存在的意义,有一句哲理名言叫做——存在即合理。

现在你觉得包导入是多此一举,是因为你还没有相应的经验。就像我年轻时觉得避孕套是多此一举一样,只能说当时too young too simple(太年轻太简单了)。当我有了相应的生活经验后,反而觉得这个世界很多东西都可以没有,但是不能没有套套。如果没有套套,当你某天加完班想出去放飞一下自我后,可能就染上了病;如果没有套套,你可能就会因为一个不小心而想起那个经典的广告“不是我不小心,只是真情难以抗拒,某某某医院,无痛人流,留住你的产权”。

好了,回到正题,总之,包导入就像套套一样,在某些时候必须得用!下面我会使用实例来帮助大家深入滴理解它。

我先给大家一个问题,看你在不使用包导入技术的前提下该如何解决它。

假设你们公司要开发一个大的系统,它里面包含了3个子系统。第一个子系统中包含了一个文件utilities.py,它包含了一些通用的工具代码。这个子系统的代码文件放在一个名为system1的文件夹里。

system1\
    utilities.py       # Common utility functions,classes
    main.py            # Launch this to start the program
    other.py           # Import utilities to load my tools

第二个子系统里面也有名为utilities.py的文件,它们在名为system2的文件夹里。

system2\
    utilities.py     # Common utilities
    main.py          # Launch this to run
    other.py         # Imports utilities

上面只是铺垫,下面问题来了!

如何才能在第三个子系统中既调用第一个子系统的utilities.py代码又调用第二个子系统的utilities.py代码?

你的第一反应想到的应该是去设置模块搜索路径,引入包含utilities.py文件的目录。但是,要在路径内先放哪个目录呢:system1还是system2?

搜索路径本质上是线性的。搜索总是从左至右扫描,所以不管这个问题你想多久,也只能得到搜索路径上最左侧(最先列出)的目录内的utilities.py。也就是说,永远无法导入另一个目录的utilities.py文件。

上面的问题正是包所能够解决的。不应该像上面那样在目录内把文件安装成单纯的文件列表,而是应该将它们进行打包,也就是多加个__init__.py文件(看不懂的同学可以回归一下我前面的文章《Python系列教程231——init.py》)。例如,上面那个包含3个子系统的大系统的文件结构就可以组织成下面的样子。

root\

    system1\

        __init__.py

        utilities.py

        main.py

        other.py

    system2\

        __init__.py

        utilities.py

        main.py

        other.py

    system3\                # Here or elsewhere

        __init__.py         # Your new code here

        myfile.py

代码文件被组织成包后,我们就可以在第三个子系统中通过下面的包导入技术来同时调用第一和第二个子系统中的utilities.py代码。如下所示。

import system1.utilities
import system2.utilities

system1.utilities.function('spam')
system2.utilities.function('eggs')

注意!!上面使用了import来导入,所以每次调用工具模块utilities的代码时,都会重复其完整的目录路径。这样一来,一级一级目录的名称让模块的调用变得具有唯一性。

记住!!如果需要读取两个或两个以上路径内的同名属性时,才需要使用import,在这种情况下不能用from(看不懂的同学回顾一下《Python系列教程233——包导入时使用import还是from》)。如果被调用的函数名称在每个路径内都不同,from语句就可以避免每次都重复完整路径的麻烦!

这篇文章的信息量有点大,有些同学可能要回顾一下我前面的文章才能看懂。简而言之就一句话,存在即合理,包导入技术就像套套一样,必须要有!它可以避免导入时的模糊性。