机器学习-python语言基础第七天

七、包与模块管理
为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式。在Python中,一个.py文件就称之为一个模块(Module)。
使用模块或包的优势:

  • 代码的可重用性:最大的好处是大大提高了代码的可维护性。其次,编写代码不必从零开始。当一个模块编写完毕,就可以被其他地方引用。我们在编写程序的时候,也经常引用其他模块,包括Python内置的模块和来自第三方的模块。
  • 命名空间(防止重名):使用模块还可以避免函数名和变量名冲突。相同名字的函数和变量完全可以分别存在不同的模块中,因此,我们自己在编写模块时,不必考虑名字会与其他模块冲突。但是也要注意,尽量不要与内置函数名字冲突。
  • 实现数据的共享

模块或包的使用语法,通过有两种语法,一种为import,另一种为from…import…,使用这两种的语法的后台运行过程都是一致的:

  1. 找到模块文件
  2. 将模块文件编译为字节码,生成pyc文件,在程序所在目录的__pycache__下。
  3. 运行模块文件

如下面的模块运行,文内的模块如下图:
此处为创建的目录
models模块内的代码如下:

#models模块
data = 10
def test():
    print('models.text')

test()

14_main模块内的代码,注意py中的变量只能以字母或下划线开头,py3中首次可以以中文作为变量,但并不能以数字开头,当其他模块导入14_main模块时,将其名称作为变量将提示错误信息,这里只是做测试,并不会导入14_main这个模块。

#14_main代码
from models import test
#输出
models.text

但此时主程序只能使用test()函数,变量data并不能使用,因为没有导入data变量。from…import…的原理是,在运行模块的命名空间内,建立一个同名变量test,指向models模块中的test,这样他们就指向同一个函数地址,当调用test时,执行结果一样,如果后期把test在主程序重新赋值,这时他就断开了到model模块的引用,因此就不会再调用test了。
在这里插入图片描述
当把主程序的代码改成如下内容:

#14_main
import models
#输出
models.text

此时,models模块中的函数和变量都可以调用,但要使用模块名.变量的方式调用。原理如下图,主程序中通过models变量指向models模块,通过models的.来调用模块内容。
在这里插入图片描述
在每个模块都有一个特殊的变量__name__,当当前模块时正在执行的脚本程序,__name__的值是’main’,当模块作为模块导入时,这个变量的值是模块名的字符串。当把模块导入后,可以通过sys.modules来获取,返回的内容是一个字典,‘main’:当前模块的目录,’models’:models模块的目录。因此可以将只从代码加入一个判断:if __name__ =='__main__'当前模块正在执行时,才会运行判断语句内部的代码,否则语句不执行。

import sys
getattr(sys.modules[__name__],变量名)

可以通过上述的程序,做到简洁的模块内变量或函数调用,getattr时一个映射函数。
另外还可以通过from…import*,来将所有的变量都导入,这时的原理与from…import时一样的,在运行的脚本中,建立所有与对应模块对应的变量名。可以在模块中使用__all__=[‘变量名’,‘函数名’…]来限制*的导入。

__all__ = ['test']

可以使用from…import…as将导入的函数或变量设置一个别名,当有多个要导入的变量或函数时,可以写成如下代码:

from models import test as func,data as ddd

因为文件第一次导入后,会生成pyc文件,当程序在运行的过程中,修改导入的模块时,程序并不会更新,因此为此时就是使用的pyc文件,pyc并没有更新,这时可以使用import.reload()来重新加载模块。
import时,python也有自己的搜索路径,通常是:

  1. 程序主目录
  2. 环境变量
  3. 标准库
  4. 扩展库

可以通过sys.path,获取搜索路径。如果不在搜索路径下,可以通过sys.path.append(),来增加目录,这样就能导入了。
在模块的导入中 不要产生循环引用问题
如果发生循环导入,就会发现命名写在这个模块中的方法,却偏显示找不到。(注:模块导入只能发生一次)
在这里插入图片描述
如上图所示,当test导入models模块是,程序加载models模块的内容,但当程序加载第一句话时,又回到了加载test,这样导致models模块没有运行。因此不能发生循环导入。
包的导入:
包的导入分绝对导入和相对导入,先说下绝对导入和相对导入的优缺点,绝对导入当模块做脚本自己运行时,时可以运行的,但当包被移动目录的话,很容易出现导入出错的现象。而相对导入,写着from.import的文件不能直接执行,只能被其他模块导入执行,但当移动目录时,相对导入的适应能力更好。如下目录
在这里插入图片描述
可以直接在主程序中使用如下代码导入:

#1
import glacne.api.policy
#2
from glance.api import policy
#3
from glance.api.policy import get

policy中的代码入下:

def get():
    print('from policy.py')

第一种方法,再使用变量或者函数时,要把前缀都写全 glacne.api.policy.变量,第二种方法,可以直接使用policy.变量,第三种方法,可以直接使用get,同时可以使用as将get重命名。
注:不管用哪种方法,在导入时,都会按照顺序执行__init__.py文件,首先执行glance的init文件,其次时api的init文件,最后才是policy文件的代码。
另一个中导入的话,可以在每个init中加入一个导入,如在glance的init文件加入如下代码:

from glance import api

在api的init文件中增加:

from glance.api import policy

这样在导入import glance时,就可以直接使用policy模块的函数了,但此时,也要把前缀写完整。因为导入时要根据当前执行模块的路径sys.path来判断能否导入,但导入后只属于相应模块的作用域,因此要加前缀。
相对导入时,只需要将from后面的改成“.”,一般.表示当前目录,两个点表示上级目录,两级目录都改写成…就可以,程序会自动适应。

八、面向对象
面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。
面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行。为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度。
而面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。
面向对象设计一般分为:

  1. OOA面向对象分析
  2. OOD面向对象设计
  3. OOP面向对象编程

具体操作为:

  1. 分析对象特征
  2. 写类描述对象模板
  3. 实例化,模拟过程。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值