基于股票大数据分析的Python入门实战(视频教学版)
上QQ阅读APP看书,第一时间看更新

3.4 通过import复用已有的功能

Python语言是面向对象的程序设计语言,所以提供了以“模块”(Module)、“包”(Package)和“库”等不同形式的程序复用功能。在编程时若需要实现某项功能,可以优先考虑通过import语句导入已有的比较成熟的功能模块,而不是从头开始开发。注:Python语言也被称为“胶水”语言,有很多开源模块都可以通过import(导入或引入)到程序项目中来加快项目的实现,这些模块一般称为包或程序包,也被称为库。本书大部分地方都统一称这些模块或包为“库”。在本书的行文中,在单独说明库名时,库名的第一个英文字母都大写,而在范例程序中用import导入库时,还要遵照库的原始名字中的英文字母大小写,否则无法正确导入。

3.4.1 通过import导入现有的模块

Python的模块是一个扩展名为py的Python文件,在模块中可以封装方法、类和变量。Python中的模块分为三种:自定义模块、内置标准模块和第三方提供的开源模块。

通用性的方法、类和属性往往会被封装到模块中,这样就能达到“一次编写多次调用”的效果,而无需在每个调用类中重复编写。在下面的ModuleDemo.py范例程序中演示了定义模块的常规方法。

1    # !/usr/bin/env python
2    # coding=utf-8
3    def displayModuleName():
4        print("CalModule")
5    def add(x,y):
6        return x+y
7    def minus(x,y):
8        return x-y
9    PI=3.14 # 封装变量
10    class Stock:
11        def __init__(self, stockCode,price):
12            self.stockCode, self.price=stockCode,price
13        def buy(self):
14            print("Buy " + self.stockCode + " with the price:" + self.price)

在第3行到第8行中定义了多个方法,在第9行中定义了PI这个变量,而在第10行到第14行定义了一个Stock类。在模块中一般放的是“定义”类的代码,而不会放“调用”类的代码。

定义好模块后,就可以在其他Python文件中通过import来导入定义好的现有模块,并使用其中的功能,如下ImportDemo.py范例程序所示。

1    # !/usr/bin/env python
2    # coding=utf-8
3    import ModuleDemo as tool
4    from ModuleDemo import Stock as stockTool
5    
6    print(tool.PI)             # 3.14
7    print(tool.add(1,2))     # 3
8    print(tool.minus(1,2))     # -1
9    tool.displayModuleName()     # CalModule
10    #stockTool.add(1,2)         # 出错
11    myStockTool=stockTool("600001","10")
12    myStockTool.buy() #Buy 600001 with the price:10

在类中导入模块的方式一般有两种:第一种如第3行所示,通过import语句和模块名导入指定的模块,并在as之后给这个模块起个别名;另一种方式是只导入该模块中指定的内容,如第4行所示,通过from模块名import类名(或方法名或属性名)的方式导入指定的内容,在as之后同样可以起个别名。

导入模块或指定内容后,在第6行到第9行中,即可通过tool这个别名访问模块中的属性和方法。由于stockTool这个别名仅仅是指向模块中的Stock类,因此通过它无法调用到add方法,而只能如第11行和第12行所示,调用Stock类中的方法。

3.4.2 包是模块的升级

如果以模块的形式复用代码出现了模块冲突的情况,则无法导入实现功能不同但名字相同的模块,为了解决这个问题,可以用包的形式来复用现有功能。

从表现形式上来看,包是一个目录,其中包含若干个扩展名为.py的模块,而且包里还得包含一个__init__.py的文件,哪怕这个文件是空的也行。这样就可以通过“包名.模块名”的方式来复用模块,从而能避免模块冲突的情况。

下面来实践一下。按照如下步骤来创建一个包,在charter3的项目中,新建一个名为myPackage的目录,随后在其中放入如图3-1所示的文件。

图3-1 包组织结构的示意图

__init__.py文件是每个包所必有的,否则会出错,这里仅是个空文件。范例程序ModuleDemo.py在3.5.1小节已经给出,新加的CalModuleDemo.py模块代码如下:

1    # !/usr/bin/env python
2    # coding=utf-8
3    E=2.718
4    G=9.8
5    def calGravity (m):
6        return m*G

在第3行和第4行定义了两个变量,而在第5行中封装了calGravity方法。这样,在myPackage这个包中放入一个__init__.py类。

随后在charter3项目中新建一个名为UsePackageDemo.py的文件,在其中调用包中的模块,代码如下。

1    # !/usr/bin/env python
2    # coding=utf-8
3    import myPackage.CalModuleDemo as calTool
4    from myPackage import ModuleDemo as myTool
5    print(myTool.PI)                 # 3.14
6    print (calTool.calGravity(10))     # 98.0
7    print (calTool.E)                 # 2.718

请注意第3行和第4行导入包中模块的方式,在第3行是通过“包名.模块名”的方式导入CalModuleDemo这个模块,而在第4行则是通过“from包名import模块名”的方式导入模块。导入后,则可以如第5行到第7行所示,通过“别名.属性”和“别名.方法名”的方式来调用。

3.4.3 导入并使用第三方库NumPy的步骤

Python中的模块(Module)和包(Package)都能被称为“库”,在实际的项目中,很多时候是通过导入第三方库,也就是复用库中封装的诸多功能。为了全书名称的统一,后面提及第三方模块或包的时候,都统一称为库。单独提及库名的时候,库名的第一个英文字母都用大写,在程序代码中用import导入库或程序语句中特指库名称时,则回归库名原始的英文名称大小写习惯。

比如之前用到的列表等功能类即是封装在Python标准库中的,在本书之后的篇幅中还会用到一些开源库。下面将以NumPy这个开源的科学计算库为例,演示一下导入并使用第三方库的具体步骤。

步骤1 由于我们安装的是python3.4.4版本,因此在Scripts目录中能看到pip.exe,如图3-2所示。

图3-2 pip.exe所在的文件夹

请确保在环境变量的Path里,已经设置了pip.exe所在的路径D:\Python34\Scripts。

步骤2 在“命令提示符”窗口中,执行命令pip install -U numpy,其中-U表示以当前用户的身份安装,安装好以后,会告知安装到了哪个路径。

步骤3 依次单击“Window”→“Preferences”菜单,在随后弹出的对话框的左侧,找到PyDev,并在“Interpreter – Python”这个选项中,在System PATHONPATH框内,单击“New Folder”按钮,而后添加NumPy库的安装路径,如图3-3所示,这样在项目中就可以调用NumPy库中的方法或函数了。

图3-3 设置NumPy安装所在的路径

完成上述步骤后,就可以调用NumPy库中的方法了,范例程序NumpyDemo.py中的代码如下。

1    # !/usr/bin/env python
2    # coding=utf-8
3    import numpy as np     # 导入NumPy库,起了个别名np
4    arr=np.array(np.arange(4)) # 创建一个序列
5    print(arr)             # 输出 [0 1 2 3]
6    print(np.eye(2))     # 创建一个维度是2的对角矩阵,输出如下
7    # [[1. 0.]
8    # [0. 1.]]

通过调用NumPy库提供的方法,就能对数组序列和矩阵进行计算。本节的重点不是讲述NumPy库中有哪些方法,而是以这个库为例,介绍如何通过pip命令安装并导入第三方库。在后续章节中,还会用到其他第三方库,也可以照此方法导入。