热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python自学之《21天学通Python》(5)

第8章复杂程序组织当一个应用程序简单时,将程序代码写入一个文件即可。但随着应用程序或项目复杂度增加时,如果将所有代码都写入同一个文件中时,


第8章 复杂程序组织



当一个应用程序简单时,将程序代码写入一个文件即可。但随着应用程序或项目复杂度增加时,如果将所有代码都写入同一个文件中时,会出现文件过长或过大,即不方便代码浏览,也不方便代码的管理、使用与维护。此时,很自然地会将同一个应用程序或项目内容按照功能或其他标准,分别放入不同的文件。不同的代码文件就是不同的模块,换句话说,每个“.py”文件都是一个模块。


以模块方式组织代码能够方便地管理和维护代码,如果项目的复杂度进一步增加,则模块可能也不能胜任了。于是,将项目中不同功能的代码放入不同的文件夹中,它们可以相互引用,这就是包。模块和包都是复杂程序组织的一种方式,一般来说,复杂度较低的使用模块来管理即可,而复杂度较高的还要用到包来管理代码。

8.1 模块
Python中的模块实际上就是包含函数或者类的Python程序,对于一个大型的程序经常将功能细化,将实现不同功能的代码放在不同的程序中实现,在其他的程序中以模块的形式使用细化的功能,这样便于程序的维护和重用。

8.1.1 模块概述


模块是包含函数和其他语句的Python脚本文件,它以“.py”为后缀名,也就是Python程序的后缀名。用作模块的Python程序与其他的程序并没有什么区别。使用模块中的代码,也很简单,那就是通过导入模块,然后使用模块中提供的函数或者数据。在Python中可以使用以下三种方法导入模块或者模块中的函数。


import 模块名 import 模块名as新名字 from 模块名import函数名


其中使用import是将整个模块导入,而使用from则是将模块中某一个函数或者名字导入,而不是整个模块。


(1) 使用import和from导入模块还有一个不同:使用import的导入模块,要使用模块中的函数则必须以模块名加“.”,然后是函数名的形式调用函数;


(2) 而使用from导入模块中的某个函数,则可以直接使用函数名调用,不用在前面加上模块名称。此外,使用from导入时,函数名处可以只用一个“*”来表示导入该模块中所有代码。但要注意导入的模块中不要与此文件中的代码重复。


(3) 使用“import模块名as新名字”用来在导入模块时给模块重新命一个名字,可能是因为防止名称重复,也可能是为了重新命一个简洁的名字,方便书写。导入一个模块时,会创建新的命名空间,就可以使用命名空间来调用其中的代码;同时,还会在新创建的命名空间中执行模块中包含的代码,如果有输出也可以在控制台看到。


在这里插入图片描述
在这里插入图片描述
8.1.2 自己编写模块
自己编写模块其实和平常写Python程序是相同的,它既可以是一个解决某个问题的独立程序,也可以是几个函数构成。而模块的名称就是代码保存的文件名。




在这里插入图片描述


在这里插入图片描述

8.1.3 模块位置


编写好的模块只有被Python找到才能被导入。上一节中编写的模块和调用模块的程序位于同一个目录中,因此不需要进行设置就能被Python找到并导入。如果在该目录中新建一个module目录,并且把module_test.py转移到module目录中。再次在Windows的命令窗口中运行a8_2.py,会引发ImportError错误,即找不到要导入的模块。


ImportError错误表示:Python解释器没有找到module_test模块。在导入模块时,Python解释器首先在当前目录中查找要导入的模。如果未找到模块,Python解释器会从sys模块中的path变量指定的目录查找导入模块。如果在以上所有目录中未找到导入的模块,则会引发ImportError错误。

一般来说,Python解释器在运行程序前将当前目录添加到sys.path路径列表中,所以导入模块时首先查找的路径是当前目录下的模块。在Windows系统下,其他的默认模块查找路径为Python的安装目录及几个子目录,如lib、lib\site-packages、dlls等。在linux下默认模块查找路径为/usr/lib、/usr/lib64及其它们的几个几子目录下。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述



注意 添加模块查找路径时使用绝对路径。



8.1.4
pycache__目录
在上一节的例子中,运行完usemodule.py会发现moudle目录中除了mymodule.py文件以外还多了一个目录__pycache
,目录下有一个module_test.cpython-34.pyc文件。其中module_test.cpython-34.pyc就是

Python将module_test.4.py编译成字节码的文件。虽然Python是脚本语言,但Python可以将程序编译成字节码的形式。对于模块,Python总是在第一次调用后将其编译成字节码的形式,以提高程序的启动速度。

Python在导入模块时会查找模块的字节码文件,如果存在则将编译版后的模块的修改时间同模块的修改时间相比较。如果两者的修改时间不相符,那么Python将重新编译模块,以保证两者内容相符。被编译的程序也是可以直接运行的。当然,没有必要去刻意编译Python程序。不过,由于Python是脚本,如果不想将源文件发布,可以将发布编译后的程序,这样可以起到一定的保护源文件的作用。


在这里插入图片描述


在这里插入图片描述

8.1.5 具有独立运行能力的模块


每个Python程序在运行时都有一个__name__属性(name前后均是两条下画线)。在程序中通过对__name__属性值的判断,可以让程序在作为导入模块和独立运行时都可以正确运行。


在Python中,如果程序作为模块被导入,则其__name__属性被设置为模块名。如果程序独立运行,则其__name__属性被设置为"__main__"。因此可以通过__name__属性来判断程序的运行状态。

如对实例8-2代码进行修改,它既可以独立运行,又可以作为模块被其他程序导入使用,修改后代码如下:


在这里插入图片描述

8.2 包

Python中的模块实际上就是包含函数或者类的Python程序。对于一个大型的程序经常要将功能细化,把实现不同功能的代码放在不同的程序中实现,在其他的程序中以模块的形式使用细化的功能,这样便于程序的维护和重用。

8.2.1 包概述

当应用程序或项目具有较多的功能模块时,如果把它们都放在同一个文件夹下,就显得不合理了。这时,可以使用Python中提供的包来管理较多的功能模块。使用包的好处在于可以有效避免名字冲突,便于包的维护管理。


包其实就是一个文件夹或目录,但其中必须包含一个名为“__init__.py”(init的前后均是两条下画线)的文件。“__init__.py”可以是一个空文件,仅用于表示该目录是一个包。此外,包还可以嵌套,即把子包放在某个包中。包可以看作处于同一目录中的模块。在Python中首先使用目录名,然后再使用模块名导入所需要的模块。要导入子包必须依照包顺序(目录顺序)以点分隔使用import进行导入。

例如,对于一个web项目可能的包组织结构如下:


在这里插入图片描述

8.2.2 包详解

上一节中所述的包目录中所属的__init__.py文件是一个空文件,只不过是作为包的一个标志。实际上在第一次导入包中的任何部分,就会执行“__init__.py”文件中的代码,其中的变量和函数等也会自动导入。
“__init__.py”文件中也可以包含可执行包的初始化工作的代码和设置“__all__”变量。对于在from中使用“*”通配符导入包内所有名字时,在“__init__.py”中设置“__all__”变量可以保证名字的正确导入。


在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


在这里插入图片描述

8.3 Python常用标准库简介


Python语言中内置的标准库包含200左右的包和模块,提供了广泛的功能,涵盖数据处理、压缩和散列、数据持久化、数据库操作、文件及文件系统处理、日志系统、网络通信、Internet协议、数据编码与转换、多进程与多线程等库和模块。除此以外,Python还有大量的第三方库可以使用。本节简单介绍几个常用的标准库,还有一些标准库将会在本书后面章节加以详细介绍。


8.3.1 数学类模块
此类常用的标准库有math、random。


math中有大量的常见数学计算函数,比如三角函数(sin(),cos(),tan())、反三角函数(asin(),acos(),atn())、对数函数(log(),log10(),log2()),还包括数学中的常量,如e、pi(圆周率)。 random中包含了常见的随机数生成函数,如random、randint,还包括一些按概率生成随机数的函数如gauss等。此外还有像shuffle(乱序列表)、choice()(从序列中随机取元素)等随机函数。

在交互式环境下使用random模块示例代码如下:


>>> import random
>>> random.random()
0.9358315255495109
>>> random.randint(0,10)
0
>>> random.randint(0,10)
4
>>> random.choice((1,2,3,4))
1
>>> alst=[1,2,3,4,5,6]
>>> random.shuffle(alst)
>>> alst
[3, 5, 2, 6, 4, 1]
>>>


8.3.2 日期与时间类
在这里插入图片描述



>>> import datetime
>>> datetime.datetime.now()
datetime.datetime(2022, 12, 20, 19, 38, 14, 366602)
>>> import time
>>> time.time()
1671536307.426266
>>> t1 = datetime.datetime(2015, 3, 7, 23, 14, 56, 139627)
>>> t1
datetime.datetime(2015, 3, 7, 23, 14, 56, 139627)
>>> t2 = datatime.datatime.now()
Traceback (most recent call last):
File "", line 1, in <module>
NameError: name &#39;datatime&#39; is not defined
>>> t2 &#61; datetime.datetime.now()
>>> t2
datetime.datetime(2022, 12, 20, 19, 47, 37, 930659)
>>> sub &#61; t2-t1
>>> sub.seconds
73961
>>> t2.year,t2.month,t2.day,t2.hour,t2.minute,t2.second
(2022, 12, 20, 19, 47, 37)
>>>


8.4 小结
本章主要介绍了Python语言中组织复杂程序或代码的基本方法。对于功能单元不多&#xff0c;而且功能单元中的代码少的小型应用&#xff0c;使用模块就可以管理好代码了。而对于功能单元多的中型应用程序或项目&#xff0c;应该用包和模块来组织代码。通过本章学习你应掌握用包和模块来组织代码的方法&#xff0c;并了解如何探查包或模块的结构。
8.5 本章习题
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述








推荐阅读
  • 开发笔记:python协程的理解
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了python协程的理解相关的知识,希望对你有一定的参考价值。一、介绍什么是并发?并发的本质就是 ... [详细]
  • 第七课主要内容:多进程多线程FIFO,LIFO,优先队列线程局部变量进程与线程的选择线程池异步IO概念及twisted案例股票数据抓取 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 代理模式的详细介绍及应用场景
    代理模式是一种在软件开发中常用的设计模式,通过在客户端和目标对象之间增加一层中间层,让代理对象代替目标对象进行访问,从而简化系统的复杂性。代理模式可以根据不同的使用目的分为远程代理、虚拟代理、Copy-on-Write代理、保护代理、防火墙代理、智能引用代理和Cache代理等几种。本文将详细介绍代理模式的原理和应用场景。 ... [详细]
  • 深入解析Linux下的I/O多路转接epoll技术
    本文深入解析了Linux下的I/O多路转接epoll技术,介绍了select和poll函数的问题,以及epoll函数的设计和优点。同时讲解了epoll函数的使用方法,包括epoll_create和epoll_ctl两个系统调用。 ... [详细]
  • 深入理解Java虚拟机的并发编程与性能优化
    本文主要介绍了Java内存模型与线程的相关概念,探讨了并发编程在服务端应用中的重要性。同时,介绍了Java语言和虚拟机提供的工具,帮助开发人员处理并发方面的问题,提高程序的并发能力和性能优化。文章指出,充分利用计算机处理器的能力和协调线程之间的并发操作是提高服务端程序性能的关键。 ... [详细]
  • 本文介绍了NetCore WebAPI开发的探索过程,包括新建项目、运行接口获取数据、跨平台部署等。同时还提供了客户端访问代码示例,包括Post函数、服务器post地址、api参数等。详细讲解了部署模式选择、框架依赖和独立部署的区别,以及在Windows和Linux平台上的部署方法。 ... [详细]
  • linux进阶50——无锁CAS
    1.概念比较并交换(compareandswap,CAS),是原⼦操作的⼀种,可⽤于在多线程编程中实现不被打断的数据交换操作࿰ ... [详细]
  • 1Lock与ReadWriteLock1.1LockpublicinterfaceLock{voidlock();voidlockInterruptibl ... [详细]
  • Mono为何能跨平台
    概念JIT编译(JITcompilation),运行时需要代码时,将Microsoft中间语言(MSIL)转换为机器码的编译。CLR(CommonLa ... [详细]
  • 开发笔记:Python之路第一篇:初识Python
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Python之路第一篇:初识Python相关的知识,希望对你有一定的参考价值。Python简介& ... [详细]
  • Java编程思想一书中第21章并发中关于线程间协作的一节中有个关于汽车打蜡与抛光的小例子(原书的704页)。这个例子主要展示的是两个线程如何通过wait ... [详细]
  • Python语言简介、环境搭建、PyCharm的安装和配置
    一、Python语言简介1.1Python语言的基本概念官方对Python语言的介绍如下:Python是一款易于学习且功能强大的编程语言。它具有高效率的数据结构,能够简单又有效地实 ... [详细]
  • Webmin远程命令执行漏洞复现及防护方法
    本文介绍了Webmin远程命令执行漏洞CVE-2019-15107的漏洞详情和复现方法,同时提供了防护方法。漏洞存在于Webmin的找回密码页面中,攻击者无需权限即可注入命令并执行任意系统命令。文章还提供了相关参考链接和搭建靶场的步骤。此外,还指出了参考链接中的数据包不准确的问题,并解释了漏洞触发的条件。最后,给出了防护方法以避免受到该漏洞的攻击。 ... [详细]
  • 我们需要用到一个python强大的库:python-dox直接pipinstallpython-docx在项目中加个赤壁赋.docx的空文件附上完整的python代码fromdoc ... [详细]
author-avatar
cut1089289
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有