函数虽然提供了一种复用代码的能力,但是前面所介绍的各种函数使用方法都只能在一个代码文件中进行,如何实现更为灵活的复用效果呢?比如就像print和input函数那样,无需在当前代码中书写函数的定义即可使用。
这就需要使用模块和包进行封装。
我们先看看模块。所谓模块,其实就是把函数单独放在一个独立的py文件中。我们现在一直编写代码的所在就是一个称为“Exec.py”的文件。我们不妨在PyCharm中再新建一个Python文件,将新文件名称设置为“myFuncs.py”。
此时,当前项目共有两个Python文件。
并在这个新的文件 myFuncs.py 中定义两个函数:
def squares(x):
return x ** 2
def convert(func, seq):
return [func(eachNum) for eachNum in seq]
就是这个样子:
保存后,我们还是回到Exec.py中,看看能不能使用到那两个函数。
print(squares(2))
你会发现系统显示找不到squares:
修改代码为:
import myFuncs
print(myFuncs.squares(2))
print(myFuncs.convert(myFuncs.squares, [2, 3, 4]))
此时你会发现可以运行了,输出为:
4
[4, 9, 16]
这里所使用的方法就是模块的定义和导入功能。
所谓模块,就是一个一个独立的Python文件,我们可以把自己准备分发给其他人的函数写在其中,也可以得到别人分享给我们的模块文件。
将模块文件放在和当前项目代码所在文件同一个目录中,然后在需要调用模块函数的代码文件中标注导入哪个模块。正如刚才的例子展示,导入使用import语句,后面的模块名称就是模块文件的主名(不要py扩展名),请注意,这些文件名称大小写要保持一致。在使用时,所有函数的前面也需要加上所在的模块名称就可以正常使用。
当然,每次调用函数都要加个模块前缀,也会觉得这些有点繁琐,因此可以考虑换种导入方式:
from myFuncs import squares
from myFuncs import convert
print(squares(2))
print(convert(squares, [2, 3, 4]))
输出内容同上。这里的导入语句可以这样理解,从myFuncs模块导入squares函数,很明确也很具体。此时就可以无需模块前缀来直接使用函数名称了。
如果想导入更多的函数,还可以使用星号来表示:
from myFuncs import *
print(squares(2))
print(convert(squares, [2, 3, 4]))
输出内容同上,此时表示myFuncs模块中的所有函数都可以正常使用。
不过,有时我们会遇到一个问题,那就是导入的函数名称可能与我们当前代码中的函数或者变量名称一样而发生冲突,此时,当前代码同名函数或者变量会优先被调用,从而掩盖住了对导入函数的调用能力。为此,我们可以考虑将导入的函数起个别名:
from myFuncs import squares as sq
def squares(x):
return x ** 2.0
print(squares(2))
print(sq(2))
输出为:
4.0
4
显然,squares将优先调用本地的同名函数,而导入的函数通过别名sq而区分了开来。这里的别名就是在导入语句的最后加上as和别名即可。
通过导入其他的模块,几乎可以无限扩展我们现有代码的能力,显然这非常有价值,也便于代码开发,不同的开发者负责不同的模块,只要大家按照商议好的接口规范,最终就可以通过模块导入来组织起来完整的项目。
为什么print和input不需要导入?并非所有的函数都需要导入,对于一些非常常见的基本函数,Python都放在sys模块中,而这个模块会自动被导入,因此我们无需显式导入也能使用。Python自带了大约200个包与模块。
模块虽然可以将不同的函数封装在一起,但是依然只是一个文件。有时代码多了以后,可能我们需要很多不同的模块文件,此时就可以进一步再按照包将不同模块组织起来。
为此,我们可以在PyCharm新建一个包(Python Package),将这个包的名称设置为“myPackage”:
你会发现此时项目中多个一个子目录,名称就是“myPackage”,里面还有个默认的“__init__.py”文件。因此,所谓包,其实就是一个文件夹,里面可以放很多模块文件。
可以使用拖拽或者剪切粘贴的方式将当前项目的myFuncs模块文件(myFuncs.py)移动过去。
此时会有提示信息,点击“OK”确定即可。
模块有了所在的包,相应的导入方法改变为:
from myPackage.myFuncs import squares
print(squares(2))
输出为:4。此时只需在模块前加上包的名称,中间通过点来分隔。
在PyCharm中,这些都有自动代码提示帮助用户完成相应的输入和代码补齐。
当然,如果采用的还是以前的import方式,则仍然需要在函数前写上完整的包和模块名称:
import myPackage.myFuncs
print(myPackage.myFuncs.squares(2))
输出内容同上。
库的含义更广,我们可以把许多相关的包和模块的整体称之为库。事实上,我们通过专门的方法将现有的包、模块打包成一个可以独立分发的文件,供其他用户下载加载使用,这样可以更好的实现代码封装和共享使用。
比如Python大数据分析将会利用到来自于各个开发者所贡献的、功能各异的库。
Python大数据分析_南京财经大学_中国大学MOOC(慕课) (icourse163.org)https://www.icourse163.org/course/NJUE-1458311167Python提供了很多内置函数,都在内置的包和模块中,同时第三方库还提供了更多的函数,这些函数基本上实现了各种常见基本操作。因此,要想有效的利用Python和简化自己的代码,我们就需要了解这些包、模块和其中的函数。
最为权威的方式,是直接访问Python官方在线文档库:
3.10.2 Documentationhttps://docs.python.org
其中我们可以更改语言为中文和选择对应的Python版本。
点击右上角的“模块”,并选择“math”模块,即可看到详细的各种数学函数功能:
如果不能联网,安装了Python的本地电脑也有帮助文档。比如在Windows系统中,直接在开始菜单中搜索“Python”,就能看到Python手册(Manuals):
其中也可以直接进一步检索所需的函数说明,如在本地Python文档中搜索“math”库函数信息:
即使不能使用这些帮助,我们也可以通过代码的方式来按需获取。比如我们想了解math模块的有哪些函数,可以使用dir函数:
import math
print(dir(math))
输出为:
['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc']
这些就是math数学模块中常见的各种函数。
再如我们想了解某个具体函数的意思,可以使用help函数:
import math
print(help(math.sin))
系统会详细显示该函数的含义:
配套学习资源、慕课视频: