Python 3


Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。



查看 Python 版本

我们可以在命令提示符/终端中使用以下命令来查看我们使用的 Python 版本:

python -V

以上命令执行结果如下:

Python 3.8.5

在命令提示符/终端中输入python并回车可以进入 Python 的交互式编程模式,在这里也可以查看版本:

Python 3.8.5 (tags/v3.8.5:580fbb0, Jul 20 2020, 15:57:54) [MSC v.1924 64 bit (AMD64)] on win32

Type "help", "copyright", "credits" or "license" for more information.

>>>


第一个 Python3.x 程序

1. 对于大多数程序语言,第一个入门编程代码便是"Hello World!",以下代码为使用 Python 输出"Hello World!":

#!/usr/bin/python3print("Hello, World!")
  • ​#!/usr/bin/python3​​ :指定用什么解释器运行脚本以及解释器所在的位置,如果解释器没有装在/usr/bin/目录,改成其所在目录就行了,或者更通用的方法是:
    #!/usr/bin/env python3​。
  • 在Windows环境下这并不是必要的代码。

2. 你可以将以上代码保存在 ​hello.py​ 文件中并使用 python 命令执行该脚本文件。

python hello.py

3. 以上命令输出结果为:

Hello, World!


 本节对学习python编程没有太多实质性的帮助,但本节介绍了一些python的历史和特性,有兴趣的小伙伴可以了解一下。

Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。

Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有比其他语言更有特色语法结构。

  • Python 是一种解释型语言: 这意味着开发过程中没有了编译这个环节。类似于PHP和Perl语言。
  • Python 是交互式语言: 这意味着,您可以在一个 Python 提示符 >>> 后直接执行代码。
  • Python 是面向对象语言: 这意味着Python支持面向对象的风格或代码封装在对象的编程技术。
  • Python 是初学者的语言:Python 对初级程序员而言,是一种伟大的语言,它支持广泛的应用程序开发,从简单的文字处理到服务器再到游戏,它都可以胜任。

Python 发展历史

Python 是由 Guido van Rossum 在八十年代末和九十年代初,在荷兰国家数学和计算机科学研究所设计出来的。

Python 本身也是由诸多其他语言发展而来的,这包括 ABC、Modula-3、C、C++、Algol-68、SmallTalk、Unix shell 和其他的脚本语言等等。

像 Perl 语言一样,Python 源代码同样遵循 GPL(GNU General Public License)协议。

现在 Python 是由一个核心开发团队在维护,Guido van Rossum 仍然占据着至关重要的作用,指导其进展。

Python 2.0 于 2000 年 10 月 16 日发布,增加了实现完整的垃圾回收,并且支持 Unicode。

Python 3.0 于 2008 年 12 月 3 日发布,此版不完全兼容之前的 Python 源代码。不过,很多新特性后来也被移植到旧的Python 2.6/2.7版本。

Python 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。

Python 2.7 被确定为最后一个 Python 2.x 版本,它除了支持 Python 2.x 语法外,还支持部分 Python 3.1 语法。

Python 特点

  • 1.易于学习:Python有相对较少的关键字,结构简单,和一个明确定义的语法,学习起来更加简单。
  • 2.易于阅读:Python代码定义的更清晰。
  • 3.易于维护:Python的成功在于它的源代码是相当容易维护的。
  • 4.一个广泛的标准库:Python的最大的优势之一是丰富的库,跨平台的,在UNIX,Windows和Macintosh兼容很好。
  • 5.互动模式:互动模式的支持,您可以从终端输入执行代码并获得结果的语言,互动的测试和调试代码片断。
  • 6.可移植:基于其开放源代码的特性,Python已经被移植(也就是使其工作)到许多平台。
  • 7.可扩展:如果你需要一段运行很快的关键代码,或者是想要编写一些不愿开放的算法,你可以使用C或C++完成那部分程序,然后从你的Python程序中调用。
  • 8.数据库:Python提供所有主要的商业数据库的接口。
  • 9.GUI编程:Python支持GUI可以创建和移植到许多系统调用。
  • 10.可嵌入: 你可以将Python嵌入到C/C++程序,让你的程序的用户获得"脚本化"的能力。

Python 应用

  • 网站建设,以下网站应用了python进行web开发:
  • Youtube - 视频社交网站
  • Reddit - 社交分享网站
  • Dropbox - 文件分享服务
  • 豆瓣网 - 图书、唱片、电影等文化产品的资料数据库网站
  • 知乎 - 一个问答网站
  • 果壳 - 一个泛科技主题网站
  • Bottle - Python微Web框架
  • EVE - 网络游戏EVE大量使用Python进行开发
  • Blender - 使用Python作为建模工具与GUI语言的开源3D绘图软件
  • Inkscape - 一个开源的SVG矢量图形编辑器。
  • 机器学习与人工智能 - TensorFlow,Keras,pytorch等机器学习库让python成为最适合机器学习的语言
  • 数据分析与数据挖掘 - 各式各样的python爬虫可以帮助数据分析工程师获取数据,而丰富的python数据处理库可以处理这些数据并以可视化形式或者可调用形式展现出来
  • 科学计算和算法设计 - 曾经matlab作为科学计算的行业标杆,但现在python正在蚕食它的市场。而简单的语法让python更适合进行算法开发(算法工程师可以轻松上手算法开发)
  • IDLE - 作为python安装时自带的IDE,这款IDE就是由 Guido van Rossum 使用python+tkinter写出来的。
  • ···

python的缺点

有优点就会有缺点,python作为一门解释型语言,拥有了解释型语言的优点(跨平台可移植性,动态变量等)也有解释型语言的缺点(效率较低)。另外,python作为一门近乎万能的语言,就像瑞士军刀一样,他拥有很多功能,但在具体的功能上都不如一些专精的语言,当对性能有一定要求的时候,python不是好选择!

本章节将向大家介绍 Python 最新版开发环境的安装步骤及如何进行环境配置,刚入门的新手学员可以跟着本章内容进行学习。

本章节需要用到的Python 最新源码,二进制文档,新闻资讯等可以在 Python 的官网查看:

Python官网

         

    你可以在以下链接中下载 Python 的文档,你可以下载 HTML、PDF 和 PostScript 等格式的文档。

    Python官方文档下载

             



      Python 安装


      • Python 已经被移植在许多平台上(经过改动使它能够工作在不同平台上)。
      • 您需要下载适用于您使用平台的二进制代码,然后安装 Python。
      • 如果您平台的二进制代码是不可用的,你需要使用 C 编译器手动编译源代码。
      • 编译的源代码,功能上有更多的选择性, 为 Python 安装提供了更多的灵活性。

      以下为不同平台上安装 Python 的方法:

      Unix & Linux 平台安装 Python:

      以下为在 Unix & Linux 平台上安装 Python 的简单步骤:

      • 打开 WEB 浏览器访问 https://www.python.org/downloads/source/
      • 选择适用于 Unix/Linux 的源码压缩包。
      • 下载及解压压缩包 Python-3.x.x.tgz3.x.x 为你下载的对应版本号。
      • 如果你需要自定义一些选项修改 Modules/Setup

      以 Python3.8.5 版本为例:

      Python3安装包下载linux/Unix版本

      # tar -zxvf Python-3.8.5.tgz# cd Python-3.8.5# ./configure# make && make install

      检查 Python3 是否正常可用:

      # python3 -VPython 3.8.5
      python作为Linux系统的一个依赖,很多Linux系统都会默认安装python环境(甚至误删python环境会导致系统崩溃),在很长一段时间里,很多Linux系统都默认安装了python2,这时候学习python3就需要安装新版本的python3,而且由于Linux系统依赖的是python2,所以python2版本不能卸载。但随着python2停止维护结束了他的使命,大多数Linux系统已经更新到了python3版本,如果对python3的小版本没有特殊要求的话,最新的Linux系统基本可以做到不需要安装即可使用python环境(小编之前安装的centos 8内置的python版本为3.6.8,已经能基本满足普通的python学习需求了)。

      Windows 平台安装 Python:

      以下为在 Windows 平台上安装 Python 的简单步骤:

      • 打开 WEB 浏览器访问https://www.python.org/downloads/windows/
        Python安装包windows版本下载                  
      • 在下载列表中选择 Windows 平台安装包,包格式为:python-3.8.5-amd64.exe 文件 , -3.8.5 为你要安装的版本号,-amd64为你系统的版本。
      • 下载后,双击下载包,进入 Python 安装向导,安装非常简单,你只需要使用默认的设置一直点击"下一步"直到安装完成即可。

      Windows x86-64 为 64 位版本

      Windows x86 为 32 位版本

      自python3.9起,官方不再支持在win7及以下版本安装和运行python,但我们仍可通过编译源代码的形式来给win7安装更高版本的python。

      MAC 平台安装 Python:

      MAC 系统一般都自带有 Python2.7 版本 的环境,你也可以在链接 https://www.python.org/downloads/mac-osx/ 上下载最新版安装。

      Python安装包官方下载MacOS版本



      环境变量配置

      • 程序和可执行文件可以在许多目录,而这些路径很可能不在操作系统提供可执行文件的搜索路径中。
      • path (路径)存储在环境变量中,这是由操作系统维护的一个命名的字符串。这些变量包含可用的命令行解释器和其他程序的信息。
      • Unix 或 Windows 中路径变量为 PATH(UNIX 区分大小写,Windows 不区分大小写)。
      • 在 Mac OS 中,安装程序过程中改变了 python 的安装路径。如果你需要在其他目录引用 Python,你必须在 path 中添加 Python 目录。

       简单地说,​python​这个指令(还记得上一节介绍的​python -v​嘛,这就是python指令)在系统中是不存在的,安装完python后就有了python这个指令,但我们需要告诉系统,在哪里可以找到python这个指令,而path路径变量,就是起到这样一个作用。

      在 Unix/Linux 设置环境变量

      • 在 csh shell: 输入 
        setenv PATH "$PATH:/51coolma/local/bin/python"
        按下 Enter。
      • 在 bash shell (Linux) 输入 :
        export PATH="$PATH:/51coolma/local/bin/python" 
        按下 Enter 。
      • 在 sh 或者 ksh shell 输入: 
        PATH="$PATH:/51coolma/local/bin/python"
        按下 Enter。

      注意: /51coolma/local/bin/python 是 Python 的安装目录。

      在 Windows 设置环境变量

       注意!在python安装的时候勾选自动添加python到path路径可可以免去配置环境这个过程,本教程介绍的是当在命令提示符中输入python显示指令不存在的情况下需要进行的操作。

      在环境变量中添加 Python 目录:

      在命令提示符中(cmd) : 输入

      path=%path%;C:Python 

      按下"Enter"。

      注意: C:Python 是 Python 的安装目录。

      也可以通过以下方式设置:

      • 右键点击"计算机",然后点击"属性"
      • 然后点击"高级系统设置"
      • 选择"系统变量"窗口下面的"Path",双击即可!
      • 然后在"​Path​"行,添加 python 安装路径即可(我的D:Python32),所以在后面,添加该路径即可。 ps:记住,路径直接用分号"​;​"隔开!
      • 最后设置成功以后,在 cmd 命令行,输入命令"​python​",就可以有相关显示。



      在win10中配置环境变量与win7类似:

      在电脑桌面右键点击此电脑,点击属性选项。

      右击进入计算机属性

      在关于页面中选择高级系统设置,点击环境变量进行环境变量的配置。

      环境变量的设置

      只需在 PATH 变量原有的变量上新增以下变量值即可:

      Python 的安装文件夹。

      python 安装文件夹下的 Scripts 文件夹。

      环境变量

       注意!添加python路径是为了配置python指令,使得python指令可以使用,而配置script文件夹则是为了配置pip指令(一个python包管理工具)。

      另外,在安装python的时候如果有勾选添加环境变量的话(下图 add python 3.9 to path),默认会将环境变量配置完毕。

      python安装界面


      Python 环境变量

      下面几个重要的环境变量,它应用于 Python:

      变量名描述
      PYTHONPATHPYTHONPATH 是 Python 搜索路径,默认我们 import 的模块都会从 PYTHONPATH 里面寻找。
      PYTHONSTARTUPPython 启动后,先寻找 PYTHONSTARTUP 环境变量,然后执行此变量指定的文件中的代码。
      PYTHONCASEOK加入 PYTHONCASEOK 的环境变量, 就会使 python 导入模块的时候不区分大小写.
      PYTHONHOME另一种模块搜索路径。它通常内嵌于的 PYTHONSTARTUP 或 PYTHONPATH 目录中,使得两个模块库更容易切换。

      运行Python

      有三种方式可以运行 Python:

      1. 交互式解释器:

      • 你可以通过命令行窗口进入 Python,并在交互式解释器中开始编写 Python 代码。
      • 你可以在 Unix、DOS 或任何其他提供了命令行或者 shell 的系统进行 Python 编码工作。
      $ python # Unix/Linux

      或者

      C:>python # Windows/DOS

      以下为Python命令行参数:

      选项描述
      -d在解析时显示调试信息
      -O生成优化代码 ( ​.pyo​ 文件 )
      -S启动时不引入查找 Python 路径的位置
      -V输出 Python 版本号
      -X从 1.6 版本之后基于内建的异常(仅仅用于字符串)已过时。
      -c cmd执行 Python 脚本,并将运行结果作为 cmd 字符串。
      file在给定的 python 文件执行 python 脚本。

      2. 命令行脚本

      在你的应用程序中通过引入解释器可以在命令行中执行 Python 脚本,如下所示:

      $ python script.py # Unix/Linux

      或者

      C:>python script.py # Windows/DOS

      注意:在执行脚本时,请检查脚本是否有可执行权限。

      3. 集成开发环境(IDE:Integrated Development Environment): PyCharm


      领取免费资料

      扫描下方二维码或打开微信搜一搜“51coolma编程狮”关注公众号回复关键词【Python123】或者【Python资料包】免费领取 Python 学习资料,包含软件安装包,电子书、思维导图等

      51coolma编程狮微信公众号

      python软件介绍

      python安装完后,在开始菜单会有如下的一个文件夹:

      python安装文件夹

      他们分别是:

      • IDLE:由python之父开发的一个小型的python开发环境,可以用来解释执行python代码,也可以用来写python脚本。
      • Python:这个就是python的解释器,可以用来解释执行python代码,使用命令行调用python命令的时候就是运行的这个程序。
      • Python Manuals:这个是python的使用手册,可以用来学习python的基础使用。
      • Python Module Docs:这个是python的模块文档,可以用来学习模块的使用。

      python代码执行方式

      python代码的执行方式有两种,一种是交互型的解释执行方式,另一种是将python写成脚本代码的形式,然后使用解释器执行,两种执行方式有所不同:

      交互型执行方式

      这种执行方式类似人与人之间的对话,写一句代码执行一句代码。这种类型类似人的交互行为,所以被称为交互执行方式,使用这种交互方式最大的特点是:在命令行界面中有​>>>​作为每行代码的开头。如下图所示:

      python解释器

      接下来本手册中的代码只要是带有>>>的都是在交互型解释器中运行后的结果,没有>>>的代码都是python脚本代码。

      进入交互型解释器的方式有如下几种方式:

      • 命令行方式:按win + r键,输入cmd,点击回车,进入命令行界面,然后输入python,点击回车,即可进入命令行界面,在命令行中输入python并按回车执行,即可进入命令行界面。
      • 运行方式:按win + r键,输入python,点击回车,即可直接进入python解释器页面。
      • 直接运行程序:安装的python中里面有一个选项是python,直接点击这个选项就可以进入python解释器。
      • IDLE:安装的python中里面有一个选项是IDLE,直接点击后进入的也是python解释器。

      IDLE shell界面

      交互型编程在代码调试中比较常见,更好的交互型编程的体验可以了解ipython或者jupyter notebook。

      如何退出?

      在交互型解释器中输入​exit()​按回车即可退出。

      退出

      如何换行&缩进?

      python以换行作为代码结束的标志(也就是说,点击换行立马执行这个代码),但这并不是绝对的,当代码的最后一个标识符是​:​时可以换行(因为出现​:​的时候都是进入代码块的情况,比如条件语句,循环语句,函数等)。

      python以缩进来区分代码块,所以在出现上述的换行情况的时候,需要搭配空格键(注意,不是Tab键!)来进行代码缩进(使用空格数并不强制,但同一代码块之间的缩进应该相同)。处于代码块内时,​>>>​会变成​...​。如下代码所示:

      >>>the_world_is_flat = True>>>if the_world_is_flat:...    print("Be careful not to fall off!")...Be careful not to fall off!

      在代码块需要结束的地方,换行后点击回车即可。

      所以上面的代码的输入方式应该是这样的:输入第一行语句,点击回车,输入第二行语句(注意末尾的冒号),点击回车,输入四个空格,输入第三行语句(该语句是代码块内的语句),回车,回车(结束这个代码块)。最后一行是代码运行结果。

       在交互型解释器中,代码如果会产生输出,会直接打印在控制台,输出和代码的区别是:代码前面有​>>>​。

      脚本代码执行方式

      这种方式是大多数编程语言执行方式(先写代码,然后一次执行),如果把代码解释比喻为做菜的话,交互型解释方式类似于看一个步骤做一个步骤,而脚本代码执行方式则是看完全部步骤后再逐步做。这种方式也是未来我们学习python编程中最常遇到的编程方式。

       不同工具(IDE)的编程方式不同,这里小编放到下一节介绍,这里我们介绍一下IDLE的脚本代码编写方式。

      点击打开IDLE,我们可以进入到python的shell(命令行,也就是交互型解释器)界面,点击File,选择New File。可以新建一个脚本代码文件(也可以使用Ctrl + N 进行新建脚本代码文件)。就会弹出一个窗口,这时候我们就可以在这个窗口里面写python代码了。

       虽然IDLE相对比较简单,但它也提供了代码着色等实用的功能,如果没有什么很好的python代码编辑器,不妨尝试一下它!

      写完代码后可点击run,选择run module(或者直接按F5),就可以运行代码了。


      初次运行需要先保存代码并给代码文件命名,后续代码更改也要重新保存代码。

      另外,IDLE也可以打开以​.py​为后缀的文件,与新建类似,点击File,选择Open...,可以打开本地的python代码文件(py代码文件以​.py​为后缀)。运行方式与新建方式相同。

       这意味着python可以使用其他的代码编辑器进行代码编写,再使用IDLE去运行,但是实际上我们不会这么做,因为执行python代码不一定要用IDLE,使用python命令也可以。这为我们使用vscode这样的代码编辑器去写代码然后使用命令行运行提供了一种可能,而vscode的插件把这样的功能实现了。在后续章节中我们将介绍如何使vscode来写python代码。

      如何使用命令行运行python脚本?

      在命令提示符中使用python命令就可以运行python脚本了,python命令的使用方法如下:

      python 要运行的文件.py

      示例:


      Q&A

      什么是命令行?

      命令行是系统提供的一种工具,可以用这些工具来执行一些系统提供的功能,常见的命令行有:Linux的终端,Windows的cmd,windows的powershell(进阶版的cmd)。

      命令行在一些工具中也存在,比如说vscode就提供了命令行窗口,python著名的IDEpycharm也有提供命令行窗口和交互型解释器的窗口。

       powershell作为微软用来替代老旧的cmd的终端,powershell拥有更强大的功能,所有在cmd上可以实现的指令在powershell上都可以实现。找不到命令提示符(或者想要尝试新事物)的小伙伴可以尝试使用。


      Linux/Unix 的系统上,Python 解释器通常被安装在 /usr/local/python3 这样的有效路径(目录)里。

      我们可以将路径 /usr/local/python3/bin 添加到您的 Linux/Unix 操作系统的环境变量中(最好参照您 Python 的安装路径进行添加),这样您就可以通过 shell 终端输入下面的命令来启动 Python 。

      $ PATH=$PATH:/user/local/python3/bin/python #设置环境变量$ python3 --vesionPython 3.7.6

      在 Window 系统下你可以通过以下命令来设置 Python 的环境变量,假设你的 Python 安装在 C:Python37 下:

      set path=%path%;C:python37

      交互式编程

      打开 IDLE,默认的就是交互式编程,类似于一个 cmd 窗口。

      我们可以在命令提示符中输入 "Python" 命令来启动 Python 解释器:

      $ python3

      执行以上命令后,出现如下窗口信息:

      $ python3Python 3.4。0 (default, Mar 16 2014, 09:25:04)[GCC 4.8.2] on linuxType "help", "copyright", "credits" or "license" for more information.>>>

      在 Python 提示符中输入以下语句,然后按回车键查看运行效果:

      print ("Welcome to W3Cschool!");

      以上命令执行结果如下:


      当键入一个多行结构时,续行是必须的。我们可以看下如下 if 语句:

      >>> the_world_is_flat = True>>> if the_world_is_flat:...     print("Be careful not to fall off!")...Be careful not to fall off!

      脚本式编程

      点击 File→New 后新建脚本文件,在此文件下进行的是脚本式编程。

      将如下代码拷贝至 W3C.py 文件中:

      print ("Welcome to W3Cschool!");

      通过以下命令执行该脚本:

      python W3C.py

      输出结果为:

      Welcome to W3Cschool!

      在 Linux/Unix 系统中,你可以在脚本顶部添加以下命令让 Python 脚本可以像 SHELL 脚本一样可直接执行:

      #! /usr/bin/env python3.7

      然后修改脚本权限,使其有执行权限,命令如下:

      $ chmod +x W3C.py

      执行以下命令:

      ./hello.py

      输出结果为:

      Welcome to W3Cschool!


      VSCode(全称:Visual Studio Code)是一款由微软开发的跨平台免费源代码编辑器。VSCode 开发环境非常简单易用,仅需要安装相关的插件进行简易的配置就可以与原有的python环境组成一套具有简单的代码调试运行的开发工具。对于轻量级的python开发和python学习是比较友好的。优秀的代码提示和更多插件功能让VSCode的使用体验不亚于知名pythonIDE—pycharm。

      准备工作:

      • 安装 Python 3
      • 安装 VS Code
      • 安装 VS Code Python 扩展和Pylance拓展

      安装 VS Code

      VSCode 安装比较简单,打开官网 https://code.visualstudio.com/,下载软件包,一步步安装即可,安装过程注意安装路径设置、环境变量默认自动添加到系统中,勾选以下所有选项:

      安装 VS Code Python 扩展和Pylance拓展

      接着我们安装 VS Code Python 扩展:


      Python扩展将自动安装Pylance和Jupyter扩展,以便在使用Python文件和Jupyter笔记本时获得最佳体验。

      创建一个 Python 代码文件

      打开 VScode,然后点击新建文件:


      点击选择语言:


      在搜索框输入 Python,选中 Python 选项:


      输入代码:

      print("W3Cschool")

      右击鼠标,选择在交互式窗口运行文件,如果有提示需要安装内核,直接点安装即可(没有安装会一直显示在连接 Python 内核):(这里VSCode会使用python的pip进行安装,部分版本会安装失败,小编在尝试的时候使用python3.8版本失败了,3.7版本成功了)


      另外,我们也可以打开一个已存在的文件或目录(文件夹),比如我们打开一个 pythonproject,你也可以自己创建一个:


      然后我们创建一个 test.py 文件,点击下面新建文件图标,输入文件名 test.py:


      注:pythonproject 里面包含了一个 .vscode 文件夹,是一些配置信息,可以先不用管。

      在 test.py 输入以下代码:

      print("W3Cschool")

      点击右上角绿色图标,即可运行:


      可以右击文件,选择"在终端中运行 Python 文件":


      当然也可以在代码窗口上右击鼠标,选择"在终端中运行 Python 文件"。



      本章节将一些Python3基础语法整理成手册,方便各位在日常使用和学习时查阅,包含了编码、标识符、保留字、注释、缩进、字符串等常用内容。

      注意,这部分内容是后续学习的一个基础和预览,请不要随意跳过这个章节的学习!

      编码

      默认情况下,Python 3 源码文件以 UTF-8 编码,所有字符串都是 unicode 字符串。 当然你也可以为源码文件指定不同的编码:

      # -*- coding: cp-1252 -*-

      标识符

      • 第一个字符必须是字母表中字母或下划线'_'。
      • 标识符的其他的部分有字母、数字和下划线组成。
      • 标识符对大小写敏感。

      在 Python 3中,非 ASCII 编码的标识符也是允许的了。


      Python 保留字

      保留字即关键字,我们不能把它们用作任何标识符名称。Python 的标准库提供了一个关键词模块,我们可以使用它来查看当前版本的所有保留字:

      >>> import keyword>>> keyword.kwlist

      ['False', 'None', 'True', '__peg_parser__', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']

      上面代码是在解释器执行的结果,写成python脚本代码应该写成如下样式(后续代码可能会有两种版本的代码块,但并不会多做解释,望读者周知!):
      import keywordprint(keyword.kwlist)


      注释

      Python 中单行注释以 # 开头,多行注释采用三对单引号(''')或者三对双引号(""")将注释括起来。

      #这是单行注释"""这是多行注释这是多行注释"""'''也可以用三个单引号来进行多行注释'''
      实际上python注释只有一种,就是单行注释,多行注释的这种使用方法类似于java的javadoc,三引号的这种使用方法实际上是用来声明多行长字符串的。

      缩进

      Python 最具特色的就是使用缩进来表示代码块。缩进的空格数是可变的,但是同一个代码块的语句必须包含相同的缩进空格数


      标准数据类型

      Python 中有六个标准的数据类型:

      • Number(数字)
      • String(字符串)
      • List(列表)
      • Tuple(元组)
      • Set(集合)
      • Dictionary(字典)

      Python3 的六个标准数据类型中:

      • 不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);
      • 可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。

       可变数据和不可变数据是相对于引用地址来说的,不可变数据类型不允许变量的值发生变化,如果改变了的变量的值,相当于新建了一个对象,而对于相同的值的对象,内部会有一个引用计数来记录有多少个变量引用了这个对象。可变数据类型允许变量的值发生变化。对变量进行修改操作只会改变变量的值,不会新建对象,变量引用的地址也不会发生变化,不过对于相同的值的不同对象,在内存中则会存在不同的对象,即每个对象都有自己的地址,相当于内存中对于同值的对象保存了多份,这里不存在引用计数,是实实在在的对象。

      简单地讲,可变数据和不可变数据的“变”是相对于引用地址来说的,不是不能改变其数据,而是改变数据的时候会不会改变变量的引用地址。


      类型判断

      python可以用type函数来检查一个变量的类型,使用方法如下:

      >>> x = "W3Cschool">>> type(x)<type 'str'>>>> x=100>>> type(x)<type 'int'>>>> x=('1','2','3')>>> type(x)<type 'tuple'>>>> x = ['1','2','3']>>> type(x)<type 'list'>

      在脚本代码中的使用:

      x = "W3Cschool"print(type(x))

      字符串

      • Python 中单引号和双引号使用完全相同,但单引号和双引号不能匹配。
      • 使用三对引号('''或""")可以囊括一个多行字符串。
      • 与其他语言相似,python也使用 ''作为转义字符
      • 自然字符串, 通过在字符串前加 r 或 R。 如 r"this is a line with " 则 会显示,并不是换行。
      • Python 允许处理 unicode 字符串,加前缀 u 或 U, 如 u"this is an unicode string"。
      • 字符串是不可变的。
      • 按字面意义级联字符串,如"this " "is " "string"会被自动转换为this is string。
      • 字符串可以用 + 运算符连接在一起,用 * 运算符重复。
      • Python 中的字符串有两种索引方式,从左往右以 0 开始,从右往左以 -1 开始。
      • Python中的字符串不能改变(详见上一小点的引用)。
      • Python 没有单独的字符类型,一个字符就是长度为 1 的字符串。
      • 字符串的截取的语法格式如下:变量 [头下标: 尾下标: 步长]

       关于字符串的更多内容,请前往字符串小节进行学习。

      word = '字符串'sentence = "这是一个句子。"paragraph = """这是一个段落,可以由多行组成"""

      实例:

      #!/usr/bin/python3 str='W3Cschool' print(str)                 # 输出字符串print(str[0:-1])           # 输出第一个到倒数第二个的所有字符print(str[0])              # 输出字符串第一个字符print(str[2:5])            # 输出从第三个开始到第五个的字符print(str[2:])             # 输出从第三个开始后的所有字符print(str[1:5:2])          # 输出从第二个开始到第五个且每隔两个的字符print(str * 2)             # 输出字符串两次print(str + '你好')         # 连接字符串 print('------------------------------') print('hello
      W3Cschool')      # 使用反斜杠()+n转义特殊字符print(r'hello
      W3Cschool')     # 在字符串前面添加一个 r,表示原始字符串,不会发生转义

      以上实例输出结果:

      W3CschoolW3CschooWCscCschool3sW3CschoolW3CschoolW3Cschool你好------------------------------helloW3Cschoolhello
      W3Cschool

      这里的 r 指 raw,即 raw string,会自动将反斜杠转义,例如:

      >>> print('
      ')       # 输出空行>>> print(r'
      ')      # 输出 
      >>>
      

      空行

      函数之间或类的方法之间用空行分隔,表示一段新的代码的开始。类和函数入口之间也用两行空行分隔,以突出函数入口的开始。

      空行与代码缩进不同,空行并不是 Python 语法的一部分。书写时不插入空行,Python 解释器运行也不会出错。但是空行的作用在于分隔两段不同功能或含义的代码,便于日后代码的维护或重构。

      记住:空行也是程序代码的一部分。

       在PEP8中介绍了一些python代码的格式,其中介绍了函数之间要有两行空行,如果python代码没有使用两行空行的话,部分IDE会出现修改提示(比如pycharm)。这样的代码不影响运行,但对于代码阅读不利,


      输入&等待用户输入

      input函数可以用来接受输入,它可以传入一个字符串,当input函数调用的时候,会在控制台打印这个字符串(所以这个字符串通常被用来做输入的提示信息)。

       input函数会读取输入内容直到读到回车,也就是说,内容输入完毕后要按回车键才能执行。

      input("这是一个简单的input信息") # 这是一个简单的input样例,他输出input信息并接受一个字符串x=input("请输入X的值:") # 这是一个常见的input样例,他输出提示信息,然后接受一个字符串并将值传递给一个变量Xprint(x) # 打印变量,可以看到输入的x的值print(type(x)) #查看这个变量的类型x = int(input("请输入一个数值:")) # 配合强制类型转换,可以将字符串转变为int类型(字符串类型不能参与计算)# 也可以分步写成:#x=input("请输入一个数值:") # 接受一个字符串#x=int(x)   #将x转换为int型# 这里强制转换也可以转换为其他类型,详细的转换方法请参考基本数据类型的强制转换相关内容print(x) # 打印变量,可以看到输入的x的值print(type(x)) #查看这个变量的类型input("
      
      按下 enter 键后退出。") # 其实这里并没有接受任何内容,input函数以enter作为结尾,所以只有输入回车后才会结束input函数

      以上代码中 ," "在结果输出前会输出两个新的空行。一旦用户按下 enter 键时,程序将退出。


      同一行显示多条语句

      Python 可以在同一行中使用多条语句,语句之间使用分号 (;) 分割,以下是一个简单的实例:

      实例:

      #!/usr/bin/python3 import sys; x = 'W3Cschool'; sys.stdout.write(x + '
      ')

      使用脚本执行以上代码,输出结果为:

      W3Cschool

      使用交互式命令行执行,输出结果为:

      >>> import sys; x = 'W3Cschool'; sys.stdout.write(x + '
      ')
      W3Cschool
      10

      此处的 10 表示字符数。

       python以回车作为语句结束的标志,一行一句语句的特色使得Python更加易读,而在一行中显示多条语句的这种行为会破坏python的可读性,不建议使用!


      多个语句构成代码组

      缩进相同的一组语句构成一个代码块,我们称之代码组。

      像 if、while、def 和 class 这样的复合语句,首行以关键字开始,以冒号 ( : ) 结束,该行之后的一行或多行代码构成代码组。

      我们将首行及后面的代码组称为一个子句 (clause)。

      如下实例:

      if expression : 
        suite
      elif expression :
        suite
      else :
        suite

      print 输出

      print函数是python的基本输出函数,他可以将变量输出(或者说,打印)到控制台。在第一个python程序中,我们就用到了print函数:

      #!/usr/bin/python3print("Hello, World!") #"Hello,World!"是一个字符串变量str = "Hello,World!"print(str) #上一种helloworld的另一种写法

      print 默认输出是换行的,如果要实现不换行需要在变量末尾加上 end="":

      实例:

      #!/usr/bin/python3 x="a"y="b"# 换行输出print( x )print( y ) print('---------')# 不换行输出print( x, end=" " )print( y, end=" " )print()

      以上实例执行结果为:

      a
      b
      ---------
      a b
      关于print的内容,本章只是粗略介绍,目的是为了能够基础使用print函数。后续章节中有print函数的详细介绍。

      import 与 from...import

      在 Python 用 import 或者 from...import 来导入相应的模块。

      将整个模块 (somemodule) 导入,格式为:​ import somemodule

      从某个模块中导入某个函数,格式为:​ from somemodule import somefunction

      从某个模块中导入多个函数,格式为:​ from somemodule import firstfunc, secondfunc, thirdfunc

      将某个模块中的全部函数导入,格式为:​ from somemodule import *

      导入 sys 模块

      import sysprint('================Python import mode==========================')print ('命令行参数为:')for i in sys.argv:    print (i)print ('
       python 路径为',sys.path)

      导入 sys 模块的 argv,path 成员

      from sys import argv,path  #  导入特定的成员 print('================python from import===================================')print('path:',path) # 因为已经导入path成员,所以此处引用时不需要加sys.path

      命令行参数

      很多程序可以执行一些操作来查看一些基本信息,Python 可以使用 -h 参数查看各参数帮助信息:

      $ python -h
      usage: python [option] ... [-c cmd | -m mod | file | -] [arg] ...
      Options and arguments (and corresponding environment variables):
      -c cmd : program passed in as string (terminates option list)
      -d     : debug output from parser (also PYTHONDEBUG=x)
      -E     : ignore environment variables (such as PYTHONPATH)
      -h     : print this help message and exit

      [ etc. ]



      现在,我们能使用 Python 完成比 ​2+2​ 更复杂的工作。在下例里,我们能写出一个初步的斐波纳契数列如下:

      #!/usr/bin/python3# Fibonacci series: 斐波纳契数列# 两个元素的总和确定了下一个数a, b = 0, 1while b < 10:    print(b)    a, b = b, a+b

      有关斐波那契数列的具体问题可在 斐波纳契奇数求和算法挑战 教程中进一步了解。

      其中代码​ a, b = b, a + b​ 的计算方式为先计算右边的表达式,然后同时赋值给左边,等价于:

      n = bm = a + ba = nb = m

      执行以上程序,输出结果为:

      112358

      这个例子介绍了几个新特征。

      • 第一行包含了一个复合赋值:变量 a 和 b 同时得到新值 0 和 1。
      • 最后一行也使用了复合赋值的方法:等价于 c = a,a = b,b = b + c。


      接下来尝试输出变量值:

      i = 1024 * 1024print('i 的值为:', i)

      执行以上程序,输出结果为:

      i 的值为: 1048576

      end 关键字

      关键字 end 可以用于将结果输出到同一行,或者在输出的末尾添加不同的字符,实例如下:

      # 两个元素的总和确定了下一个数a, b = 0, 1while b < 1024:    print(b, end=',')    a, b = b, a+b

      执行以上程序,输出结果为:

      1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,

      最后尝试使用 if 条件控制  

      age = int(input("请输入你家狗狗的年龄: "))print("")if age < 0:	print("请输入正确的年龄。")elif age == 1:	print("相当于 14 岁的人。")elif age == 2:	print("相当于 22 岁的人。")elif age > 2:	human = 22 + (age -2)*5	print("对应人类年龄: ", human)### 退出提示,本地环境下可以使用这样的退出提示使代码更易用input('点击 enter 键退出')


      在 Python 中,变量就是变量,它没有类型,我们所说的"类型"是变量所指的内存中对象的类型。

      Python 3 中有六个标准的数据类型:

      • Numbers(数字)
      • String(字符串)
      • List(列表)
      • Tuple(元组)
      • Sets(集合)
      • Dictionaries(字典)

      Numbers(数字)

      Python 3 支持 int(整型)、float(浮点型)、bool(布尔型)、complex(复数)。

      数值类型的赋值和计算都是很直观的,就像大多数语言一样。内置的 type() 函数可以用来查询变量所指的对象类型。

      >>> a, b, c, d = 20, 5.5, True, 4+3j>>> print(type(a), type(b), type(c), type(d))<class 'int'><class 'float'><class 'bool'><class 'complex'>

      此外还可以用isinstance来判断:

      >>>a=111>>>isinstance(a,int)True>>>

      isinstance和type的区别在于:

      • type()不会认为子类是一种父类类型。
      • isinstance()会认为子类是一种父类类型。
      >>> class A:...     pass... >>> class B(A):...     pass... >>> isinstance(A(), A)True>>> type(A()) == A True>>> isinstance(B(), A)True>>> type(B()) == AFalse

      注意:在 Python2 中是没有布尔型的,它用数字 0 表示 False,用 1 表示 True。到 Python3 中,把 True 和 False 定义成关键字了,但它们的值还是 1 和 0,它们可以和数字相加。

      当你指定一个值时,Number 对象就会被创建:

      var1 = 1var2 = 10

      您也可以使用 del 语句删除一些对象引用。

      del 语句的语法是:

      del var1[,var2[,var3[....,varN]]]

      您可以通过使用 del 语句删除单个或多个对象。例如:

      del vardel var_a, var_b

      数值运算:

      >>> 5 + 4  # 加法9>>> 4.3 - 2 # 减法2.3>>> 3 * 7  # 乘法21>>> 2 / 4  # 除法,得到一个浮点数0.5>>> 2 // 4 # 除法,得到一个整数0>>> 17 % 3 # 取余 2>>> 2 ** 5 # 乘方32

      注意:

      • 1、Python 可以同时为多个变量赋值,如 a, b = 1, 2。
      • 2、一个变量可以通过赋值指向不同类型的对象。
      • 3、数值的除法(/)总是返回一个浮点数,要获取整数使用​//​操作符。
      • 4、在混合计算时,Python 会把整型转换成为浮点数。

      String(字符串)

      Python 中的字符串 str 用单引号(' ')或双引号 (" ") 括起来,同时使用反斜杠 () 转义特殊字符。

      >>> s = 'Yes,he doesn't'>>> print(s, type(s), len(s))Yes,he doesn't  <class 'str'> 14

      如果你不想让反斜杠发生转义,可以在字符串前面添加一个 r,表示原始字符串:

      >>> print('C:some
      ame')C:someame>>> print(r'C:some
      ame')C:some
      ame

      另外,反斜杠可以作为续行符,表示下一行是上一行的延续。还可以使用"""..."""或者'''...'''跨越多行。

      字符串可以使用 + 运算符串连接在一起,或者用 * 运算符重复:

      >>> print('str'+'ing', 'my'*3)string mymymy

      Python 中的字符串有两种索引方式,第一种是从左往右,从 0 开始依次增加;第二种是从右往左,从 -1 开始依次减少。

      注意,没有单独的字符类型,一个字符就是长度为 1 的字符串。

      >>> word = 'Python'>>> print(word[0], word[5])P n>>> print(word[-1], word[-6])n P

      还可以对字符串进行切片,获取一段子串。用冒号分隔两个索引,形式为变量[头下标:尾下标]。

      截取的范围是前闭后开的(头下标取,尾下标不取),并且两个索引都可以省略:

      >>> word = 'ilovepython'>>> word[1:5]'love'>>> word[:]'ilovepython'>>> word[5:]'python'>>> word[-10:-6]'love'

      与 C 字符串不同的是,Python 字符串不能被改变。向一个索引位置赋值,比如 word[0] = 'm' 会导致错误

      注意:

      • 1、反斜杠可以用来转义,使用 r 可以让反斜杠不发生转义。
      • 2、字符串可以用 + 运算符连接在一起,用 * 运算符重复。
      • 3、Python 中的字符串有两种索引方式,从左往右以 0 开始,从右往左以 -1 开始。
      • 4、Python 中的字符串不能改变。

      List(列表)

      List(列表) 是 Python 中使用最频繁的数据类型。

      列表是写在方括号之间、用逗号分隔开的元素列表。列表中元素的类型可以不相同:

      >>> a = ['him', 25, 100, 'her']>>> print(a)['him', 25, 100, 'her']

      和字符串一样,列表同样可以被索引和切片,列表被切片后返回一个包含所需元素的新列表。详细的在这里就不赘述了。

      列表还支持串联操作,使用 + 操作符:

      >>> a = [1, 2, 3, 4, 5]>>> a + [6, 7, 8][1, 2, 3, 4, 5, 6, 7, 8]

      与 Python 字符串不一样的是,列表中的元素是可以改变的:

      >>> a = [1, 2, 3, 4, 5, 6]>>> a[0] = 9>>> a[2:5] = [13, 14, 15]>>> a[9, 2, 13, 14, 15, 6]>>> a[2:5] = []   # 删除>>> a[9, 2, 6]

      List 内置了有很多方法,例如 append()、pop() 等等,这在后面会讲到。

      注意:

      • 1、List 写在方括号之间,元素用逗号隔开。
      • 2、和字符串一样,List 可以被索引和切片。
      • 3、List 可以使用 + 操作符进行拼接。
      • 4、List 中的元素是可以改变的。

      Tuple(元组)

      元组(tuple)与列表类似,不同之处在于元组的元素不能修改。元组写在小括号里,元素之间用逗号隔开。

      元组中的元素类型也可以不相同:

      >>> a = (1991, 2014, 'physics', 'math')>>> print(a, type(a), len(a))(1991, 2014, 'physics', 'math') <class 'tuple'> 4

      元组与字符串类似,可以被索引且下标索引从 0 开始,也可以进行截取/切片(看上面,这里不再赘述)。

      其实,可以把字符串看作一种特殊的元组。

      >>> tup = (1, 2, 3, 4, 5, 6)>>> print(tup[0], tup[1:5])1 (2, 3, 4, 5)>>> tup[0] = 11  # 修改元组元素的操作是非法的

      虽然 tuple 的元素不可改变,但它可以包含可变的对象,比如 list 列表。

      构造包含 0 个或 1 个元素的 tuple 是个特殊的问题,所以有一些额外的语法规则:

      tup1 = () # 空元组tup2 = (20,) # 一个元素,需要在元素后添加逗号

      另外,元组也支持用 + 操作符:

      >>> tup1, tup2 = (1, 2, 3), (4, 5, 6)>>> print(tup1+tup2)(1, 2, 3, 4, 5, 6)

      string、list 和 tuple 都属于 sequence(序列)。

      注意:

      • 1、与字符串一样,元组的元素不能修改。
      • 2、元组也可以被索引和切片,方法都是一样的。
      • 3、注意构造包含 0 或 1 个元素的元组的特殊语法规则。
      • 4、元组也可以使用 + 操作符进行拼接。

      Sets(集合)

      集合(set)是一个无序不重复元素的集。

      基本功能是进行成员关系测试和消除重复元素。

      可以使用大括号 或者 set() 函数创建 set 集合,注意:创建一个空集合必须用 set() 而不是 { },因为{ }是用来创建一个空字典。

      >>> student = {'Tom', 'Jim', 'Mary', 'Tom', 'Jack', 'Rose'}>>> print(student)   # 重复的元素被自动去掉{'Jim', 'Jack', 'Mary', 'Tom', 'Rose'}>>> 'Rose' in student  # membership testing(成员测试)True>>> # set可以进行集合运算... >>> a = set('abracadabra')>>> b = set('alacazam')>>> a{'a', 'b', 'c', 'd', 'r'}>>> a - b     # a和b的差集{'b', 'd', 'r'}>>> a | b     # a和b的并集{'l', 'm', 'a', 'b', 'c', 'd', 'z', 'r'}>>> a & b     # a和b的交集{'a', 'c'}>>> a ^ b     # a和b中不同时存在的元素{'l', 'm', 'b', 'd', 'z', 'r'}

      Dictionaries(字典)

      字典(dictionary)是 Python 中另一个非常有用的内置数据类型。

      字典是一种映射类型(mapping type),它是一个无序的键值对(key-value)集合。

      关键字(key)必须使用不可变类型,也就是说list和包含可变类型的 tuple 不能做关键字。

      在同一个字典中,关键字(key)必须互不相同。

      >>> dic = {}  # 创建空字典>>> tel = {'Jack':1557, 'Tom':1320, 'Rose':1886}>>> tel{'Tom': 1320, 'Jack': 1557, 'Rose': 1886}>>> tel['Jack']   # 主要的操作:通过key查询1557>>> del tel['Rose']  # 删除一个键值对>>> tel['Mary'] = 4127  # 添加一个键值对>>> tel{'Tom': 1320, 'Jack': 1557, 'Mary': 4127}>>> list(tel.keys())  # 返回所有key组成的list['Tom', 'Jack', 'Mary']>>> sorted(tel.keys()) # 按key排序['Jack', 'Mary', 'Tom']>>> 'Tom' in tel       # 成员测试True>>> 'Mary' not in tel  # 成员测试False

      构造函数 dict() 直接从键值对 sequence 中构建字典,当然也可以进行推导,如下:

      >>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)]){'jack': 4098, 'sape': 4139, 'guido': 4127}>>> {x: x**2 for x in (2, 4, 6)}{2: 4, 4: 16, 6: 36}>>> dict(sape=4139, guido=4127, jack=4098){'jack': 4098, 'sape': 4139, 'guido': 4127}

      另外,字典类型也有一些内置的函数,例如 clear()、keys()、values() 等。

      注意:

      • 1、字典是一种映射类型,它的元素是键值对。
      • 2、字典的关键字必须为不可变类型,且不能重复。
      • 3、创建空字典使用 { }。


      Python3注释可以确保对模块, 函数, 方法和行内注释使用正确的风格,有专门的符号和格式,有单行与多行的区别。

      Python 中的注释有单行注释和多行注释:

      Python 中单行注释以 # 开头,例如:

      #!/usr/bin/python3 #coding=utf-8# 这是一个注释print("Hello, World") 

      多行注释用三个单引号(''')或者三个双引号(""")将需要注释的内容囊括起来,例如:

      1、单引号(''')

      #!/usr/bin/python3 #coding=utf-8'''这是多行注释,用三个单引号这是多行注释,用三个单引号 这是多行注释,用三个单引号'''print("Hello, World!") 

      2、双引号(""")

      #!/usr/bin/python3 #coding=utf-8"""这是多行注释,用三个双引号这是多行注释,用三个双引号 这是多行注释,用三个双引号"""print("Hello, World!") 

       三引号实际上是多行长字符串的声明方式,也作为python代码文档使用(类似javadoc)。


      本章节主要说明 Python 的运算符。举个简单的例子 4 + 5 = 9 。例子中,45 被称为操作数,"+" 称为运算符。

      Python 语言支持以下类型的运算符:

      接下来让我们一个个来学习 Python 的运算符。


      Python 算术运算符

      以下假设变量 a 为 21,变量 b 为 10:

      运算符描述实例
      +加 - 两个对象相加a + b 输出结果 31
      -减 - 得到负数或是一个数减去另一个数a - b 输出结果 -11
      *乘 - 两个数相乘或是返回一个被重复若干次的字符串a * b 输出结果 210
      /除 - x 除以 ya / b 输出结果 2.1
      %取模 - 返回除法的余数a % b 输出结果 1
      **幂 - 返回 x 的 y 次幂a ** b 为 10 的 21 次方
      //取整除 - 返回商的整数部分9//2 输出结果 4 , 9.0//2.0 输出结果 4.0

      以下实例演示了 Python 所有算术运算符的操作:

      #!/usr/bin/python3#coding=utf-8a = 21b = 10c = 0c = a + bprint ("a+b 的值为:", c)c = a - bprint ("a-b 的值为:", c)c = a * bprint ("a*b 的值为:", c)c = a / bprint ("a/b 的值为:", c)c = a % bprint ("a%b 的值为:", c)# 修改变量 a 、b 、ca = 2b = 3c = a**b print ("a**b 的值为:", c)a = 10b = 5c = a//b print ("a//b 的值为:", c)

      以上实例输出结果:

      a+b 的值为: 31

      a-b 的值为: 11

      a*b 的值为: 210

      a/b 的值为: 2.1

      a%b 的值为: 1

      a**b 的值为: 8

      a//b 的值为: 2


      Python 比较运算符

      以下假设变量 a 为 10,变量 b 为 20:

      运算符描述实例
      ==等于 -- 比较对象是否相等(a == b) 返回 False。
      !=不等于 -- 比较两个对象是否不相等(a != b) 返回 True.
      >大于 -- 返回 x 是否大于 y(a > b) 返回 False。
      <小于 -- 返回 x 是否小于 y。(a < b) 返回 True。
      >=大于等于 -- 返回 x 是否大于等于 y。(a >= b) 返回 False。
      <=小于等于 -- 返回 x 是否小于等于 y。(a <= b) 返回 True。

      所有比较运算符返回 1 表示真,返回 0 表示假。这分别与特殊的变量 True 和 False 等价。注意:True和False的首字母为大写。

      以下实例演示了 Python 所有比较运算符的操作:

      #!/usr/bin/python3#coding=utf-8a = 21b = 10c = 0if ( a == b ):    print ("a 等于 b")else:    print ("a 不等于 b")if ( a != b ):    print ("a 不等于 b")else:    print ("a 等于 b")if ( a < b ):    print ("a 小于 b")else:    print ("a 大于等于 b")if ( a > b ):    print ("a 大于 b")else:    print ("a 小于等于 b")# 修改变量 a 和 b 的值a = 5;b = 20;if ( a <= b ):    print ("a 小于等于 b")else:    print ("a 大于  b")if ( a >= b ):    print ("a 大于等于 b")else:    print ("a 小于 b")

      以上实例输出结果:

      a 不等于 b

      a 不等于 b

      a 大于等于 b

      a 大于 b

      a 小于等于 b

      a 小于 b


      Python 赋值运算符

      以下假设变量 a 为 10,变量 b 为 20:

      运算符描述实例
      =简单的赋值运算符c = a + b 将 a + b 的运算结果赋值为 c
      +=加法赋值运算符c += a 等效于 c = c + a
      -=减法赋值运算符c -= a 等效于 c = c - a
      *=乘法赋值运算符c *= a 等效于 c = c * a
      /=除法赋值运算符c /= a 等效于 c = c / a
      %=取模赋值运算符c %= a 等效于 c = c % a
      **=幂赋值运算符c **= a 等效于 c = c ** a
      //=取整除赋值运算符c //= a 等效于 c = c // a

      以下实例演示了 Python 所有赋值运算符的操作:

      #!/usr/bin/python3#coding=utf-8a = 21b = 10c = 0c = a + bprint ("1 - c 的值为:", c)c += aprint ("2 - c 的值为:", c)c *= aprint ("3 - c 的值为:", c)c /= a print ("4 - c 的值为:", c)c = 2c %= aprint ("5 - c 的值为:", c)c **= aprint ("6 - c 的值为:", c)c //= aprint ("7 - c 的值为:", c)

      以上实例输出结果:

      1 - c 的值为: 312 - c 的值为: 523 - c 的值为: 10924 - c 的值为: 52.05 - c 的值为: 26 - c 的值为: 20971527 - c 的值为: 99864

      Python 位运算符

      按位运算符是把数字看作二进制来进行计算的。Python 中的按位运算法则如下:

      下表中变量 a 为 60,b 为 13。

        按位与运算(a&b) 按位或运算(a|b)按位异或(a^b) 
       a(60)的二进制表示0011 1100 0011 1100 0011 1100 
       b(13)的二进制表示0000 11010000 1101 0000 1101 
       运算结果0000 11000011 11010011 0001
       结果的十进制表示 12 61 49
        按位取反(~a)左移(a<<2)右移(a>>2) 
       a(60)的二进制表示0011 1100 0011 1100 0011 1100 
       运算结果1100 0011 1111 00000000 1111
       运算结果的十进制表示 -61 240 15
      注:关于原码,补码和反码:
      原码:假设机器字长为n,原码就是用一个n位的二进制数,其中最高位为符号位:正数是0,负数是1。剩下的表示概数的绝对值,位数如果不够就用0补全。
      反码:在原码的基础上,符号位不变其他位取反,也就是就是0变1,1变0。
      补码:在反码的基础上加1。  
      PS:正数的原、反、补码都一样,0的原码跟反码都有两个,因为这里0被分为+0和-0。
      按位取反和反码有一定的相似之处但又不尽相同(反码符号位不取反)。
      在计算机中,是以补码的形式存放数据的。1100 0011刚好对应-61。
      -61的原码-> 1011 1101->反码->1100 0010->补码->1100 0011
      运算符描述实例
      &按位与运算符:参与运算的两个值,如果两个相应位都为  1,则该位的结果为 1,否则为 0(a & b) 输出结果 12 ,二进制解释: 0000 1100
      |按位或运算符:只要对应的二个二进位有一个为 1 时,结果位就为 1。(a | b) 输出结果 61 ,二进制解释: 0011 1101
      ^按位异或运算符:当两对应的二进位相异(不同)时,结果为 1(a ^ b) 输出结果 49 ,二进制解释: 0011 0001
      ~按位取反运算符:对数据的每个二进制位取反,即把 1 变为 0,把 0 变为 1(~a ) 输出结果 -61 ,二进制解释: 1100 0011
      <<左移动运算符:运算数的各二进位全部左移若干位,由"<<"右边的数指定移动的位数,高位丢弃,低位补 0。a << 2 输出结果 240 ,二进制解释: 1111 0000
      >>右移动运算符:把">>"左边的运算数的各二进位全部右移若干位,">>"右边的数指定移动的位数a >> 2 输出结果 15 ,二进制解释: 0000 1111

      以下实例演示了 Python 所有位运算符的操作:

      #!/usr/bin/python3#coding=utf-8a = 60            # 60 = 0011 1100 b = 13            # 13 = 0000 1101 c = 0c = a & b;        # 12 = 0000 1100print ("1 - c 的值为:", c)c = a | b;        # 61 = 0011 1101 print ("2 - c 的值为:", c)c = a ^ b;        # 49 = 0011 0001print ("3 - c 的值为:", c)c = ~a;           # -61 = 1100 0011print ("4 - c 的值为:", c)c = a << 2;       # 240 = 1111 0000print ("5 - c 的值为:", c)c = a >> 2;       # 15 = 0000 1111print ("6 - c 的值为:", c)

      以上实例输出结果:

      1 - c 的值为: 122 - c 的值为: 613 - c 的值为: 494 - c 的值为: -615 - c 的值为: 2406 - c 的值为: 15

      Python 逻辑运算符

      Python 语言支持逻辑运算符,以下假设变量 a 为 10, b 为 20:

      运算符逻辑表达式描述实例
      andx and y布尔"与" - 如果 x 为 False,x and y 返回 False,否则它返回 y 的计算值。(a and b) 返回 20。
      orx or y布尔"或" - 如果 x 是 True,它返回 x的值,否则它返回 y 的计算值。(a or b) 返回 10。
      notnot x布尔"非" - 如果 x 为 True,返回 False 。如果 x 为 False,它返回 True。not(a and b) 返回 False

      以上实例输出结果:

      #!/usr/bin/python3#coding=utf-8a = 10b = 20if ( a and b ):    print ("1 - 变量 a 和 b 都为 true")else:    print ("1 - 变量 a 和 b 有一个不为 true")if ( a or b ):    print ("2 - 变量 a 和 b 都为 true,或其中一个变量为 true")else:    print ("2 - 变量 a 和 b 都不为 true")# 修改变量 a 的值a = 0if ( a and b ):    print ("3 - 变量 a 和 b 都为 true")else:    print ("3 - 变量 a 和 b 有一个不为 true")if ( a or b ):    print ("4 - 变量 a 和 b 都为 true,或其中一个变量为 true")else:    print ("4 - 变量 a 和 b 都不为 true")if not( a and b ):    print ("5 - 变量 a 和 b 都为 false,或其中一个变量为 false")else:    print ("5 - 变量 a 和 b 都为 true")

      以上实例输出结果:

      1 - 变量 a 和 b 都为 true2 - 变量 a 和 b 都为 true,或其中一个变量为 true3 - 变量 a 和 b 有一个不为 true4 - 变量 a 和 b 都为 true,或其中一个变量为 true5 - 变量 a 和 b 都为 false,或其中一个变量为 false

      Python 成员运算符

      除了以上的一些运算符之外,Python 还支持成员运算符,测试实例中包含了一系列的成员,包括字符串,列表或元组。

      运算符描述实例
      in如果在指定的序列中找到值返回 True,否则返回 False。x 在 y 序列中 , 如果 x 在 y 序列中返回 True。
      not in如果在指定的序列中没有找到值返回 True,否则返回 False。x 不在 y 序列中 , 如果 x 不在 y 序列中返回 True。

      以下实例演示了 Python 所有成员运算符的操作:

      #!/usr/bin/python3#coding=utf-8a = 10b = 20list = [1, 2, 3, 4, 5 ];if ( a in list ):    print ("1 - 变量 a 在给定的列表中 list 中")else:    print ("1 - 变量 a 不在给定的列表中 list 中")if ( b not in list ):    print ("2 - 变量 b 不在给定的列表中 list 中")else:    print ("2 - 变量 b 在给定的列表中 list 中")# 修改变量 a 的值a = 2if ( a in list ):    print ("3 - 变量 a 在给定的列表中 list 中")else:    print ("3 - 变量 a 不在给定的列表中 list 中")

      以上实例输出结果:

      1 - 变量 a 不在给定的列表中 list 中2 - 变量 b 不在给定的列表中 list 中3 - 变量 a 在给定的列表中 list 中

      Python 身份运算符

      身份运算符用于比较两个对象的存储单元

      运算符描述实例
      isis 是判断两个标识符是不是引用自一个对象x is y, 如果 id(x) 等于 id(y) , is 返回结果 True
      is notis not 是判断两个标识符是不是引用自不同对象x is not y, 如果 id(x) 不等于 id(y). is not 返回结果 True

      以下实例演示了 Python 所有身份运算符的操作:

      #!/usr/bin/python3#coding=utf-8a = 20b = 20if ( a is b ):    print ("1 - a 和 b 有相同的标识")else:    print ("1 - a 和 b 没有相同的标识")if ( id(a) == id(b) ):    print ("2 - a 和 b 有相同的标识")else:    print ("2 - a 和 b 没有相同的标识")# 修改变量 b 的值b = 30if ( a is b ):    print ("3 - a 和 b 有相同的标识")else:    print ("3 - a 和 b 没有相同的标识")if ( a is not b ):    print ("4 - a 和 b 没有相同的标识")else:    print ("4 - a 和 b 有相同的标识")

      以上实例输出结果:

      1 - a 和 b 有相同的标识2 - a 和 b 有相同的标识3 - a 和 b 没有相同的标识4 - a 和 b 没有相同的标识

      Python 运算符优先级

      以下表格列出了从最高到最低优先级的所有运算符:

      运算符描述
      **指数 (最高优先级)
      ~ + -按位翻转, 一元加号和减号 (最后两个的方法名为 +@ 和 -@)
      * / % //乘,除,取模和取整除
      + -加法减法
      >> <<右移,左移运算符
      &位 'AND'
      ^ |位运算符
      <= < > >=比较运算符
      <> == !=比较运算符
      = %= /= //= -= += *= **=赋值运算符
      is is not身份运算符
      in not in成员运算符
      not or and逻辑运算符

      •  括号因为不是运算符所以没有纳入本表,但算术式中一旦出现括号,就要先算括号内的内容。
      • 同一级运算符的优先级从左往右进行计算。

      以下实例演示了 Python 所有运算符优先级的操作:

      #!/usr/bin/python3#coding=utf-8a = 20b = 10c = 15d = 5e = 0e = (a + b) * c / d       #( 30 * 15 ) / 5print ("(a + b) * c / d 运算结果为:",  e)e = ((a + b) * c) / d     # (30 * 15 ) / 5print ("((a + b) * c) / d 运算结果为:",  e)e = (a + b) * (c / d);    # (30) * (15/5)print ("(a + b) * (c / d) 运算结果为:",  e)e = a + (b * c) / d;      #  20 + (150/5)print ("a + (b * c) / d 运算结果为:",  e)

      以上实例输出结果:

      (a + b) * c / d 运算结果为: 90.0((a + b) * c) / d 运算结果为: 90.0(a + b) * (c / d) 运算结果为: 90.0a + (b * c) / d 运算结果为: 50.0



      Python 数字类型用于数值的储存。数值类型是不允许改变的,如果改变数字数据类型的值,将重新分配内存空间。

      以下实例在变量赋值时 Number 对象将被创建:

      var1 = 1var2 = 10

      您也可以使用del语句删除一些数字对象的引用。

      del语句的语法是:

      del var1[,var2[,var3[....,varN]]]

      您可以通过使用del语句删除单个或多个对象的引用,例如:

      del vardel var_a, var_b

      Python 支持三种不同的数值类型:

      • 整型(Int) - 通常被称为是整型或整数,是正或负整数,不带小数点。Python3 整型是没有限制大小的,可以当作 Long 类型使用,所以 Python3 没有 Python2 的 Long 类型。
      • 浮点型(float) - 浮点型由整数部分与小数部分组成,浮点型也可以使用科学计数法表示(2.5e2 = 2.5 x 102 = 250)
      • 复数( (complex)) - 复数由实数部分和虚数部分构成,可以用a + bj,或者complex(a,b)表示, 复数的实部a和虚部b都是浮点型。

      我们可以使用十六进制和八进制来代表整数:

      >>> number = 0xA0F # 十六进制>>> number2575>>> number=0o37 # 八进制>>> number31
      intfloatcomplex
      100.03.14j
      10015.2045.j
      -786-21.99.322e-36j
      08032.3e+18.876j
      -0490-90.-.6545+0J
      -0x260-32.54e1003e+26J
      0x6970.2E-124.53e-7j
      • Python支持复数,复数由实数部分和虚数部分构成,可以用a + bj,或者complex(a,b)表示, 复数的实部a和虚部b都是浮点型。

      Python 数字类型转换

      有时候,我们需要对数据内置的类型进行转换,数据类型的转换,你只需要将数据类型作为函数名即可。

      • int(x) 将x转换为一个整数。

      • float(x) 将x转换到一个浮点数。

      • complex(x) 将x转换到一个复数,实数部分为 x,虚数部分为 0。

      • complex(x, y) 将 x 和 y 转换到一个复数,实数部分为 x,虚数部分为 y。x 和 y 是数字表达式。

      以下实例将浮点数变量 a 转换为整数:

      >>> a = 1.0>>> int(a)1

      强制数据类型转换在某些情况下会丢失精度,在一些对精度要求比较高的环境下建议不要轻易使用强制数据类型转换!!


      Python 数字运算

      Python 解释器可以作为一个简单的计算器,您可以在解释器里输入一个表达式,它将输出表达式的值。

      表达式的语法很直白: +, -, */, 和其它语言(如Pascal或C)里一样。例如:

      >>> 2 + 24>>> 50 - 5*620>>> (50 - 5*6) / 45.0>>> 8 / 5  # 总是返回一个浮点数1.6

      注意:在不同的机器上浮点运算的结果可能会不一样。

      在整数除法中,除法 / 总是返回一个浮点数,如果只想得到整数的结果,丢弃可能的分数部分,可以使用运算符 //

      >>> 17 / 3  # 整数除法返回浮点型5.666666666666667>>>>>> 17 // 3  # 整数除法返回向下取整后的结果5>>> 17 % 3  # %操作符返回除法的余数2>>> 5 * 3 + 2 17

      注意:// 得到的并不一定是整数类型的数,它与分母分子的数据类型有关系。

      >>> 7//23>>> 7.0//23.0>>> 7//2.03.0>>> 

      等号 = 用于给变量赋值。赋值之后,除了下一个提示符,解释器不会显示任何结果。

      >>> width = 20>>> height = 5*9>>> width * height900

      Python 可以使用 ** 操作来进行幂运算:

      >>> 5 ** 2  # 5 的平方25>>> 2 ** 7  # 2的7次方128

      变量在使用前必须先"定义"(即赋予变量一个值),否则会出现错误:

      >>> n   # 尝试访问一个未定义的变量Traceback (most recent call last):  File "<stdin>", line 1, in <module>NameError: name 'n' is not defined

      不同类型的数混合运算时会将整数转换为浮点数:

      >>> 3 * 3.75 / 1.57.5>>> 7.0 / 23.5

      在交互模式中,最后被输出的表达式结果被赋值给变量 _ 。例如:

      >>> tax = 12.5 / 100>>> price = 100.50>>> price * tax12.5625>>> price + _113.0625>>> round(_, 2)113.06

      此处, _ 变量应被用户视为只读变量。


      数学函数

      函数返回值 ( 描述 )
      abs(x)返回数字的绝对值,如abs(-10) 返回 10
      ceil(x)返回数字的上入整数,如math.ceil(4.1) 返回 5

      cmp(x, y)

      如果 x < y 返回 -1, 如果 x == y 返回 0, 如果 x > y 返回 1。 Python 3 已废弃,使用 (x>y)-(x<y) 替换
      exp(x)返回e的x次幂(ex),如math.exp(1) 返回2.718281828459045
      fabs(x)返回数字的绝对值,如math.fabs(-10) 返回10.0
      floor(x)返回数字的下舍整数,如math.floor(4.9)返回 4
      log(x)如math.log(math.e)返回1.0,math.log(100,10)返回2.0
      log10(x)返回以10为基数的x的对数,如math.log10(100)返回 2.0
      max(x1, x2,...)返回给定参数的最大值,参数可以为序列。
      min(x1, x2,...)返回给定参数的最小值,参数可以为序列。
      modf(x)返回x的整数部分与小数部分,两部分的数值符号与x相同,整数部分以浮点型表示。
      pow(x, y)x**y 运算后的值。
      round(x [,n])

      返回浮点数 x 的四舍五入值,如给出 n 值,则代表舍入到小数点后的位数。

      其实准确的说是保留值将保留到离上一位更近的一端。

      sqrt(x)返回数字x的平方根。


      随机数函数

      随机数可以用于数学,游戏,安全等领域中,还经常被嵌入到算法中,用以提高算法效率,并提高程序的安全性。

      Python包含以下常用随机数函数:

      函数描述
      choice(seq)从序列的元素中随机挑选一个元素,比如random.choice(range(10)),从0到9中随机挑选一个整数。
      randrange ([start,] stop [,step])从指定范围内,按指定基数递增的集合中获取一个随机数,基数默认值为 1
      random()随机生成下一个实数,它在[0,1)范围内。
      seed([x])改变随机数生成器的种子seed。如果你不了解其原理,你不必特别去设定seed,Python会帮你选择seed。
      shuffle(lst)将序列的所有元素随机排序
      uniform(x, y)随机生成下一个实数,它在[x,y]范围内。


      三角函数

      Python包括以下三角函数:

      函数描述
      acos(x)返回x的反余弦弧度值。
      asin(x)返回x的反正弦弧度值。
      atan(x)返回x的反正切弧度值。
      atan2(y, x)返回给定的 X 及 Y 坐标值的反正切值。
      cos(x)返回x的弧度的余弦值。
      hypot(x, y)返回欧几里德范数 sqrt(x*x + y*y)。
      sin(x)返回的x弧度的正弦值。
      tan(x)返回x弧度的正切值。
      degrees(x)将弧度转换为角度,如degrees(math.pi/2) , 返回90.0
      radians(x)将角度转换为弧度


      数学常量

      常量描述
      pi数学常量 pi(圆周率,一般以π来表示)
      e数学常量 e,e即自然常数(自然常数)。



      在编程语言中,将以某种方式(比如通过编号)组合起来数据元素(如数字,字符串乃至其他数据结构)集合称为数据结构。在python中,最基本的数据结构为序列(sequence,简写为seq)

      所谓序列,指的是一块可存放多个值的连续内存空间,这些值按一定顺序排列,可通过每个值所在位置的编号(称为索引)访问它们。

      为了更形象的认识序列,可以将它看做是一家旅店,那么店中的每个房间就如同序列存储数据的一个个内存空间,每个房间所特有的房间号就相当于索引值。也就是说,通过房间号(索引)我们可以找到这家旅店(序列)中的每个房间(内存空间)。

      在 Python 中,​​序列类型包括字符串、列表、元组、集合和字典​​,这些序列支持以下几种通用的操作,但比较特殊的是,集合和字典不支持索引、切片、相加和相乘操作

      字符串也是一种常见的序列(所以以下的例子以字符串作为),它也可以直接通过索引访问字符串内的字符。

      序列索引

      序列中,每个元素都有属于自己的编号(索引)。从起始元素开始,索引值从 0 开始递增,如图 1 所示。

      序列索引值示意图

      除此之外,Python 还支持索引值是负数,此类索引是从右向左计数,换句话说,从最后一个元素开始计数,从索引值 -1 开始,如图 2 所示。

       负值索引示意图

      注意,在使用负值作为列序中各元素的索引值时,是从 -1 开始,而不是从 0 开始。

      另一种理解方式是:将序列想象成如下方的一个环:
      红色值为元素,绿色值为正索引,蓝色值为负索引
      可以发现序列的最后一个元素和第一个元素刚好相邻,方向与正索引的方向刚好相反,所以其负索引值是-1,。该序列有8个元素,所以最后一个负索引(也就是第一个元素)是-8,刚好等于该序列的长度的负值。

      无论是采用正索引值,还是负索引值,都可以访问序列中的任何元素。以字符串为例,访问“W3Cschool”的首元素和尾元素,可以使用如下的代码:

      str="W3Cschool"print(str[0],"==",str[-9])print(str[8],"==",str[-1])

      输出结果为:

      W == Wl == l

      序列切片

      切片操作是访问序列中元素的另一种方法,它可以访问一定范围内的元素,通过切片操作,可以生成一个新的序列。
      序列实现切片操作的语法格式如下:

      sname[start : end : step]

      其中,各个参数的含义分别是:

      • sname:表示序列的名称;
      • start:表示切片的开始索引位置(包括该位置),此参数也可以不指定,会默认为 0,也就是从序列的开头进行切片;
      • end:表示切片的结束索引位置(不包括该位置),如果不指定,则默认为序列的长度;
      • step:表示在切片过程中,隔几个存储位置(包含当前位置)取一次元素,也就是说,如果 step 的值大于 1,则在进行切片去序列元素时,会“跳跃式”的取元素。如果省略设置 step 的值,则最后一个冒号就可以省略。

      例如,对字符串“W3Cschool”进行切片:

      str="W3Cschool"#取索引区间为[0,2]之间(不包括索引2处的字符)的字符串print(str[:2])#隔 1 个字符取一个字符,区间是整个字符串print(str[::2])#取整个字符串,此时 [] 中只需一个冒号即可print(str[:])

      运行结果为:

      W3WCcolW3Cschool

      序列相加

      Python 中,支持两种类型相同的序列使用“+”运算符做相加操作,它会将两个序列进行连接,但不会去除重复的元素。

      这里所说的“类型相同”,指的是“+”运算符的两侧序列要么都是列表类型,要么都是元组类型,要么都是字符串。

      例如,前面章节中我们已经实现用“+”运算符连接 2 个(甚至多个)字符串,如下所示:

      protocol = "https://"url = "www.51coolma.cn"print(protocol+url)

      输出结果为:

      https://www.51coolma.cn

      序列相乘

      Python 中,使用数字 n 乘以一个序列会生成新的序列,其内容为原来序列被重复 n 次的结果。例如:

      str="W3Cschool"print(str*3)

      输出结果为:

      W3CschoolW3CschoolW3Cschool

      比较特殊的是,列表类型在进行乘法运算时,还可以实现初始化指定长度列表的功能。例如如下的代码,将创建一个长度为 5 的列表,列表中的每个元素都是 None,表示什么都没有。

      #列表的创建用 [],可以指定长度list = [None]*5print(list)

      输出结果为:

      [None, None, None, None, None]

      检查元素是否包含在序列中

      Python 中,可以使用 in 关键字检查某元素是否为序列的成员,其语法格式为:

      value in sequence​

      其中,value 表示要检查的元素,sequence 表示指定的序列。
      例如,检查字符‘C’是否包含在字符串“W3Cschool”中,可以执行如下代码:

      str="W3Cschool"print('C'in str)

      运行结果为:

      True

      和 in 关键字用法相同,但功能恰好相反的,还有 not in 关键字,它用来检查某个元素是否不包含在指定的序列中,比如说:

      str="W3Cschool"print('A' not in str)

      输出结果为:

      True

      和序列相关的内置函数

      Python提供了几个内置函数(表 3 所示),可用于实现与序列相关的一些常用操作。

      表 3 序列相关的内置函数
      函数功能
      len()计算序列的长度,即返回序列中包含多少个元素。
      max()找出序列中的最大元素。注意,对序列使用 sum() 函数时,做加和操作的必须都是数字,不能是字符或字符串,否则该函数将抛出异常,因为解释器无法判定是要做连接操作(+ 运算符可以连接两个序列),还是做加和操作。
      min()找出序列中的最小元素。
      list()将序列转换为列表。
      str()将序列转换为字符串。
      sum()计算元素和。
      sorted()对元素进行排序。
      reversed()反向序列中的元素。
      enumerate()将序列组合为一个索引序列,多用在 for 循环中。

       部分序列不能应用其中的部分函数,比如字典中不能直接使用list,详细的函数介绍请参阅相应数据类型的函数介绍。

      这里给大家给几个例子:

      str="W3Cschool"#找出最大的字符print(max(str))#找出最小的字符print(min(str))#对字符串中的元素进行排序print(sorted(str))

      输出结果为:

      s3['3', 'C', 'W', 'c', 'h', 'l', 'o', 'o', 's']


      列表(list)也是最常用的 Python 数据类型之一,它以一个方括号内包含多个其他数据项(字符串,数字等甚至是另一个列表),数据项间以逗号作为分隔的数据类型。

      列表的数据项不需要具有相同的类型。(这点是与其他语言的数组的一个区别)

      创建一个列表,只要把逗号分隔的不同的数据项使用方括号括起来即可。如下所示:

      list1 = ['Google', 'W3Cschool', 1997, 2000]list2 = [1, 2, 3, 4, 5, 6, 7 ]print ("list1: ", list1)print ("list2: ", list2)

      运行结果:

      list1:  ['Google', 'W3Cschool', 1997, 2000]list2:  [1, 2, 3, 4, 5, 6, 7]

      访问列表中的值

      与字符串的索引一样,列表索引从 0 开始,第二个索引是 1,依此类推。

      通过索引列表可以进行截取、组合等操作。

       该部分内容和字符串索引和切片内容具有很高的相似性(因为这些都是序列的基本操作),本章不做过多介绍,有需求的同学可以前往字符串章节进行回顾。

       索引
       负索引-4 -3 -2 -1
       值'Google' 'W3Cschool'1997 2000 

      以下是列表索引的操作:

      list1 = ['Google', 'W3Cschool', 1997, 2000]print ("list1的第一项: ", list1[0])print ("list1的最后一项: ", list1[-1])

      运行结果:

      list1的第一项:  Googlelist1的最后一项:  2000

      以下是列表切片的操作:

      list1 = ['Google', 'W3Cschool', 1997, 2000]print ("list1的前3项: ", list1[0:3])print ("list1的2、3项: ", list1[1:3])

      运行结果:

      list1的前3项:  ['Google', 'W3Cschool', 1997]list1的2、3项:  ['W3Cschool', 1997]

      更新列表

      你可以对列表的数据项进行修改或更新,你也可以使用 append() 方法来添加列表项,如下所示:

      list1 = ['Google', 'W3Cschool', 1997, 2000]print ("list1的第三个元素为: ", list1[2])list1[2] = "1998" #直接对想要修改的数据项赋上一个新值即可修改该数据项print ("list1的第三个元素为: ", list1[2])list1.append(2021) #append()可以在列表后追加一项列表项print ("追加列表项后的list1: ", list1)

      运行结果:

      list1的第三个元素为:  1997list1的第三个元素为:  1998追加列表项后的list1:  ['Google', 'W3Cschool', '1998', 2000, 2021]

      注意:我们会在接下来的章节讨论 append() 方法的使用。

      删除列表元素

      可以使用 del 语句来删除列表的的元素,如下实例:

      list1 = ['Google', 'W3Cschool', 1997, 2000]del list1[0] #del可以删掉一个元素print ("删除列表项后的list1: ", list1)

      运行结果:

      删除列表项后的list1:  ['W3Cschool', 1997, 2000]

      注意:使用del是删除删除一个变量的方法,所以使用del的时候要作用在变量上(也就是list[1])

      另一种删除的方式是使用remove来删除列表的元素,如下实例

      #!/usr/bin/python3list1 = ['Google', 'W3CSchool', 'Taobao', 'Baidu']list1.remove('Taobao') # remove可以按值查找列表中的元素并删除print ("列表现在为 : ", list1)list1.remove('Baidu')print ("列表现在为 : ", list1)

      运行结果

      列表现在为 :  ['Google', 'W3CSchool', 'Baidu']列表现在为 :  ['Google', 'W3CSchool']

      注意:我们会在接下来的章节讨论 remove() 方法的使用

      除此之外,pop也可以删除列表的最后一项。

      Python列表脚本操作符

      列表对 + 和 * 的操作符与字符串相似。+ 号用于组合列表,* 号用于重复列表。

      如下所示:

      Python 表达式结果描述
      len([1, 2, 3])3长度
      [1, 2, 3] + [4, 5, 6][1, 2, 3, 4, 5, 6]组合
      ['Hi!'] * 4['Hi!', 'Hi!', 'Hi!', 'Hi!']重复
      3 in [1, 2, 3]True元素是否存在于列表中
      for x in [1, 2, 3]: print(x, end=" ") 1 2 3迭代

      Python列表截取与拼接

      Python的列表截取与字符串操作类似,如下所示:

      L=['Google', 'W3Cschool', 'Taobao']

      操作:

      Python 表达式结果描述
      L[2]'Taobao'读取第三个元素
      L[-2]'W3Cschool'从右侧开始读取倒数第二个元素
      L[1:]['W3Cschool', 'Taobao']输出从第二个元素开始后的所有元素
      >>>L=['Google', 'W3Cschool', 'Taobao'] >>> L[2] 'Taobao' >>> L[-2] 'W3Cschool' >>> L[1:] ['W3Cschool', 'Taobao'] >>>

      列表还支持拼接操作:

      >>>squares = [1, 4, 9, 16, 25] >>> squares += [36, 49, 64, 81, 100] >>> squares [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] >>>

      嵌套列表

      使用嵌套列表即在列表里创建其它列表,例如:

      >>>a = ['a', 'b', 'c'] >>> n = [1, 2, 3] >>> x = [a, n] >>> x [['a', 'b', 'c'], [1, 2, 3]] >>> x[0] ['a', 'b', 'c'] >>> x[0][1] 'b'

      如果有其他语言的基础,会发现嵌套列表的使用和数据结构和多维数组很像。实际上,python的列表可以当做其他语言的数组使用!

      Python列表函数&方法

      Python列表包含以下函数:

      序号函数
      1len(list)
      列表元素个数
      2max(list)
      返回列表元素最大值
      3min(list)
      返回列表元素最小值
      4list(seq)
      将序列(元组,集合等)转换为列表

      Python列表包含以下方法:

      序号方法
      1list.append(obj)
      在列表末尾添加新的对象
      2list.count(obj)
      统计某个元素在列表中出现的次数
      3list.extend(seq)
      在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
      4list.index(obj)
      从列表中找出某个值第一个匹配项的索引位置
      5list.insert(index, obj)
      在列表的index的地方插入一个对象
      6list.pop([index=-1])
      移除列表中的一个元素(默认最后一个元素),并且返回该元素的值
      7list.remove(obj)
      移除列表中某个值的第一个匹配项
      8list.reverse()
      反向排列列表中元素
      9list.sort( key=None, reverse=False)
      对原列表进行排序
      10list.clear()
      清空列表
      11list.copy()
      复制列表


      Python 的元组(tuple,简写为tup)与列表类似,不同之处在于元组的元素不能修改。

      元组使用小括号​()​,列表使用方括号​[]​。

      元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。

      如下实例:

      tup1 = ('Google', 'W3CSchool', 1997, 2020)tup2 = (1, 2, 3, 4, 5 )tup3 = "a", "b", "c", "d" # 不需括号也可以print(type(tup3))

      运行结果:

      <class 'tuple'>

      创建空元组

      tup1 = ()

      元组中只包含一个元素时,需要在元素后面添加逗号,否则括号会被当做运算符使用。

      tup1 = (50,)

      元组与字符串类似,下标索引从 0 开始,可以进行截取,组合等。

       正索引
       值 GoogleW3Cschool 1997 2020 
       负索引-4 -3 -2 -1 



      访问元组

      元组可以使用下标索引来访问元组中的值,如下实例:

      #!/usr/bin/python3tup1 = ('Google', 'W3CSchool', 1997, 2020)tup2 = (1, 2, 3, 4, 5, 6, 7 )print ("tup1[0]: ", tup1[0])print ("tup2[1:5]: ", tup2[1:5])

      以上实例输出结果:

      tup1[0]:  Googletup2[1:5]:  (2, 3, 4, 5)

      修改元组

      元组中的元素值是不允许修改的,但我们可以对元组进行连接组合,如下实例:

      #!/usr/bin/python3tup1 = (12, 34.56);tup2 = ('abc', 'xyz')# 以下修改元组元素操作是非法的。# tup1[0] = 100# 创建一个新的元组tup3 = tup1 + tup2;print (tup3)

      以上实例输出结果:

      (12, 34.56, 'abc', 'xyz')

      删除元组

      元组中的元素值是不允许删除的,但我们可以使用del语句来删除整个元组,如下实例:

      #!/usr/bin/python3tup = ('Google', 'W3CSchool', 1997, 2020)print (tup)del tup;print ("删除后的元组 tup : ")print (tup)

      以上实例元组被删除后,输出变量会有异常信息,输出如下所示:

      删除后的元组 tup : Traceback (most recent call last):  File "test.py", line 8, in <module>    print (tup)NameError: name 'tup' is not defined

      元组运算符

      与字符串一样,元组之间可以使用 + 号和 * 号进行运算。这就意味着他们可以组合和复制,运算后会生成一个新的元组。

      Python 表达式结果描述
      len((1, 2, 3))3计算元素个数
      (1, 2, 3) + (4, 5, 6)(1, 2, 3, 4, 5, 6)连接
      ('Hi!',) * 4('Hi!', 'Hi!', 'Hi!', 'Hi!')复制
      3 in (1, 2, 3)True元素是否存在
      for x in (1, 2, 3): print x,1 2 3迭代

      元组索引,截取

      因为元组也是一个序列,所以我们可以访问元组中的指定位置的元素,也可以截取索引中的一段元素,如下所示:

      元组:

      L = ('Google', 'Taobao', 'W3CSchool')
      Python 表达式结果描述
      L[2]'W3CSchool'读取第三个元素
      L[-2]'Taobao'反向读取;读取倒数第二个元素
      L[1:]('Taobao', 'W3CSchool')截取元素,从第二个开始后的所有元素。

      运行实例如下:

      >>> L = ('Google', 'Taobao', 'W3CSchool')>>> L[2]'W3CSchool'>>> L[-2]'Taobao'>>> L[1:]('Taobao', 'W3CSchool')

      元组内置函数

      Python 元组包含了以下内置函数

      序号方法及描述实例
      1len(tuple)
      计算元组元素个数。
      >>> tuple1 = ('Google', 'W3CSchool', 'Taobao')>>> len(tuple1)3>>> 
      2max(tuple)
      返回元组中元素最大值。
      >>> tuple2 = ('5', '4', '8')>>> max(tuple2)'8'>>> 
      3min(tuple)
      返回元组中元素最小值。
      >>> tuple2 = ('5', '4', '8')>>> min(tuple2)'4'>>> 
      4
      tuple(seq)
      将列表转换为元组。
      >>> list1= ['Google', 'Taobao', 'W3CSchool', 'Baidu']>>> tuple1=tuple(list1)>>> tuple1('Google', 'Taobao', 'W3CSchool', 'Baidu')
      5operator(tuple1,tuple2)
      较两个元组元素
      >>> import operator>>> dict1 = (1, 2, 3)>>> dict2 = ('a', 'b', 'c')>>> operator.eq(dict1, dict2)False

      关于元组是不可变的

      所谓元组的不可变指的是元组所指向的内存中的内容不可变。

      >>> tup = ('W', '3', 'C', 's', 'c', 'h','o','o','l')>>> tup[0] = 'w'     # 不支持修改元素Traceback (most recent call last):  File "<stdin>", line 1, in <module>TypeError: 'tuple' object does not support item assignment>>> id(tup)     # 查看内存地址4440687904>>> tup = (1,2,3)>>> id(tup)4441088800    # 内存地址不一样了

      从以上实例可以看出,重新赋值的元组 tup,绑定到新的对象了,不是修改了原来的对象。


      在Python3中字典(dictionary ,简写为dict)是另一种可变容器模型,且可存储任意类型对象。

      字典的每个键值 (​key=>value​) 对用冒号 (:) 分割,每个对之间用逗号 (,) 分割,整个字典包括在花括号 ({}​) 中 ,格式如下所示:

      d = {key1 : value1, key2 : value2 }
       key(键)value(值) 
       'Alice''2341' 
       'Beth''9102' 
       'Cecil''3258' 
       'Danna''2341' 
       'Steven''5643' 

      键必须是唯一的,但值则不必(上表中Danna和Alice的键是不同的,值却是相同的)。

      值可以取任何数据类型,但​键必须是不可变的​,如字符串,数字或元组。

      一个简单的字典实例:

      dict = {'Alice': '2341', 'Beth': '9102', 'Cecil': '3258'}

      也可如此创建字典:

      dict1 = { 'abc': 456 }dict2 = { 'abc': 123, 98.6: 37 }

      访问字典里的值

      与列表取值类似,但列表取值时使用索引,字典取值时使用key,如下实例:

      #!/usr/bin/python3dict = {'Name': 'W3CSchool', 'Age': 7, 'Class': 'First'}print ("dict['Name']: ", dict['Name'])print ("dict['Age']: ", dict['Age'])

      以上实例输出结果:

      dict['Name']:  W3CSchooldict['Age']:  7

      如果用字典里没有的键访问数据,会输出错误如下:

      #!/usr/bin/python3 dict = {'Name': 'W3CSchool', 'Age': 7, 'Class': 'First'} print ("dict['Alice']: ", dict['Alice'])

      以上实例输出结果:

      Traceback (most recent call last):  File "test.py", line 5, in <module>    print ("dict['Alice']: ", dict['Alice'])KeyError: 'Alice'

      修改字典

      向字典添加新内容的方法是增加新的键/值对,修改或删除已有键/值对如下实例:

      #!/usr/bin/python3dict = {'Name': 'W3CSchool', 'Age': 7, 'Class': 'First'}dict['Age'] = 8;               # 更新 Agedict['School'] = "W3Cschool教程"  # 添加信息print ("dict['Age']: ", dict['Age'])print ("dict['School']: ", dict['School'])
      以上实例输出结果:
      dict['Age']:  8dict['School']:  W3Cschool教程

      删除字典元素

      del ​能删单一的元素也能清空字典。我们可以用它来删除字典中的一组键值对也可以用来删除整个字典。另外使用clear()也能删除字典。如下实例:

      #!/usr/bin/python3dict = {'Name': 'W3CSchool', 'Age': 7, 'Class': 'First'}del dict['Name'] # 删除键 'Name'dict.clear()     # 删除字典del dict         # 删除字典print ("dict['Age']: ", dict['Age'])print ("dict['School']: ", dict['School'])

      但这会引发一个异常,因为用执行 del 操作后字典不再存在:

      Traceback (most recent call last):  File "test.py", line 9, in <module>    print ("dict['Age']: ", dict['Age'])TypeError: 'type' object is not subscriptable

      注:clear() 方法后面也会讨论。

      字典键的特性

      字典值可以没有限制地取任何 Python 对象,既可以是标准的对象,也可以是用户定义的,但键不行。

      两个重要的点需要记住:

      1)不允许同一个键出现两次。创建时如果同一个键被赋值两次,后一个值会被记住,如下实例:

      #!/usr/bin/python3dict = {'Name': 'W3CSchool', 'Age': 7, 'Name': '编程狮'}print ("dict['Name']: ", dict['Name'])

      以上实例输出结果:

      dict['Name']:  编程狮

      2)键必须不可变,所以可以用数字,字符串或元组充当,而用列表就不行,如下实例:

      #!/usr/bin/python3dict = {['Name']: 'W3CSchool', 'Age': 7}print ("dict['Name']: ", dict['Name'])

      以上实例输出结果:

      Traceback (most recent call last):  File "test.py", line 3, in <module>    dict = {['Name']: 'W3CSchool', 'Age': 7}TypeError: unhashable type: 'list'

      字典内置函数&方法

      Python 字典包含了以下内置函数:

      序号函数及描述实例
      1len(dict)
      计算字典元素个数,即键的总数。
      >>> dict = {'Name': 'W3CSchool', 'Age': 7, 'Class': 'First'}>>> len(dict)3
      2str(dict)
      以可打印的字符串输出字典。
      >>> dict = {'Name': 'W3CSchool', 'Age': 7, 'Class': 'First'}>>> str(dict)"{'Name': 'W3CSchool', 'Class': 'First', 'Age': 7}"
      3type(variable)
      返回输入的变量类型,如果变量是字典就返回字典类型。
      >>> dict = {'Name': 'W3CSchool', 'Age': 7, 'Class': 'First'}>>> type(dict)<class 'dict'>

      Python 字典包含了以下内置方法:

      序号函数及描述
      1radiansdict.clear()
      删除字典内所有元素
      2radiansdict.copy()
      返回一个字典的浅复制
      3radiansdict.fromkeys()
      创建一个新字典,以序列seq中元素做字典的键,val为字典所有键对应的初始值
      4radiansdict.get(key, default=None)
      返回指定键的值,如果值不在字典中返回default值
      5key in dict
      如果键在字典dict里返回true,否则返回false
      6radiansdict.items()
      以列表返回可遍历的(键, 值) 元组数组
      7radiansdict.keys()
      以列表返回一个字典所有的键
      8radiansdict.setdefault(key, default=None)
      和get()类似, 但如果键不存在于字典中,将会添加键并将值设为default
      9radiansdict.update(dict2)
      把字典dict2的键/值对更新到dict里
      10radiansdict.values()
      以列表返回字典中的所有值


      集合(set)是一个无序的不重复元素序列。因此在每次运行的时候集合的运行结果的内容都是相同的,但元素的排列顺序却不是固定的,所以本章中部分案例的运行结果会出现与给出结果不同的情况(运行结果不唯一)。

      可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。

      创建格式:

      parame = {value01,value02,...}或者set(value)

      集合实例:

      basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}print(basket)  # 这里演示的是去重功能print('orange' in basket)                 # 快速判断元素是否在集合内print('crabgrass' in basket)

      运行结果:

      {'pear', 'banana', 'orange', 'apple'}TrueFalse

      集合的运算:

      a = set('abracadabra')b = set('alacazam')print(a)print(b)print(a-b)print(a|b)print(a&b)print(a^b)

      运行结果:

      {'b', 'd', 'a', 'c', 'r'}{'l', 'z', 'm', 'a', 'c'}{'r', 'd', 'b'}{'l', 'z', 'b', 'm', 'd', 'a', 'c', 'r'}{'c', 'a'}{'l', 'z', 'b', 'm', 'r', 'd'}
       a-b(a集合中b没有的元素) b     
       集合a b a   
       a|b(并集) b a
       集合b    a l
       a&b(交集)    a   
       a^b(不同时包含于a和b的元素)  

      类似列表推导式,同样集合支持集合推导式(Set comprehension):

      >>> a = {x for x in 'abracadabra' if x not in 'abc'}>>> a{'r', 'd'}

      集合的基本操作

      1、添加元素

      语法格式如下:

      s.add( x )

      将元素 x 添加到集合 s 中,如果元素已存在,则不进行任何操作。

      thisset = set(("Google", "W3Cschool", "Taobao"))thisset.add("Baidu")print(thisset)

      运行结果:

      {'W3Cschool', 'Taobao', 'Google', 'Baidu'}

      还有一个方法,也可以添加元素,且参数可以是列表,元组,字典等,语法格式如下:

      s.update( x )

      x 可以有多个,用逗号分开。

      实例:

      thisset = set(("Google", "w3Cschool", "Taobao"))thisset.update({1,3})print(thisset)thisset.update([1,4],[5,6])  print(thisset)
      运行结果:
      {1, 3, 'w3Cschool', 'Taobao', 'Google'}{1, 3, 4, 5, 6, 'w3Cschool', 'Taobao', 'Google'}

      2、移除元素

      语法格式如下:

      s.remove( x )

      将元素 x 从集合 s 中移除,如果元素不存在,则会发生错误。

      实例:

      thisset = set(("Google", "W3Cschool", "Taobao"))thisset.remove("Taobao")print(thisset)thisset.remove("Facebook")   # 不存在会发生错误

      运行结果:

      {'W3Cschool', 'Google'}Traceback (most recent call last):  File ".code.tio", line 5, in     thisset.remove("Facebook")   # 不存在会发生错误KeyError: 'Facebook'

      此外还有一个方法也是移除集合中的元素,且如果元素不存在,不会发生错误。格式如下所示:

      s.discard( x )

      实例:

      thisset = set(("Google", "W3Cschool", "Taobao"))thisset.discard("Facebook")  # 不存在不会发生错误print(thisset)

      运行结果:

      {'Taobao', 'Google', 'W3Cschool'}

      我们也可以设置随机删除集合中的一个元素,语法格式如下:

      s.pop() 

      实例:

      thisset = set(("Google", "W3Cschool", "Taobao", "Facebook"))x = thisset.pop()print(x)print(thisset)

      输出结果:

      Google{'Facebook', 'Taobao', 'W3Cschool'}

      多次执行测试结果都不一样。

      set 集合的 pop 方法会对集合进行无序的排列,然后将这个无序排列集合的左面第一个元素进行删除。因为这个过程是不确定的,所以删除结果也是不确定的,不建议使用这种方式进行删除。

      3、计算集合元素个数

      语法格式如下:

      len(s)

      计算集合 s 的元素个数。

      实例:

      thisset = set(("Google", "W3Cschool", "Taobao"))print(len(thisset))

      运行结果:

      3

      4、清空集合

      语法格式如下:

      s.clear()

      清空集合 s。

      实例

      thisset = set(("Google", "W3cschool", "Taobao"))thisset.clear()print(thisset)

      运行结果:

      set()

      5、判断元素是否在集合中存在

      语法格式如下:

      x in s

      判断元素 x 是否在集合 s 中,存在则返回 True,不存在则返回 False。

      实例:

      thisset = set(("Google", "W3Cschool", "Taobao"))print("W3Cschool" in thisset)print("Facebook" in thisset)

      运行结果:

      TrueFalse

      集合内置方法完整列表

      方法描述
      add()为集合添加元素
      clear()移除集合中的所有元素
      copy()拷贝一个集合
      difference()返回多个集合的差集
      difference_update()移除集合中的元素,该元素在指定的集合也存在。
      discard()删除集合中指定的元素
      intersection()返回集合的交集
      intersection_update()返回集合的交集。
      isdisjoint()判断两个集合是否包含相同的元素,如果没有返回 True,否则返回 False。
      issubset()判断指定集合是否为该方法参数集合的子集。
      issuperset()判断该方法的参数集合是否为指定集合的子集
      pop()随机移除元素
      remove()移除指定元素
      symmetric_difference()返回两个集合中不重复的元素集合。
      symmetric_difference_update()移除当前集合中在另外一个指定集合相同的元素,并将另外一个指定集合中不同的元素插入到当前集合中。
      union()返回两个集合的并集
      update()给集合添加元素


      if语句

      Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块。


      Python 中 if 语句的一般形式如下所示:

      if condition_1:    statement_block_1

      流程图如下所示:


      这种if语句只有在符合条件的时候才会执行代码块内的代码,是一种比较常见的用法。

      另一种常见的用法是:

      if condition_1:    statement_block_1else:    statement_block_2

      流程图如下所示:


      这种语句是一种常用的if-else语句,通常用于二分支结构的条件语句代码。

      在一些时候,我们可能需要多分支的条件语句代码,可以在if-else语句中混合elif语句进行使用:

      Python 中用 elif 代替了else if,所以if语句的关键字为:if – elif – else。

      if condition_1:    statement_block_1elif condition_2:    statement_block_2else:    statement_block_3

      流程图如下所示:


      如果 "condition_1" 为 True 将执行 "statement_block_1" 块语句,如果 "condition_1" 为 False,将判断 "condition_2",如果"condition_2" 为 True 将执行 "statement_block_2" 块语句,如果 "condition_2" 为 False,将执行"statement_block_3"块语句。

       使用第一种常用的if语句搭配合适的条件可以实现第二种和第三种语句的全部效果,但在执行效率和代码可读性上会变得比较糟糕。

      注意:

      • 1、每个条件后面要使用冒号(:),表示接下来是满足条件后要执行的语句块。
      • 2、使用缩进来划分语句块,相同缩进数的语句在一起组成一个语句块。
      • 3、在 Python 中没有 switch – case 语句,但在python3.10中添加了用法类似的match-case语句。

      match-case语句(python3.10新特性)

      在其他语言(比如说经典的C语言)中有一种多分支条件判断语句,可以进行模式匹配(通俗的讲,就是将传入的内容跟多个已存在的样例进行比较,找到相同的案例并按照该案例的代码进行处理,如果没有相同案例就按默认案例进行处理,可以查看其他编程语言的条件语句的Switch相关部分内容进行比较参考)。在python3.10中也引入了这样的新特性。

      match-case语句的结构一般如下所示:

      match variable: #这里的variable是需要判断的内容    case ["quit"]:         statement_block_1 # 对应案例的执行代码,当variable="quit"时执行statement_block_1    case ["go", direction]:         statement_block_2    case ["drop", *objects]:         statement_block_3    ... # 其他的case语句    case _: #如果上面的case语句没有命中,则执行这个代码块,类似于Switch的default        statement_block_default

      一个match语句的使用示例:

      def http_error(status):    match status:        case 400:            return "Bad request"        case 404:            return "Not found"        case 418:            return "I'm a teapot"        case _:            return "Something's wrong with the Internet"

       上述代码等价于:

      def http_error(status):    if status == 400:        return "Bad request"    elif status == 404:        return "Not found"    elif status == 418:        return "I'm a teapot"    else:        return "Something's wrong with the Internet"

      关于模式匹配还有更多的用法,可以参考PEP636进行详细的学习。

      实例

      以下实例演示了狗的年龄计算判断:

      age = int(input("Age of the dog: "))print()if age < 0:      print("This can hardly be true!") elif age == 1:      print("about 14 human years") elif age == 2:      print("about 22 human years") elif age > 2:    human = 22 + (age -2)*5    print("Human years: ", human)### input('press Return>')

      将以上脚本保存在 dog.py 文件中,并执行该脚本:

      python dog.pyAge of the dog: 1about 14 human years

      以下为 if 中常用的操作运算符:

      操作符 描述
      < 小于
      <= 小于或等于
      > 大于
      >= 大于或等于
      == 等于,比较对象是否相等
      != 不等于

       只要返回结果为布尔型(true或者false)的,都可以作为if的条件,所以在之前的集合等内容中涉及到的判断元素是否在集合中的​in​和​not in​,都可以作为if的条件。

      实例

      # 程序演示了 == 操作符# 使用数字print(5 == 6)# 使用变量x = 5y = 8print(x == y)

      以上实例输出结果:

      FalseFalse

      使用​in​和​not in​作为判断条件:

      thisset = set(("Google", "W3Cschool", "Taobao"))if "W3Cschool" in thisset:    print("该元素在列表中")if "baidu" not in thisset:    print("该元素不在列表中")

      运行结果如下:

      该元素在列表中该元素不在列表中

      以下示例使用if语句来实现一个猜数字游戏(建议在本地环境尝试):

      #!/usr/bin/python3 # 该实例演示了数字猜谜游戏number = 7guess = -1print("猜数字!")while guess != number:    guess = int(input("请输入你要猜的数字"))    if guess == number:        print("你猜中了,真厉害!")    elif guess < number:        print("猜小了,再猜猜?")    elif guess > number:        print("猜大了,在猜猜?")


      本章节将为大家介绍 Python 循环语句的使用。

      Python 中的循环语句有 for 和 while。

      Python 循环语句的控制结构图如下所示:


      while 循环

      Python 中 while 语句的一般形式:

      while 判断条件:    statements

      同样需要注意冒号和缩进。另外,在Python中没有 do-while 循环。

      以下实例使用了 while 来计算 1 到 100 的总和:

      #!/usr/bin/env python3n = 100sum = 0counter = 1while counter <= n:    sum = sum + counter         counter += 1  print('Sum of 1 until %d: %d' % (n,sum)) 

      执行结果如下:

      Sum of 1 until 100: 5050

      for 语句

      Python for 循环可以遍历任何序列的项目,如一个列表或者一个字符串。

      for 循环的一般格式如下:

      for <variable> in <sequence>:  <statements>else: <statements>

      Python for循环实例:

      >>> languages = ["C", "C++", "Perl", "Python"] >>> for x in languages:...     print (x)... CC++PerlPython>>> 

      以下 for 实例中使用了 break 语句,break 语句用于跳出当前循环体:

      #!/usr/bin/env python3edibles = ["ham", "spam","eggs","nuts"]for food in edibles:    if food == "spam":        print("No more spam please!")        break    print("Great, delicious " + food)else:    print("I am so glad: No spam!")print("Finally, I finished stuffing myself")

      执行脚本后,在循环到 "spam"时会跳出循环体:

      Great, delicious hamNo more spam please!Finally, I finished stuffing myself

      range()函数

      如果你需要遍历数字序列,可以使用内置 range() 函数。它会生成数列,例如:

      >>> for i in range(5):...     print(i)...01234

      你也可以使用 range 指定区间的值:

      >>> for i in range(5,9) :  print(i)    5678>>>

      也可以使 range 以指定数字开始并指定不同的增量(甚至可以是负数;有时这也叫做'步长'):

      >>> for i in range(0, 10, 3) :    print(i)    0369>>> 

      负数:

      >>> for i in range(-10, -100, -30) :   print(i)    -10-40-70>>> 

      您可以结合 range() 和 len() 函数以遍历一个序列的索引,如下所示:

      >>> a = ['Mary', 'had', 'a', 'little', 'lamb']>>> for i in range(len(a)):...     print(i, a[i])...0 Mary1 had2 a3 little4 lamb

      还可以使用 range() 函数来创建一个列表:

      >>> list(range(5))[0, 1, 2, 3, 4]>>>

      break 和 continue 语句及循环中的 else 子句

      break 语句可以跳出 for 和 while 的循环体。如果你从 for 或 while 循环中终止,任何对应的循环 else 块将不执行。

      continue 语句被用来告诉 Python 跳过当前循环中的当此循环,然后继续进行下一轮循环。

      循环语句可以有 else 子句;它在穷尽列表(以 for 循环)或条件变为假(以 while 循环)循环终止时被执行,但循环被 break 终止时不执行,如下查寻质数的循环例子:

      >>> for n in range(2, 10):...     for x in range(2, n):...         if n % x == 0:...             print(n, 'equals', x, '*', n//x)...             break...     else:...         # 循环中没有找到元素...         print(n, 'is a prime number')...2 is a prime number3 is a prime number4 equals 2 * 25 is a prime number6 equals 2 * 37 is a prime number8 equals 2 * 49 equals 3 * 3

      pass 语句

      pass 语句什么都不做。它只在语法上需要一条语句但程序不需要任何操作时使用。例如:

      >>> while True:...     pass  # 等待键盘中断 (Ctrl+C)

      最小的类:

      >>> class MyEmptyClass:...     pass


      迭代器

      迭代是 Python 最强大的功能之一,是访问集合元素的一种方式。。

      迭代器是一个可以记住遍历的位置的对象。

      迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

      迭代器有两个基本的方法:iter()next()

      字符串,列表或元组对象都可用于创建迭代器:

      >>> list=[1,2,3,4]>>> it = iter(list)    # 创建迭代器对象>>> print (next(it))   # 输出迭代器的下一个元素1>>> print (next(it))2>>> 

      迭代器对象可以使用常规 for 语句进行遍历:

      #!/usr/bin/python3list=[1,2,3,4]it = iter(list)    # 创建迭代器对象for x in it:    print (x, end=" ")

      执行以上程序,输出结果如下:

      1 2 3 4

      也可以使用 next() 函数:

      #!/usr/bin/python3import sys         # 引入 sys 模块list=[1,2,3,4]it = iter(list)    # 创建迭代器对象while True:    try:        print (next(it))    except StopIteration:        sys.exit()

      执行以上程序,输出结果如下:

      1234

      生成器

      在 Python 中,使用了 yield 的函数被称为生成器(generator)。

      跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。

      在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值。并在下一次执行 next() 方法时从当前位置继续运行。

      以下实例使用 yield 实现斐波那契数列:

      #!/usr/bin/python3import sysdef fibonacci(n): # 生成器函数 - 斐波那契    a, b, counter = 0, 1, 0    while True:        if (counter > n):             return        yield a        a, b = b, a + b        counter += 1f = fibonacci(10) # f 是一个迭代器,由生成器返回生成while True:    try:        print (next(f), end=" ")    except StopIteration:        sys.exit()

      执行以上程序,输出结果如下:

      0 1 1 2 3 5 8 13 21 34 55

      Python sys 模块介绍

      在 Python 的 sys 模块提供访问解释器使用或维护的变量,和与解释器进行交互的函数。

      通俗来讲,sys 模块负责程序与 Python 解释器的交互,提供了一系列的函数和变量,用于操控 Python 运行时的环境。

      本章节我们将为大家介绍 Python 中函数的应用。

      该章节可参阅 Python 函数应用详解

      Python 定义函数使用 def 关键字,一般格式如下:

      def  函数名(参数列表):    函数体

      让我们使用函数来输出"Hello World!":

      >>> def hello() :  print("Hello World!") >>> hello()Hello World!>>> 

      更复杂点的应用,函数中带上参数变量:

      def area(width, height):    return width * height def print_welcome(name):    print("Welcome", name)print_welcome("Fred")w = 4h = 5print("width =", w, " height =", h, " area =", area(w, h))

      以上实例输出结果:

      Welcome Fredwidth = 4  height = 5  area = 20

      函数变量作用域

      定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。

      通过以下实例,你可以清楚了解 Python 函数变量的作用域:

      #!/usr/bin/env python3a = 4  # 全局变量 def print_func1():    a = 17 # 局部变量    print("in print_func a = ", a)def print_func2():       print("in print_func a = ", a)print_func1()print_func2()print("a = ", a) 

      以上实例运行结果如下:

      in print_func a =  17in print_func a =  4a =  4

      关键字参数

      函数也可以使用 kwarg = value 的关键字参数形式被调用。例如,以下函数:

      def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):    print("-- This parrot wouldn't", action, end=' ')    print("if you put", voltage, "volts through it.")    print("-- Lovely plumage, the", type)    print("-- It's", state, "!")

      可以以下几种方式被调用:

      parrot(1000)                                          # 1 positional argumentparrot(voltage=1000)                                  # 1 keyword argumentparrot(voltage=1000000, action='VOOOOOM')             # 2 keyword argumentsparrot(action='VOOOOOM', voltage=1000000)             # 2 keyword argumentsparrot('a million', 'bereft of life', 'jump')         # 3 positional argumentsparrot('a thousand', state='pushing up the daisies')  # 1 positional, 1 keyword

      以下为错误调用方法:

      parrot()                     # required argument missingparrot(voltage=5.0, 'dead')  # non-keyword argument after a keyword argumentparrot(110, voltage=220)     # duplicate value for the same argumentparrot(actor='John Cleese')  # unknown keyword argument

      返回值

      Python 函数使用 return 语句返回函数值,可以将函数作为一个值赋值给指定变量:

      def return_sum(x,y):    c = x + y    return cres = return_sum(4,5)print(res)

      你也可以让函数返回空值:

      def empty_return(x,y):    c = x + y    returnres = empty_return(4,5)print(res)

      可变参数列表

      最后,一个较不常用的功能是可以让函数调用可变个数的参数。

      这些参数被包装进一个元组(查看元组和序列)。

      在这些可变个数的参数之前,可以有零到多个普通的参数:

      def arithmetic_mean(*args):    if len(args) == 0:        return 0    else:        sum = 0        for x in args:            sum += x        return sum/len(args)print(arithmetic_mean(45,32,89,78))print(arithmetic_mean(8989.8,78787.78,3453,78778.73))print(arithmetic_mean(45,32))print(arithmetic_mean(45))print(arithmetic_mean())

      以上实例输出结果为:

      61.042502.327538.545.00

      更详细教程请参阅参阅Python 函数应用详解


      本章节我们主要结合前面所学的知识点来介绍 Python 数据结构。


      列表

      Python 中列表是可变的,这是它区别于字符串和元组的最重要的特点,一句话概括即:列表可以修改,而字符串和元组不能修改。

      以下是 Python 中列表的方法:

      方法描述
      list.append(x)把一个元素添加到列表的结尾,相当于 a[len(a):] = [x]。
      list.extend(L)通过添加指定列表的所有元素来扩充列表,相当于 a[len(a):] = L。
      list.insert(i, x)在指定位置插入一个元素。第一个参数是准备插入到其前面的那个元素的索引,例如 a.insert(0, x) 会插入到整个列表之前,而 a.insert(len(a), x) 相当于 a.append(x) 。
      list.remove(x)删除列表中值为 x 的第一个元素。如果没有这样的元素,就会返回一个错误。
      list.pop([i])从列表的指定位置删除元素,并将其返回。如果没有指定索引,a.pop()返回最后一个元素。元素随即从列表中被删除。(方法中 i 两边的方括号表示这个参数是可选的,而不是要求你输入一对方括号,你会经常在 Python 库参考手册中遇到这样的标记。)
      list.clear()移除列表中的所有项,等于del a[:]。
      list.index(x)返回列表中第一个值为 x 的元素的索引。如果没有匹配的元素就会返回一个错误。
      list.count(x)返回 x 在列表中出现的次数。
      list.sort()对列表中的元素进行排序。
      list.reverse()倒排列表中的元素。
      list.copy()返回列表的浅复制,等于a[:]。

      下面示例演示了列表的大部分方法:

      >>> a = [66.25, 333, 333, 1, 1234.5]>>> print(a.count(333), a.count(66.25), a.count('x'))2 1 0>>> a.insert(2, -1)>>> a.append(333)>>> a[66.25, 333, -1, 333, 1, 1234.5, 333]>>> a.index(333)1>>> a.remove(333)>>> a[66.25, -1, 333, 1, 1234.5, 333]>>> a.reverse()>>> a[333, 1234.5, 1, 333, -1, 66.25]>>> a.sort()>>> a[-1, 1, 66.25, 333, 333, 1234.5]

      注意:类似 insert, remove 或 sort 等修改列表的方法没有返回值。


      将列表当做堆栈使用

      列表的方法使得列表可以很方便的作为一个堆栈来使用,堆栈作为特定的数据结构,最先进入的元素会最后一个被释放(后进先出)。用 append() 方法可以把一个元素添加到堆栈顶。用不指定索引的 pop() 方法可以把一个元素从堆栈顶释放出来。例如:

      >>> stack = [3, 4, 5]>>> stack.append(6)>>> stack.append(7)>>> stack[3, 4, 5, 6, 7]>>> stack.pop()7>>> stack[3, 4, 5, 6]>>> stack.pop()6>>> stack.pop()5>>> stack[3, 4]

      将列表当作队列使用

      也可以把列表当做队列用,在队列里第一个位置加入的元素,第一个取出来;但是拿列表用作队列效率不高。在列表的最后添加或者弹出元素速度快,然而在列表里插入或者从头部弹出速度却不快(因为所有其他的元素都得一个一个地移动)。

      >>> from collections import deque>>> queue = deque(["Eric", "John", "Michael"])>>> queue.append("Terry")           # Terry arrives>>> queue.append("Graham")          # Graham arrives>>> queue.popleft()                 # The first to arrive now leaves'Eric'>>> queue.popleft()                 # The second to arrive now leaves'John'>>> queue                           # Remaining queue in order of arrivaldeque(['Michael', 'Terry', 'Graham'])

      列表推导式

      列表推导式提供了从序列创建列表的简单途径。通常应用程序将一些操作应用于某个序列的每个元素,用其获得的结果作为生成新列表的元素,或者根据确定的判定条件创建子序列。

      每个列表推导式都在 for 之后跟一个表达式,然后有零到多个 for 或 if 子句。返回结果是一个根据表达从其后的 for 和 if 上下文环境中生成出来的列表。如果希望表达式推导出一个元组,就必须使用括号。

      这里我们将列表中每个数值乘三,获得一个新的列表:

      >>> vec = [2, 4, 6]>>> [3*x for x in vec][6, 12, 18]

      现在我们玩一点小花样:

      >>> [[x, x**2] for x in vec][[2, 4], [4, 16], [6, 36]]

      这里我们对序列里每一个元素逐个调用某方法:

      >>> freshfruit = ['  banana', '  loganberry ', 'passion fruit  ']>>> [weapon.strip() for weapon in freshfruit]['banana', 'loganberry', 'passion fruit']

      我们可以用 if 子句作为过滤器:

      >>> [3*x for x in vec if x > 3][12, 18]>>> [3*x for x in vec if x < 2] [] 

      以下是一些关于循环和其它技巧的演示:

      >>> vec1 = [2, 4, 6]>>> vec2 = [4, 3, -9]>>> [x*y for x in vec1 for y in vec2][8, 6, -18, 16, 12, -36, 24, 18, -54]>>> [x+y for x in vec1 for y in vec2][6, 5, -7, 8, 7, -5, 10, 9, -3]>>> [vec1[i]*vec2[i] for i in range(len(vec1))][8, 12, -54]

      列表推导式可以使用复杂表达式或嵌套函数:

      >>> [str(round(355/113, i)) for i in range(1, 6)]['3.1', '3.14', '3.142', '3.1416', '3.14159']

      嵌套列表解析

      Python 的列表还可以嵌套。

      以下实例展示了 3 * 4 的矩阵列表:

      >>> matrix = [...     [1, 2, 3, 4],...     [5, 6, 7, 8],...     [9, 10, 11, 12],... ]

      以下实例将 3 * 4 的矩阵列表转换为 4 * 3 列表:

      >>> [[row[i] for row in matrix] for i in range(4)][[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

      以下实例也可以使用以下方法来实现:

      >>> transposed = []>>> for i in range(4):...     transposed.append([row[i] for row in matrix])...>>> transposed[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

      另外一种实现方法:

      >>> transposed = []>>> for i in range(4):...     # the following 3 lines implement the nested listcomp...     transposed_row = []...     for row in matrix:...         transposed_row.append(row[i])...     transposed.append(transposed_row)...>>> transposed[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

      del 语句

      使用 del 语句可以从一个列表中依照索引(而不是值)来删除一个元素。这与使用 pop() 返回一个值不同。

      可以用 del 语句从列表中删除一个切片,或清空整个列表(我们以前介绍的方法是给该切片赋一个空列表)。例如:

      >>> a = [-1, 1, 66.25, 333, 333, 1234.5]>>> del a[0]>>> a[1, 66.25, 333, 333, 1234.5]>>> del a[2:4]>>> a[1, 66.25, 1234.5]>>> del a[:]>>> a[]

      也可以用 del 删除实体变量:

      >>> del a

      元组和序列

      元组由若干逗号分隔的值组成,例如:

      >>> t = 12345, 54321, 'hello!'>>> t[0]12345>>> t(12345, 54321, 'hello!')>>> # Tuples may be nested:... u = t, (1, 2, 3, 4, 5)>>> u((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))

      如你所见,元组在输出时总是有括号的,以便于正确表达嵌套结构。在输入时可能有或没有括号, 不过括号通常是必须的(如果元组是更大的表达式的一部分)。


      集合

      集合是一个无序不重复元素的集。基本功能包括关系测试和消除重复元素。

      可以用大括号 ({}) 创建集合。注意:如果要创建一个空集合,你必须用 set() 而不是 {} ;后者创建一个空的字典,下一节我们会介绍这个数据结构。

      以下是一个简单的演示:

      >>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}>>> print(basket)                      # show that duplicates have been removed{'orange', 'banana', 'pear', 'apple'}>>> 'orange' in basket                 # fast membership testingTrue>>> 'crabgrass' in basketFalse>>> # Demonstrate set operations on unique letters from two words...>>> a = set('abracadabra')>>> b = set('alacazam')>>> a                                  # unique letters in a{'a', 'r', 'b', 'c', 'd'}>>> a - b                              # letters in a but not in b{'r', 'd', 'b'}>>> a | b                              # letters in either a or b{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}>>> a & b                              # letters in both a and b{'a', 'c'}>>> a ^ b                              # letters in a or b but not both{'r', 'd', 'b', 'm', 'z', 'l'}

      集合也支持推导式:

      >>> a = {x for x in 'abracadabra' if x not in 'abc'}>>> a{'r', 'd'}

      字典

      另一个非常有用的 Python 内建数据类型是字典。

      序列是以连续的整数为索引,与此不同的是,字典以关键字为索引,关键字可以是任意不可变类型,通常用字符串或数值。

      理解字典的最佳方式是把它看做无序的键 => 值对集合。在同一个字典之内,关键字必须是互不相同。

      一对大括号创建一个空的字典:{}。

      这是一个字典运用的简单例子:

      >>> tel = {'jack': 4098, 'sape': 4139}>>> tel['guido'] = 4127>>> tel{'sape': 4139, 'guido': 4127, 'jack': 4098}>>> tel['jack']4098>>> del tel['sape']>>> tel['irv'] = 4127>>> tel{'guido': 4127, 'irv': 4127, 'jack': 4098}>>> list(tel.keys())['irv', 'guido', 'jack']>>> sorted(tel.keys())['guido', 'irv', 'jack']>>> 'guido' in telTrue>>> 'jack' not in telFalse

      构造函数 dict() 直接从键值对元组列表中构建字典。如果有固定的模式,列表推导式指定特定的键值对:

      >>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)]){'sape': 4139, 'jack': 4098, 'guido': 4127}

      此外,字典推导可以用来创建任意键和值的表达式词典:

      >>> {x: x**2 for x in (2, 4, 6)}{2: 4, 4: 16, 6: 36}

      如果关键字只是简单的字符串,使用关键字参数指定键值对有时候更方便:

      >>> dict(sape=4139, guido=4127, jack=4098){'sape': 4139, 'jack': 4098, 'guido': 4127}

      遍历技巧

      在字典中遍历时,关键字和对应的值可以使用 items() 方法同时解读出来:

      >>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}>>> for k, v in knights.items():...     print(k, v)...gallahad the purerobin the brave

      在序列中遍历时,索引位置和对应值可以使用 enumerate() 函数同时得到:

      >>> for i, v in enumerate(['tic', 'tac', 'toe']):...     print(i, v)...0 tic1 tac2 toe

      同时遍历两个或更多的序列,可以使用 zip() 组合:

      >>> questions = ['name', 'quest', 'favorite color']>>> answers = ['lancelot', 'the holy grail', 'blue']>>> for q, a in zip(questions, answers):...     print('What is your {0}?  It is {1}.'.format(q, a))...What is your name?  It is lancelot.What is your quest?  It is the holy grail.What is your favorite color?  It is blue.

      要反向遍历一个序列,首先指定这个序列,然后调用 reversed() 函数:

      >>> for i in reversed(range(1, 10, 2)):...     print(i)...97531

      要按顺序遍历一个序列,使用 sorted() 函数返回一个已排序的序列,并不修改原值:

      >>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']>>> for f in sorted(set(basket)):...     print(f)...applebananaorangepear

      其他参阅文档(Python2.x)


      在前面的几个章节中我们脚本上是用 Python 解释器来编程,如果你从 Python 解释器退出再进入,那么你定义的所有的方法和变量就都消失了。

      为此 Python 提供了一个办法,把这些定义存放在文件中,为一些脚本或者交互式的解释器实例使用,这个文件被称为模块。

      模块是一个包含所有你定义的函数和变量的文件,其后缀名是 .py。模块可以被别的程序引入,以使用该模块中的函数等功能。这也是使用 Python 标准库的方法。下面是一个使用 Python 标准库中模块的例子。 

      #!/usr/bin/python3# Filename: using_sys.pyimport sysprint('命令行参数如下:')for i in sys.argv:    print(i)print('
      
      Python 路径为:', sys.path, '
      ')

      执行结果如下所示:

      $ python using_sys.py 参数1 参数2命令行参数如下:using_sys.py参数1参数2Python 路径为: ['/root', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages']
      • 1、import sys 引入 Python 标准库中的 sys.py 模块;这是引入某一模块的方法。
      • 2、sys.argv 是一个包含命令行参数的列表。
      • 3、sys.path 包含了一个 Python 解释器自动查找所需模块的路径的列表。

      import 语句

      如果要使用 Python 源文件,只需在另一个源文件里执行 import 语句,import 语句语法如下:

      import module1[,module2[, ... moduleN]

      当解释器遇到 import 语句,如果模块在当前的搜索路径就会被导入。

      搜索路径是一个解释器会先进行搜索的所有目录的列表。如果想要导入模块 support,需要把命令放在脚本的顶端:

      #!/usr/bin/python3# Filename: support.pydef print_func( par ):    print ("Hello : ", par)    return

      test.py 引入 support 模块:

      #!/usr/bin/python3# Filename: test.py# 导入模块import support# 现在可以调用模块里包含的函数了support.print_func("51coolma")

      以上实例输出结果:

      $ python3 test.pyHello :  51coolma

      一个模块只会被导入一次,不管你执行了多少次 import。这样可以防止导入模块被一遍又一遍地执行。

      当我们使用 import 语句的时候,Python 解释器是怎样找到对应的文件的呢?

      这就涉及到 Python 的搜索路径,搜索路径是由一系列目录名组成的,Python 解释器就依次从这些目录中去寻找所引入的模块。

      这看起来很像环境变量,事实上,也可以通过定义环境变量的方式来确定搜索路径。

      搜索路径是在 Python 编译或安装的时候确定的,安装新的库应该也会修改。搜索路径被存储在 sys 模块中的 path 变量,做一个简单的实验,在交互式解释器中,输入以下代码:

      >>> import sys>>> sys.path['', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages']>>> 

      sys.path 输出是一个列表,其中第一项是空串'',代表当前目录(若是从一个脚本中打印出来的话,可以更清楚地看出是哪个目录),亦即我们执行 Python 解释器的目录(对于脚本的话就是运行的脚本所在的目录)。

      因此若像我一样在当前目录下存在与要引入模块同名的文件,就会把要引入的模块屏蔽掉。

      了解了搜索路径的概念,就可以在脚本中修改 sys.path 来引入一些不在搜索路径中的模块。

      现在,在解释器的当前目录或者 sys.path 中的一个目录里面来创建一个 fibo.py 的文件,代码如下:

      # 斐波那契数列模块(Fibonacci numbers module)def fib(n):    # 定义到 n 的斐波那契数列    a, b = 0, 1    while b < n:        print(b, end=' ')        a, b = b, a+b    print()def fib2(n): # 返回到 n 的斐波那契数列    result = []    a, b = 0, 1    while b < n:        result.append(b)        a, b = b, a+b    return result 

      然后进入 Python 解释器,使用下面的命令导入这个模块:

      >>> import fibo

      这样做并没有把直接定义在 fibo 中的函数名称写入到当前符号表里,只是把模块 fibo 的名字写到了那里。

      可以使用模块名称来访问函数:

      >>> fibo.fib(1000)1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987>>> fibo.fib2(100)[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]>>> fibo.__name__'fibo'

      如果你打算经常使用一个函数,你可以把它赋给一个本地的名称:

      >>> fib = fibo.fib>>> fib(500)1 1 2 3 5 8 13 21 34 55 89 144 233 377

      from ... import 语句

      Python 的 from 语句让你从模块中导入一个指定的部分到当前命名空间中,语法如下:

      from modname import name1[, name2[, ... nameN]

      例如,要导入模块 fibo 的 fib 函数,使用如下语句:

      >>> from fibo import fib, fib2>>> fib(500)1 1 2 3 5 8 13 21 34 55 89 144 233 377

      这个声明不会把整个 fibo 模块导入到当前的命名空间中,它只会将 fibo 里的 fib 函数引入进来。


      from ... import * 语句

      把一个模块的所有内容全都导入到当前的命名空间也是可行的,只需使用如下声明:

      from modname import *

      这提供了一个简单的方法来导入一个模块中的所有项目。然而这种声明不该被过多的使用。


      进一步了解模块

      模块除了方法定义,还可以包括可执行的代码。这些代码一般用来初始化这个模块。这些代码只有在第一次被导入时才会被执行。

      每个模块有各自独立的符号表,在模块内部为所有的函数当作全局符号表来使用。

      所以,模块的作者可以放心大胆的在模块内部使用这些全局变量,而不用担心把其他用户的全局变量搞花。

      从另一个方面,当你确实知道你在做什么的话,你也可以通过 modname.itemname 这样的表示法来访问模块内的函数。

      模块是可以导入其他模块的。在一个模块(或者脚本,或者其他地方)的最前面使用 import 来导入一个模块,当然这只是一个惯例,而不是强制的。被导入的模块的名称将被放入当前操作的模块的符号表中。

      还有一种导入的方法,可以使用 import 直接把模块内(函数,变量的)名称导入到当前操作模块。比如:

      >>> from fibo import fib, fib2>>> fib(500)1 1 2 3 5 8 13 21 34 55 89 144 233 377

      这种导入的方法不会把被导入的模块的名称放在当前的字符表中(所以在这个例子里面,fibo 这个名称是没有定义的)。

      这还有一种方法,可以一次性的把模块中的所有(函数,变量)名称都导入到当前模块的字符表:

      >>> from fibo import *>>> fib(500)1 1 2 3 5 8 13 21 34 55 89 144 233 377

      这将把所有的名字都导入进来,但是那些由单一下划线(_)开头的名字不在此例。大多数情况, Python程序员不使用这种方法,因为引入的其它来源的命名,很可能覆盖了已有的定义。


      __name__属性

      一个模块被另一个程序第一次引入时,其主程序将运行。如果我们想在模块被引入时,模块中的某一程序块不执行,我们可以用 __name__ 属性来使该程序块仅在该模块自身运行时执行。

      #!/usr/bin/python3# Filename: using_name.pyif __name__ == '__main__':    print('程序自身在运行')else:    print('我来自另一模块')

      运行输出如下:

      $ python using_name.py程序自身在运行
      $ python>>> import using_name我来自另一模块>>>

      说明:

      1. 每个模块都有一个 __name__ 属性,当其值是 '__main__' 时,表明该模块自身在运行,否则是被引入。
      2. __name__ 与 __main__ 底下是双下划线,是“_ _”去掉中间的空格。


      dir() 函数

      内置的函数 dir() 可以找到模块内定义的所有名称。以一个字符串列表的形式返回:</p><pre>>>> import fibo, sys>>> dir(fibo)['__name__', 'fib', 'fib2']>>> dir(sys)  ['__displayhook__', '__doc__', '__excepthook__', '__loader__', '__name__', '__package__', '__stderr__', '__stdin__', '__stdout__', '_clear_type_cache', '_current_frames', '_debugmallocstats', '_getframe', '_home', '_mercurial', '_xoptions', 'abiflags', 'api_version', 'argv', 'base_exec_prefix', 'base_prefix', 'builtin_module_names', 'byteorder', 'call_tracing', 'callstats', 'copyright', 'displayhook', 'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info', 'float_repr_style', 'getcheckinterval', 'getdefaultencoding', 'getdlopenflags', 'getfilesystemencoding', 'getobjects', 'getprofile', 'getrecursionlimit', 'getrefcount', 'getsizeof', 'getswitchinterval', 'gettotalrefcount', 'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info', 'intern', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1', 'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit', 'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout', 'thread_info', 'version', 'version_info', 'warnoptions']

      如果没有给定参数,那么 dir() 函数会罗列出当前定义的所有名称:

      >>> a = [1, 2, 3, 4, 5]>>> import fibo>>> fib = fibo.fib>>> dir() # 得到一个当前模块中定义的属性列表['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']>>> a = 5 # 建立一个新的变量 'a'>>> dir()['__builtins__', '__doc__', '__name__', 'a', 'sys']>>>>>> del a # 删除变量名a>>>>>> dir()['__builtins__', '__doc__', '__name__', 'sys']>>>

      标准模块

      Python 本身带着一些标准的模块库,在 Python 库参考文档中将会介绍到(就是后面的"库参考文档")。

      有些模块直接被构建在解析器里,这些虽然不是一些语言内置的功能,但是他却能很高效的使用,甚至是系统级调用也没问题。

      这些组件会根据不同的操作系统进行不同形式的配置,比如 winreg 这个模块就只会提供给 Windows 系统。

      应该注意到这有一个特别的模块 sys ,它内置在每一个 Python 解析器中。变量 sys.ps1 和 sys.ps2 定义了主提示符和副提示符所对应的字符串:

      >>> import sys>>> sys.ps1'>>> '>>> sys.ps2'... '>>> sys.ps1 = 'C> 'C> print('Yuck!')Yuck!C>

      包是一种管理 Python 模块命名空间的形式,采用"点模块名称"。

      比如一个模块的名称是 A.B, 那么他表示一个包 A 中的子模块 B 。

      就好像使用模块的时候,你不用担心不同模块之间的全局变量相互影响一样,采用点模块名称这种形式也不用担心不同库之间的模块重名的情况。

      这样不同的作者都可以提供 NumPy 模块,或者是 Python 图形库。

      不妨假设你想设计一套统一处理声音文件和数据的模块(或者称之为一个"包")。

      现存很多种不同的音频文件格式(基本上都是通过后缀名区分的,例如: .wav,:file:.aiff,:file:.au,),所以你需要有一组不断增加的模块,用来在不同的格式之间转换。

      并且针对这些音频数据,还有很多不同的操作(比如混音,添加回声,增加均衡器功能,创建人造立体声效果),所以你还需要一组怎么也写不完的模块来处理这些操作。

      这里给出了一种可能的包结构(在分层的文件系统中):

      sound/                          顶层包      __init__.py               初始化 sound 包      formats/                  文件格式转换子包              __init__.py              wavread.py              wavwrite.py              aiffread.py              aiffwrite.py              auread.py              auwrite.py              ...      effects/                  声音效果子包              __init__.py              echo.py              surround.py              reverse.py              ...      filters/                  filters 子包              __init__.py              equalizer.py              vocoder.py              karaoke.py              ...

      在导入一个包的时候,Python 会根据 sys.path 中的目录来寻找这个包中包含的子目录。

      目录只有包含一个叫做 __init__.py 的文件才会被认作是一个包,主要是为了避免一些滥俗的名字(比如叫做 string)不小心的影响搜索路径中的有效模块。

      最简单的情况,放一个空的 :file:__init__.py 就可以了。当然这个文件中也可以包含一些初始化代码或者为(将在后面介绍的) __all__变量赋值。

      用户可以每次只导入一个包里面的特定模块,比如:

      import sound.effects.echo

      这将会导入子模块: mod:song.effects.echo。 他必须使用全名去访问:

      sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

      还有一种导入子模块的方法是:

      from sound.effects import echo

      这同样会导入子模块 echo ,并且他不需要那些冗长的前缀,所以他可以这样使用:

      echo.echofilter(input, output, delay=0.7, atten=4)

      还有一种变化就是直接导入一个函数或者变量:

      from sound.effects.echo import echofilter

      同样的,这种方法会导入子模块 echo ,并且可以直接使用他的 echofilter() 函数:

      echofilter(input, output, delay=0.7, atten=4)

      注意当使用 from package import item 这种形式的时候,对应的 item 既可以是包里面的子模块(子包),或者包里面定义的其他名称,比如函数,类或者变量。

      import语法会首先把item当作一个包定义的名称,如果没找到,再试图按照一个模块去导入。如果还没找到,恭喜,一个 : exc:ImportError 异常被抛出了。

      反之,如果使用形如 import item.subitem.subsubitem 这种导入形式,除了最后一项,都必须是包,而最后一项则可以是模块或者是包,但是不可以是类,函数或者变量的名字。


      从一个包中导入*

      设想一下,如果我们使用 from sound.effects import *会发生什么?

      Python 会进入文件系统,找到这个包里面所有的子模块,一个一个的把它们都导入进来。

      但是很不幸,这个方法在 Windows平台上工作的就不是非常好,因为 Windows 是一个大小写不区分的系统。

      在这类平台上,没有人敢担保一个叫做 ECHO.py 的文件导入为模块 echo 还是 Echo 甚至 ECHO 。

      (例如,Windows 95就很讨厌的把每一个文件的首字母大写显示)而且 DOS 的 8+3 命名规则对长模块名称的处理会把问题搞得更纠结。

      为了解决这个问题,只能烦劳包作者提供一个精确的包的索引了。

      导入语句遵循如下规则:如果包定义文件 __init__.py 存在一个叫做 __all__ 的列表变量,那么在使用 from package import * 的时候就把这个列表中的所有名字作为包内容导入。

      作为包的作者,可别忘了在更新包之后保证 __all__ 也更新了啊。你说我就不这么做,我就不使用导入*这种用法,好吧,没问题,谁让你是老板呢。这里有一个例子,在 ​:file:sounds/effects/__init__.py​ 中包含如下代码:

      __all__ = ["echo", "surround", "reverse"]

      这表示当你使用 from sound.effects import * 这种用法时,你只会导入包里面这三个子模块。

      如果 __all__ 没有定义,那么使用 from sound.effects import * 这种语法的时候,就不会导入包 sound.effects 里的任何子模块。他只是把包 sound.effects 和它里面定义的所有内容导入进来(可能运行 __init__.py 里定义的初始化代码)。

      这会把 __init__.py 里面定义的所有名字导入进来。并且他不会破坏掉我们在这句话之前导入的所有明确指定的模块。看下这部分代码:

      import sound.effects.echoimport sound.effects.surroundfrom sound.effects import *

      这个例子中,在执行 from...import 前,包 sound.effects 中的 echo 和 surround 模块都被导入到当前的命名空间中了。(当然如果定义了__all__ 就更没问题了)

      通常我们并不主张使用*这种方法来导入模块,因为这种方法经常会导致代码的可读性降低。不过这样倒的确是可以省去不少敲键的功夫,而且一些模块都设计成了只能通过特定的方法导入。

      记住,使用 from Package import specific_submodule 这种方法永远不会有错。事实上,这也是推荐的方法。除非是你要导入的子模块有可能和其他包的子模块重名。

      如果在结构中包是一个子包(比如这个例子中对于包 sound 来说),而你又想导入兄弟包(同级别的包)你就得使用导入绝对的路径来导入。比如,如果模块  sound.filters.vocoder 要使用包 sound.effects 中的模块 echo ,你就要写成 from sound.effects import echo。

      from . import echofrom .. import formatsfrom ..filters import equalizer

      无论是隐式的还是显式的相对导入都是从当前模块开始的。主模块的名字永远是 "__main__",一个Python应用程序的主模块,应当总是使用绝对路径引用。

      包还提供一个额外的属性 __path__ 。这是一个目录列表,里面每一个包含的目录都有为这个包服务的 __init__.py ,你得在其他 __init__.py 被执行前定义哦。可以修改这个变量,用来影响包含在包里面的模块和子包。

      这个功能并不常用,一般用来扩展包里面的模块。


      在前面几个章节中,我们其实已经接触了 Python 的输入输出的功能。本章节我们将具体介绍 Python 的输入输出。


      输出格式美化

      Python 两种输出值的方式: 表达式语句和 print() 函数。(第三种方式是使用文件对象的 write() 方法; 标准输出文件可以用 sys.stdout 引用。)

      如果你希望输出的形式更加多样,可以使用 str.format() 函数来格式化输出值。

      如果你希望将输出的值转成字符串,可以使用 repr() 或 str() 函数来实现。

      str() 函数返回一个用户易读的表达形式。

      repr() 产生一个解释器易读的表达形式。

      例如

      >>> s = 'Hello, world.'>>> str(s)'Hello, world.'>>> repr(s)"'Hello, world.'">>> str(1/7)'0.14285714285714285'>>> x = 10 * 3.25>>> y = 200 * 200>>> s = 'The value of x is ' + repr(x) + ', and y is ' + repr(y) + '...'>>> print(s)The value of x is 32.5, and y is 40000...>>> #  repr() 函数可以转义字符串中的特殊字符... hello = 'hello, world
      '>>> hellos = repr(hello)>>> print(hellos)'hello, world
      '>>> # repr() 的参数可以是 Python 的任何对象... repr((x, y, ('spam', 'eggs')))"(32.5, 40000, ('spam', 'eggs'))"

      这里有两种方式输出一个平方与立方的表:

      >>> for x in range(1, 11):...     print(repr(x).rjust(2), repr(x*x).rjust(3), end=' ')...     # 注意前一行 'end' 的使用...     print(repr(x*x*x).rjust(4))... 1   1    1 2   4    8 3   9   27 4  16   64 5  25  125 6  36  216 7  49  343 8  64  512 9  81  72910 100 1000>>> for x in range(1, 11):...     print('{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x))... 1   1    1 2   4    8 3   9   27 4  16   64 5  25  125 6  36  216 7  49  343 8  64  512 9  81  72910 100 1000

      注意:在第一个例子中, 每列间的空格由 print() 添加。

      这个例子展示了字符串对象的 rjust() 方法, 它可以将字符串靠右, 并在左边填充空格。

      还有类似的方法, 如 ljust() 和 center()。 这些方法并不会写任何东西, 它们仅仅返回新的字符串。

      另一个方法 zfill(), 它会在数字的左边填充 0,如下所示:

      >>> '12'.zfill(5)'00012'>>> '-3.14'.zfill(7)'-003.14'>>> '3.14159265359'.zfill(5)'3.14159265359'

      str.format() 的基本使用如下:

      >>> print('We are the {} who say "{}!"'.format('knights', 'Ni'))We are the knights who say "Ni!"

      括号及其里面的字符 (称作格式化字段) 将会被 format() 中的参数替换。

      在括号中的数字用于指向传入对象在 format() 中的位置,如下所示:

      >>> print('{0} and {1}'.format('spam', 'eggs'))spam and eggs>>> print('{1} and {0}'.format('spam', 'eggs'))eggs and spam

      如果在 format() 中使用了关键字参数, 那么它们的值会指向使用该名字的参数。

      >>> print('This {food} is {adjective}.'.format(...       food='spam', adjective='absolutely horrible'))This spam is absolutely horrible.

      位置及关键字参数可以任意的结合:

      >>> print('The story of {0}, {1}, and {other}.'.format('Bill', 'Manfred',other='Georg'))The story of Bill, Manfred, and Georg.

      '!a' (使用 ascii()), '!s' (使用 str()) 和 '!r' (使用 repr()) 可以用于在格式化某个值之前对其进行转化:

      >>> import math>>> print('The value of PI is approximately {}.'.format(math.pi))The value of PI is approximately 3.14159265359.>>> print('The value of PI is approximately {!r}.'.format(math.pi))The value of PI is approximately 3.141592653589793.

      可选项 ':' 和格式标识符可以跟着字段名。 这就允许对值进行更好的格式化。 下面的例子将 Pi 保留到小数点后三位:

      >>> import math>>> print('The value of PI is approximately {0:.3f}.'.format(math.pi))The value of PI is approximately 3.142.

      在 ':' 后传入一个整数, 可以保证该域至少有这么多的宽度。 用于美化表格时很有用。

      >>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}>>> for name, phone in table.items():...     print('{0:10} ==> {1:10d}'.format(name, phone))...Jack       ==>       4098Dcab       ==>       7678Sjoerd     ==>       4127

      如果你有一个很长的格式化字符串, 而你不想将它们分开, 那么在格式化时通过变量名而非位置会是很好的事情。

      最简单的就是传入一个字典, 然后使用方括号 '[]' 来访问键值 :

      >>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}>>> print('Jack: {0[Jack]:d}; Sjoerd: {0[Sjoerd]:d}; '          'Dcab: {0[Dcab]:d}'.format(table))Jack: 4098; Sjoerd: 4127; Dcab: 8637678

      也可以通过在 table 变量前使用 '**' 来实现相同的功能:

      >>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}>>> print('Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table))Jack: 4098; Sjoerd: 4127; Dcab: 8637678

      旧式字符串格式化

      % 操作符也可以实现字符串格式化。 它将左边的参数作为类似 sprintf() 式的格式化字符串, 而将右边的代入, 然后返回格式化后的字符串. 例如:

      >>> import math>>> print('The value of PI is approximately %5.3f.' % math.pi)The value of PI is approximately 3.142.

      因为 str.format() 比较新的函数, 大多数的 Python 代码仍然使用 % 操作符。但是因为这种旧式的格式化最终会从该语言中移除, 应该更多的使用 str.format().


      读和写文件

      open() 将会返回一个 file 对象,基本语法格式如下:

      open(filename, mode)

      实例:

      >>> f = open('/tmp/workfile', 'w')
      • 第一个参数为要打开的文件名。
      • 第二个参数描述文件如何使用的字符。 mode 可以是 'r' 如果文件只读, 'w' 只用于写 (如果存在同名文件则将被删除), 和 'a' 用于追加文件内容; 所写的任何数据都会被自动增加到末尾. 'r+' 同时用于读写。 mode 参数是可选的; 'r' 将是默认值。

      文件对象的方法

      本节中剩下的例子假设已经创建了一个称为 f 的文件对象。

      f.read()

      为了读取一个文件的内容,调用 f.read(size), 这将读取一定数目的数据, 然后作为字符串或字节对象返回。

      size 是一个可选的数字类型的参数。 当 size 被忽略了或者为负, 那么该文件的所有内容都将被读取并且返回。

      >>> f.read()'This is the entire file.
      '>>> f.read()''

      f.readline()

      f.readline() 会从文件中读取单独的一行。换行符为 ' '。f.readline() 如果返回一个空字符串, 说明已经已经读取到最后一行。

      >>> f.readline()'This is the first line of the file.
      '>>> f.readline()'Second line of the file
      '>>> f.readline()''

      f.readlines()

      f.readlines() 将返回该文件中包含的所有行。

      如果设置可选参数 sizehint, 则读取指定长度的字节, 并且将这些字节按行分割。

      >>> f.readlines()['This is the first line of the file.
      ', 'Second line of the file
      ']

      另一种方式是迭代一个文件对象然后读取每行:

      >>> for line in f:...     print(line, end='')...This is the first line of the file.Second line of the file

      这个方法很简单, 但是并没有提供一个很好的控制。 因为两者的处理机制不同, 最好不要混用。

      f.write()

      f.write(string) 将 string 写入到文件中, 然后返回写入的字符数。

      >>> f.write('This is a test
      ')15

      如果要写入一些不是字符串的东西, 那么将需要先进行转换:

      >>> value = ('the answer', 42)>>> s = str(value)>>> f.write(s)18

      f.tell()

      f.tell() 返回文件对象当前所处的位置, 它是从文件开头开始算起的字节数。

      f.seek()

      如果要改变文件当前的位置, 可以使用 f.seek(offset, from_what) 函数。

      from_what 的值, 如果是 0 表示开头, 如果是 1 表示当前位置, 2 表示文件的结尾,例如:

      • seek(x, 0) : 从起始位置即文件首行首字符开始移动 x 个字符
      • seek(x, 1) : 表示从当前位置往后移动x个字符
      • seek(-x, 2):表示从文件的结尾往前移动x个字符

      from_what 值为默认为 0,即文件开头。下面给出一个完整的例子:

      >>> f = open('/tmp/workfile', 'rb+')>>> f.write(b'0123456789abcdef')16>>> f.seek(5)     # 移动到文件的第六个字节5>>> f.read(1)b'5'>>> f.seek(-3, 2) # 移动到文件的倒数第三字节13>>> f.read(1)b'd'

      f.close()

      在文本文件中 (那些打开文件的模式下没有 b 的), 只会相对于文件起始位置进行定位。

      当你处理完一个文件后, 调用 f.close() 来关闭文件并释放系统的资源,如果尝试再调用该文件,则会抛出异常。

      >>> f.close()>>> f.read()Traceback (most recent call last):  File "<stdin>", line 1, in ?ValueError: I/O operation on closed file<pre><p>当处理一个文件对象时, 使用 with 关键字是非常好的方式。在结束后, 它会帮你正确的关闭文件。 而且写起来也比 try - finally 语句块要简短:</p><pre>>>> with open('/tmp/workfile', 'r') as f:...     read_data = f.read()>>> f.closedTrue

      文件对象还有其他方法, 如 isatty() 和 trucate(), 但这些通常比较少用。


      pickle 模块

      Python 的 pickle 模块实现了基本的数据序列和反序列化。

      通过 pickle 模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储。

      通过 pickle 模块的反序列化操作,我们能够从文件中创建上一次程序保存的对象。

      基本接口:

      pickle.dump(obj, file, [,protocol])

      有了 pickle 这个对象, 就能对 file 以读取的形式打开:

      x = pickle.load(file)

      注解:从 file 中读取一个字符串,并将它重构为原来的 Python 对象。

      file: 类文件对象,有read() 和 readline() 接口。

      实例 1:

      #使用pickle模块将数据对象保存到文件import pickledata1 = {'a': [1, 2.0, 3, 4+6j],         'b': ('string', u'Unicode string'),         'c': None}selfref_list = [1, 2, 3]selfref_list.append(selfref_list)output = open('data.pkl', 'wb')# Pickle dictionary using protocol 0.pickle.dump(data1, output)# Pickle the list using the highest protocol available.pickle.dump(selfref_list, output, -1)output.close()

      实例 2:

      #使用pickle模块从文件中重构python对象import pprint, picklepkl_file = open('data.pkl', 'rb')data1 = pickle.load(pkl_file)pprint.pprint(data1)data2 = pickle.load(pkl_file)pprint.pprint(data2)pkl_file.close()


      file 文件对象使用 open 函数来创建,下表列出了 file 文件对象常用的函数:

      序号方法及描述
      1

      file.close()

      关闭文件。关闭后文件不能再进行读写操作。

      2

      file.flush()

      刷新文件内部缓冲,直接把内部缓冲区的数据立刻写入文件, 而不是被动的等待输出缓冲区写入。

      3

      file.fileno()

      返回一个整型的文件描述符 (file descriptor FD 整型), 可以用在如 os 模块的 read 方法等一些底层操作上。

      4

      file.isatty()

      如果文件连接到一个终端设备返回 True,否则返回 False。

      5

      file.next()

      返回文件下一行。

      6

      file.read([size])

      从文件读取指定的字节数,如果未给定或为负则读取所有。

      7

      file.readline([size])

      读取整行,包括 " " 字符。

      8

      file.readlines([sizehint])

      读取所有行并返回列表,若给定 sizeint>0,返回总和大约为 sizeint 字节的行, 实际读取值可能比 sizeint 较大, 因为需要填充缓冲区。

      9

      file.seek(offset[, whence])

      设置文件当前位置

      10

      file.tell()

      返回文件当前位置。

      11

      file.truncate([size])

      截取文件,截取的字节通过 size 指定,默认为当前文件位置。

      12

      file.write(str)

      将字符串写入文件,返回的是写入的字符长度。

      13

      file.writelines(sequence)

      向文件写入一个序列字符串列表,如果需要换行则要自己加入每行的换行符。


      os 模块提供了非常丰富的方法用来处理文件和目录。常用的方法如下表所示:

      序号方法及描述
      1

      os.access(path, mode)

      检验权限模式。
      2

      os.chdir(path)

      改变当前工作目录。
      3

      os.chflags(path, flags)

      设置路径的标记为数字标记。
      4

      os.chmod(path, mode)

      更改权限。
      5

      os.chown(path, uid, gid)

      更改文件所有者。
      6

      os.chroot(path)

      改变当前进程的根目录。
      7

      os.close(fd)

      关闭文件描述符 fd。
      8

      os.closerange(fd_low, fd_high)

      关闭所有文件描述符,从 fd_low (包含) 到 fd_high (不包含), 错误会忽略。
      9

      os.dup(fd)

      复制文件描述符 fd。
      10

      os.dup2(fd, fd2)

      将一个文件描述符 fd 复制到另一个 fd2。
      11

      os.fchdir(fd)

      通过文件描述符改变当前工作目录。
      12

      os.fchmod(fd, mode)

      改变一个文件的访问权限,该文件由参数 fd 指定,参数 mode 是 Unix 下的文件访问权限。
      13

      os.fchown(fd, uid, gid)

      修改一个文件的所有权,这个函数修改一个文件的用户 ID 和用户组 ID,该文件由文件描述符 fd 指定。
      14

      os.fdatasync(fd)

      强制将文件写入磁盘,该文件由文件描述符 fd 指定,但是不强制更新文件的状态信息。
      15

      os.fdopen(fd[, mode[, bufsize]])

      通过文件描述符 fd 创建一个文件对象,并返回这个文件对象。
      16

      os.fpathconf(fd, name)

      返回一个打开的文件的系统配置信息。name 为检索的系统配置的值,它也许是一个定义系统值的字符串,这些名字在很多标准中指定(POSIX.1, Unix 95, Unix 98, 和其它)。
      17

      os.fstat(fd)

      返回文件描述符 fd 的状态,像 stat()。
      18

      os.fstatvfs(fd)

      返回包含文件描述符 fd 的文件的文件系统的信息,像 statvfs()。
      19

      os.fsync(fd)

      强制将文件描述符为 fd 的文件写入硬盘。
      20

      os.ftruncate(fd, length)

      裁剪文件描述符 fd 对应的文件, 所以它最大不能超过文件大小。
      21

      os.getcwd()

      返回当前工作目录。
      22

      os.getcwdu()

      返回一个当前工作目录的 Unicode 对象。
      23

      os.isatty(fd)

      如果文件描述符 fd 是打开的,同时与 tty(-like) 设备相连,则返回 true, 否则 False。
      24

      os.lchflags(path, flags)

      设置路径的标记为数字标记,类似 chflags(),但是没有软链接。
      25

      os.lchmod(path, mode)

      修改连接文件权限。
      26

      os.lchown(path, uid, gid)

      更改文件所有者,类似 chown,但是不追踪链接。
      27

      os.link(src, dst)

      创建硬链接,名为参数 dst,指向参数 src。
      28

      os.listdir(path)

      返回 path 指定的文件夹包含的文件或文件夹的名字的列表。
      29

      os.lseek(fd, pos, how)

      设置文件描述符 fd 当前位置为 pos, how 方式修改: SEEK_SET 或者 0 设置从文件开始的计算的 pos; SEEK_CUR 或者 1 则从当前位置计算;os.SEEK_END 或者 2 则从文件尾部开始。在 unix,Windows 中有效。
      30

      os.lstat(path)

      像 stat(),但是没有软链接。
      31

      os.major(device)

      从原始的设备号中提取设备 major 号码 (使用 stat 中的 st_dev 或者 st_rdev field)。
      32

      os.makedev(major, minor)

      以 major 和 minor 设备号组成一个原始设备号。
      33

      os.makedirs(path[, mode])

      递归文件夹创建函数。像 mkdir(), 但创建的所有 intermediate-level 文件夹需要包含子文件夹。
      34

      os.minor(device)

      从原始的设备号中提取设备 minor 号码 (使用 stat 中的 st_dev 或者 st_rdev field )。
      35

      os.mkdir(path[, mode])

      以数字 mode 的 mode 创建一个名为 path 的文件夹。默认的 mode 是 0777 (八进制)。
      36

      os.mkfifo(path[, mode])

      创建命名管道,mode 为数字,默认为 0666 (八进制)。
      37

      os.mknod(filename[, mode=0600, device])
      创建一个名为 filename 文件系统节点(文件,设备特别文件或者命名 pipe)。

      38

      os.open(file, flags[, mode])

      打开一个文件,并且设置需要的打开选项,mode 参数是可选的。
      39

      os.openpty()

      打开一个新的伪终端对。返回 pty 和 tty 的文件描述符。
      40

      os.pathconf(path, name)

      返回相关文件的系统配置信息。
      41

      os.pipe()

      创建一个管道. 返回一对文件描述符 (r, w) 分别为读和写
      42

      os.popen(command[, mode[, bufsize]])

      从一个 command 打开一个管道。
      43

      os.read(fd, n)

      从文件描述符 fd 中读取最多 n 个字节,返回包含读取字节的字符串,文件描述符 fd 对应文件已达到结尾,返回一个空字符串。
      44

      os.readlink(path)

      返回软链接所指向的文件。
      45

      os.remove(path)

      删除路径为 path 的文件。如果 path 是一个文件夹,将抛出 OSError; 查看下面的 rmdir() 删除一个 directory。
      46

      os.removedirs(path)

      递归删除目录。
      47

      os.rename(src, dst)

      重命名文件或目录,从 src 到 dst。
      48

      os.renames(old, new)

      递归地对目录进行更名,也可以对文件进行更名。
      49

      os.rmdir(path)

      删除 path 指定的空目录,如果目录非空,则抛出一个 OSError 异常。
      50

      os.stat(path)

      获取 path 指定的路径的信息,功能等同于 C API 中的 stat() 系统调用。
      51

      os.stat_float_times([newvalue])
      决定 stat_result 是否以 float 对象显示时间戳。

      52

      os.statvfs(path)

      获取指定路径的文件系统统计信息。
      53

      os.symlink(src, dst)

      创建一个软链接。
      54

      os.tcgetpgrp(fd)

      返回与终端 fd(一个由 os.open() 返回的打开的文件描述符)关联的进程组。
      55

      os.tcsetpgrp(fd, pg)

      设置与终端 fd(一个由 os.open() 返回的打开的文件描述符)关联的进程组为 pg。
      56

      os.tempnam([dir[, prefix]])

      返回唯一的路径名用于创建临时文件。
      57

      os.tmpfile()

      返回一个打开的模式为 (w+b) 的文件对象,这文件对象没有文件夹入口,没有文件描述符,将会自动删除。
      58

      os.tmpnam()

      为创建一个临时文件返回一个唯一的路径。
      59

      os.ttyname(fd)

      返回一个字符串,它表示与文件描述符 fd 关联的终端设备。如果 fd 没有与终端设备关联,则引发一个异常。
      60

      os.unlink(path)

      删除文件路径。
      61

      os.utime(path, times)

      返回指定的 path 文件的访问和修改的时间。
      62

      os.walk(top[, topdown=True[, onerror=None[, followlinks=False]]])

      输出在文件夹中的文件名通过在树中游走,向上或者向下。
      63

      os.write(fd, str)

      写入字符串到文件描述符 fd 中,返回实际写入的字符串长度


      作为 Python 初学者,在刚学习 Python 编程时,经常会看到一些报错信息,在前面我们没有提及,这章节我们会专门介绍。

      Python 有两种错误很容易辨认:语法错误和异常。

      语法错误

      Python 的语法错误或者称之为解析错,是初学者经常碰到的,如下实例

      >>> while True print('Hello world')  File "<stdin>", line 1, in ?    while True print('Hello world')                   ^SyntaxError: invalid syntax

      这个例子中,函数 print() 被检查到有错误,是它前面缺少了一个冒号(:)。

      语法分析器指出了出错的一行,并且在最先找到的错误的位置标记了一个小小的箭头。

      异常

      即便 Python 程序的语法是正确的,在运行它的时候,也有可能发生错误。运行期检测到的错误被称为异常。

      大多数的异常都不会被程序处理,都以错误信息的形式展现在这里:

      >>> 10 * (1/0)Traceback (most recent call last):  File "<stdin>", line 1, in ?ZeroDivisionError: division by zero>>> 4 + spam*3Traceback (most recent call last):  File "<stdin>", line 1, in ?NameError: name 'spam' is not defined>>> '2' + 2Traceback (most recent call last):  File "<stdin>", line 1, in ?TypeError: Can't convert 'int' object to str implicitly

      异常以不同的类型出现,这些类型都作为信息的一部分打印出来: 例子中的类型有 ZeroDivisionError,NameError 和 TypeError。

      错误信息的前面部分显示了异常发生的上下文,并以调用栈的形式显示具体信息。

      异常处理

      以下例子中,让用户输入一个合法的整数,但是允许用户中断这个程序(使用 Control-C 或者操作系统提供的方法)。用户中断的信息会引发一个 KeyboardInterrupt 异常。

      >>> while True:        try:            x = int(input("Please enter a number: "))            break        except ValueError:            print("Oops!  That was no valid number.  Try again   ")   

      try 语句按照如下方式工作;

      • 首先,执行 try 子句(在关键字 try 和关键字 except 之间的语句)
      • 如果没有异常发生,忽略 except 子句,try 子句执行后结束。
      • 如果在执行 try 子句的过程中发生了异常,那么 try 子句余下的部分将被忽略。如果异常的类型和 except 之后的名称相符,那么对应的 except 子句将被执行。最后执行 try 语句之后的代码。
      • 如果一个异常没有与任何的 except 匹配,那么这个异常将会传递给上层的 try 中。

      一个 try 语句可能包含多个 except 子句,分别来处理不同的特定的异常。最多只有一个分支会被执行。

      处理程序将只针对对应的 try 子句中的异常进行处理,而不是其他的 try 的处理程序中的异常。

      一个 except 子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组,例如:

      >>> except (RuntimeError, TypeError, NameError):        pass

      最后一个 except 子句可以忽略异常的名称,它将被当作通配符使用。你可以使用这种方法打印一个错误信息,然后再次把异常抛出。

      import systry:    f = open('myfile.txt')    s = f.readline()    i = int(s.strip())except OSError as err:    print("OS error: {0}".format(err))except ValueError:    print("Could not convert data to an integer.")except:    print("Unexpected error:", sys.exc_info()[0])    raise

      try except 语句还有一个可选的 else 子句,如果使用这个子句,那么必须放在所有的 except 子句之后。这个子句将在 try 子句没有发生任何异常的时候执行。例如:

      for arg in sys.argv[1:]:    try:        f = open(arg, 'r')    except IOError:        print('cannot open', arg)    else:        print(arg, 'has', len(f.readlines()), 'lines')        f.close()

      使用 else 子句比把所有的语句都放在 try 子句里面要好,这样可以避免一些意想不到的、而except又没有捕获的异常。

      异常处理并不仅仅处理那些直接发生在try子句中的异常,而且还能处理子句中调用的函数(甚至间接调用的函数)里抛出的异常。例如:

      >>> def this_fails():        x = 1/0   >>> try:        this_fails()    except ZeroDivisionError as err:        print('Handling run-time error:', err)   Handling run-time error: int division or modulo by zero

      抛出异常

      Python 使用 raise 语句抛出一个指定的异常。例如:

      >>> raise NameError('HiThere')Traceback (most recent call last):  File "<stdin>", line 1, in ?NameError: HiThere

      raise 唯一的一个参数指定了要被抛出的异常。它必须是一个异常的实例或者是异常的类(也就是 Exception 的子类)。

      如果你只想知道这是否抛出了一个异常,并不想去处理它,那么一个简单的 raise 语句就可以再次把它抛出。

      >>> try:        raise NameError('HiThere')    except NameError:        print('An exception flew by!')        raise   An exception flew by!Traceback (most recent call last):  File "<stdin>", line 2, in ?NameError: HiThere

      用户自定义异常

      你可以通过创建一个新的 exception 类来拥有自己的异常。异常应该继承自 Exception 类,或者直接继承,或者间接继承,例如:

      >>> class MyError(Exception):        def __init__(self, value):            self.value = value        def __str__(self):            return repr(self.value)   >>> try:        raise MyError(2*2)    except MyError as e:        print('My exception occurred, value:', e.value)   My exception occurred, value: 4>>> raise MyError('oops!')Traceback (most recent call last):  File "<stdin>", line 1, in ?__main__.MyError: 'oops!'

      在这个例子中,类 Exception 默认的 __init__() 被覆盖。

      异常的类可以像其他的类一样做任何事情,但是通常都会比较简单,只提供一些错误相关的属性,并且允许处理异常的代码方便的获取这些信息。

      当创建一个模块有可能抛出多种不同的异常时,一种通常的做法是为这个包建立一个基础异常类,然后基于这个基础类为不同的错误情况创建不同的子类:

      class Error(Exception):    """Base class for exceptions in this module."""    passclass InputError(Error):    """Exception raised for errors in the input.    Attributes:        expression -- input expression in which the error occurred        message -- explanation of the error    """    def __init__(self, expression, message):        self.expression = expression        self.message = messageclass TransitionError(Error):    """Raised when an operation attempts a state transition that's not    allowed.    Attributes:        previous -- state at beginning of transition        next -- attempted new state        message -- explanation of why the specific transition is not allowed    """    def __init__(self, previous, next, message):        self.previous = previous        self.next = next        self.message = message

      大多数的异常的名字都以"Error"结尾,就跟标准的异常命名一样。


      定义清理行为

      try 语句还有另外一个可选的子句,它定义了无论在任何情况下都会执行的清理行为。 例如:

      >>> try:        raise KeyboardInterrupt    finally:        print('Goodbye, world!')   Goodbye, world!KeyboardInterrupt

      以上例子不管 try 子句里面有没有发生异常,finally 子句都会执行。

      如果一个异常在 try 子句里(或者在 except 和 else 子句里)被抛出,而又没有任何的 except 把它截住,那么这个异常会在 finally 子句执行后再次被抛出。

      下面是一个更加复杂的例子(在同一个 try 语句里包含 except 和 finally 子句):

      >>> def divide(x, y):        try:            result = x / y        except ZeroDivisionError:            print("division by zero!")        else:            print("result is", result)        finally:            print("executing finally clause")   >>> divide(2, 1)result is 2.0executing finally clause>>> divide(2, 0)division by zero!executing finally clause>>> divide("2", "1")executing finally clauseTraceback (most recent call last):  File "<stdin>", line 1, in ?  File "<stdin>", line 3, in divideTypeError: unsupported operand type(s) for /: 'str' and 'str'

      预定义的清理行为

      一些对象定义了标准的清理行为,无论系统是否成功的使用了它,一旦不需要它了,那么这个标准的清理行为就会执行。

      这面这个例子展示了尝试打开一个文件,然后把内容打印到屏幕上:

      for line in open("myfile.txt"):    print(line, end="")

      以上这段代码的问题是,当执行完毕后,文件会保持打开状态,并没有被关闭。

      关键词 with 语句就可以保证诸如文件之类的对象在使用完之后一定会正确的执行他的清理方法:

      with open("myfile.txt") as f:    for line in f:        print(line, end="")

      以上这段代码执行完毕后,就算在处理过程中出问题了,文件 f 总是会关闭。


      Python 从设计之初就是一门面向对象的语言,正因为如此,在 Python 中创建一个类和对象是很容易的。本章节我们将详细介绍 Python 的面向对象编程。

      如果你以前没有接触过面向对象的编程语言,那你可能需要先了解一些面向对象语言的一些基本特征,在头脑里头形成一个基本的面向对象的概念,这样有助于你更容易的学习 Python 的面向对象编程。

      接下来我们先来简单的了解下面向对象的一些基本特征。


      Python3 面向对象技术简介

      • 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
      • 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
      • 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
      • 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
      • 局部变量:定义在方法中的变量,只作用于当前实例的类。
      • 实例变量:在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。
      • 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个 Dog 类型的对象派生自 Animal 类,这是模拟"是一个(is-a)"关系(例图,Dog 是一个 Animal)。
      • 实例化:创建一个类的实例,类的具体对象。
      • 方法:类中定义的函数。
      • 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

      和其它编程语言相比,Python 在尽可能不增加新的语法和语义的情况下加入了类机制。

      Python 中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法。

      对象可以包含任意数量和类型的数据。

      类定义

      语法格式如下:

      class ClassName:    <statement-1>    .    .    .    <statement-N>

      类实例化后,可以使用其属性,实际上,创建一个类之后,可以通过类名访问其属性。

      类对象

      类对象支持两种操作:属性引用和实例化。

      属性引用使用和 Python 中所有的属性引用一样的标准语法:obj.name

      类对象创建后,类命名空间中所有的命名都是有效属性名。所以如果类定义是这样:

      #!/usr/bin/python3class MyClass:    """一个简单的类实例"""    i = 12345    def f(self):        return 'hello world'# 实例化类x = MyClass()# 访问类的属性和方法print("MyClass 类的属性 i 为:", x.i)print("MyClass 类的方法 f 输出为:", x.f())

      实例化类:

      # 实例化类x = MyClass()# 访问类的属性和方法

      以上创建了一个新的类实例并将该对象赋给局部变量 x,x 为空的对象。

      执行以上程序输出结果为:

      MyClass 类的属性 i 为: 12345MyClass 类的方法 f 输出为: hello world

      很多类都倾向于将对象创建为有初始状态的。因此类可能会定义一个名为 __init__() 的特殊方法(构造方法),像下面这样:

      def __init__(self):    self.data = []

      类定义了 __init__() 方法的话,类的实例化操作会自动调用 __init__() 方法。所以在下例中,可以这样创建一个新的实例:

      x = MyClass()

      当然, __init__() 方法可以有参数,参数通过 __init__() 传递到类的实例化操作上。例如:

      >>> class Complex:...     def __init__(self, realpart, imagpart):...         self.r = realpart...         self.i = imagpart...>>> x = Complex(3.0, -4.5)>>> x.r, x.i(3.0, -4.5)

      类的方法

      在类的内部,使用 def 关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数:

      #!/usr/bin/python3#类定义class people:    #定义基本属性    name = ''    age = 0    #定义私有属性,私有属性在类外部无法直接进行访问    __weight = 0    #定义构造方法    def __init__(self,n,a,w):        self.name = n        self.age = a        self.__weight = w    def speak(self):        print("%s 说: 我 %d 岁。" %(self.name,self.age))# 实例化类p = people('W3Cschool',10,30)p.speak()

      执行以上程序输出结果为:

      W3Cschool 说:  10 岁。

      继承

      Python 同样支持类的继承,如果一种语言不支持继承,类就没有什么意义。派生类的定义如下所示:

      class DerivedClassName(BaseClassName1):    <statement-1>    .    .    .    <statement-N>

      需要注意圆括号中基类的顺序,若是基类中有相同的方法名,而在子类使用时未指定,Python 从左至右搜索 即方法在子类中未找到时,从左到右查找基类中是否包含方法。

      BaseClassName(示例中的基类名)必须与派生类定义在一个作用域内。除了类,还可以用表达式,基类定义在另一个模块中时这一点非常有用:

      class DerivedClassName(modname.BaseClassName):

      实例

      #!/usr/bin/python3#类定义class people:    #定义基本属性    name = ''    age = 0    #定义私有属性,私有属性在类外部无法直接进行访问    __weight = 0    #定义构造方法    def __init__(self,n,a,w):        self.name = n        self.age = a        self.__weight = w    def speak(self):        print("%s 说: 我 %d 岁。" %(self.name,self.age))#单继承示例class student(people):    grade = ''    def __init__(self,n,a,w,g):        #调用父类的构函        people.__init__(self,n,a,w)        self.grade = g    #覆写父类的方法    def speak(self):        print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))s = student('ken',10,60,3)s.speak()

      执行以上程序输出结果为:

      ken 说:  10 岁了,我在读 3 年级

      多继承

      Python 同样有限的支持多继承形式。多继承的类定义形如下例:

      class DerivedClassName(Base1, Base2, Base3):    <statement-1>    .    .    .    <statement-N>

      需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,Python 从左至右搜索 即方法在子类中未找到时,从左到右查找父类中是否包含方法。

      #!/usr/bin/python3#类定义class people:    #定义基本属性    name = ''    age = 0    #定义私有属性,私有属性在类外部无法直接进行访问    __weight = 0    #定义构造方法    def __init__(self,n,a,w):        self.name = n        self.age = a        self.__weight = w    def speak(self):        print("%s 说: 我 %d 岁。" %(self.name,self.age))#单继承示例class student(people):    grade = ''    def __init__(self,n,a,w,g):        #调用父类的构函        people.__init__(self,n,a,w)        self.grade = g    #覆写父类的方法    def speak(self):        print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))#另一个类,多重继承之前的准备class speaker():    topic = ''    name = ''    def __init__(self,n,t):        self.name = n        self.topic = t    def speak(self):        print("我叫 %s,我是一个演说家,我演讲的主题是 %s"%(self.name,self.topic))#多重继承class sample(speaker,student):    a =''    def __init__(self,n,a,w,g,t):        student.__init__(self,n,a,w,g)        speaker.__init__(self,n,t)test = sample("Tim",25,80,4,"Python")test.speak()   #方法名同,默认调用的是在括号中排前地父类的方法

      执行以上程序输出结果为:

      我叫 Tim,我是一个演说家,我演讲的主题是 Python

      方法重写

      如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法,实例如下:

      #!/usr/bin/python3class Parent:        # 定义父类   def myMethod(self):      print ('调用父类方法')class Child(Parent): # 定义子类   def myMethod(self):      print ('调用子类方法')c = Child()          # 子类实例c.myMethod()         # 子类调用重写方法

      执行以上程序输出结果为:

      调用子类方法

      类属性与方法

      类的私有属性

      __private_attrs:两个下划线开头,声明该属性为私有,不能在类地外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs

      类的方法

      在类地内部,使用 def 关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数 self, 且为第一个参数

      类的私有方法

      __private_method:两个下划线开头,声明该方法为私有方法,不能在类地外部调用。在类的内部调用 slef.__private_methods

      实例如下:

      #!/usr/bin/python3class JustCounter:    __secretCount = 0  # 私有变量    publicCount = 0    # 公开变量    def count(self):        self.__secretCount += 1        self.publicCount += 1        print (self.__secretCount)counter = JustCounter()counter.count()counter.count()print (counter.publicCount)print (counter.__secretCount)  # 报错,实例不能访问私有变量

      执行以上程序输出结果为:

      122Traceback (most recent call last):  File "test.py", line 16, in <module>    print (counter.__secretCount)  # 报错,实例不能访问私有变量AttributeError: 'JustCounter' object has no attribute '__secretCount'

      类的专有方法:

      • __init__ : 构造函数,在生成对象时调用
      • __del__ : 析构函数,释放对象时使用
      • __repr__ : 打印,转换
      • __setitem__ : 按照索引赋值
      • __getitem__: 按照索引获取值
      • __len__: 获得长度
      • __cmp__: 比较运算
      • __call__: 函数调用
      • __add__: 加运算
      • __sub__: 减运算
      • __mul__: 乘运算
      • __div__: 除运算
      • __mod__: 求余运算
      • __pow__: 乘方

      运算符重载

      Python 同样支持运算符重载,我么可以对类的专有方法进行重载,实例如下:

      #!/usr/bin/python3class Vector:   def __init__(self, a, b):      self.a = a      self.b = b   def __str__(self):      return 'Vector (%d, %d)' % (self.a, self.b)      def __add__(self,other):      return Vector(self.a + other.a, self.b + other.b)v1 = Vector(2,10)v2 = Vector(5,-2)print (v1 + v2)

      以上代码执行结果如下所示:

      Vector(7,8)


      Python 语言参考手册描述了具体语法和语义,并介绍了与 Python 一起发布的标准库。本文还描述了发行版中通常包含的一些可选组件。

      操作系统接口

      os 模块提供了不少与操作系统相关联的函数。

      >>> import os>>> os.getcwd()      # 返回当前的工作目录'C:Python34'>>> os.chdir('/server/accesslogs')   # 修改当前的工作目录>>> os.system('mkdir today')   # 执行系统命令 mkdir 0

      建议使用 "import os" 风格而非 "from os import *"。这样可以保证随操作系统不同而有所变化的 os.open() 不会覆盖内置函数 open()。

      在使用 os 这样的大型模块时内置的 dir() 和 help() 函数非常有用:

      >>> import os>>> dir(os)<returns a list of all module functions>>>> help(os)<returns an extensive manual page created from the module's docstrings>

      针对日常的文件和目录管理任务,:mod:shutil 模块提供了一个易于使用的高级接口:

      >>> import shutil>>> shutil.copyfile('data.db', 'archive.db')>>> shutil.move('/build/executables', 'installdir')

      文件通配符

      glob 模块提供了一个函数用于从目录通配符搜索中生成文件列表:

      >>> import glob>>> glob.glob('*.py')['primes.py', 'random.py', 'quote.py']

      命令行参数

      通用工具脚本经常调用命令行参数。这些命令行参数以链表形式存储于 sys 模块的 argv 变量。例如在命令行中执行 "python demo.py one two three" 后可以得到以下输出结果:

      >>> import sys>>> print(sys.argv)['demo.py', 'one', 'two', 'three']

      错误输出重定向和程序终止

      sys 还有 stdin,stdout 和 stderr 属性,即使在 stdout 被重定向时,后者也可以用于显示警告和错误信息。

      >>> sys.stderr.write('Warning, log file not found starting a new one
      ')Warning, log file not found starting a new one

      大多脚本的定向终止都使用 "sys.exit()"。


      字符串正则匹配

      re 模块为高级字符串处理提供了正则表达式工具。对于复杂的匹配和处理,正则表达式提供了简洁、优化的解决方案:

      >>> import re>>> re.findall(r'f[a-z]*', 'which foot or hand fell fastest')['foot', 'fell', 'fastest']>>> re.sub(r'([a-z]+) 1', r'1', 'cat in the the hat')'cat in the hat'

      如果只需要简单的功能,应该首先考虑字符串方法,因为它们非常简单,易于阅读和调试:

      >>> 'tea for too'.replace('too', 'two')'tea for two'

      数学

      math 模块为浮点运算提供了对底层 C 函数库的访问:

      >>> import math>>> math.cos(math.pi / 4)0.70710678118654757>>> math.log(1024, 2)10.0

      random 提供了生成随机数的工具。

      >>> import random>>> random.choice(['apple', 'pear', 'banana'])'apple'>>> random.sample(range(100), 10)   # sampling without replacement[30, 83, 16, 4, 8, 81, 41, 50, 18, 33]>>> random.random()    # random float0.17970987693706186>>> random.randrange(6)    # random integer chosen from range(6)4

      访问 互联网

      有几个模块用于访问互联网以及处理网络通信协议。其中最简单的两个是用于处理从 urls 接收的数据的 urllib.request 以及用于发送电子邮件的 smtplib:

      >>> from urllib.request import urlopen>>> for line in urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'):...     line = line.decode('utf-8')  # Decoding the binary data to text....     if 'EST' in line or 'EDT' in line:  # look for Eastern Time...         print(line)<BR>Nov. 25, 09:43:32 PM EST>>> import smtplib>>> server = smtplib.SMTP('localhost')>>> server.sendmail('soothsayer@example.org', 'jcaesar@example.org',... """To: jcaesar@example.org... From: soothsayer@example.org...... Beware the Ides of March.... """)>>> server.quit()

      注意第二个例子需要本地有一个在运行的邮件服务器。


      日期和时间

      datetime 模块为日期和时间处理同时提供了简单和复杂的方法。

      支持日期和时间算法的同时,实现的重点放在更有效的处理和格式化输出。

      该模块还支持时区处理:

      >>> # dates are easily constructed and formatted>>> from datetime import date>>> now = date.today()>>> nowdatetime.date(2003, 12, 2)>>> now.strftime("%m-%d-%y. %d %b %Y is a %A on the %d day of %B.")'12-02-03. 02 Dec 2003 is a Tuesday on the 02 day of December.'>>> # dates support calendar arithmetic>>> birthday = date(1964, 7, 31)>>> age = now - birthday>>> age.days14368

      数据压缩

      以下模块直接支持通用的数据打包和压缩格式:zlib,gzip,bz2,zipfile,以及 tarfile。

      >>> import zlib>>> s = b'witch which has which witches wrist watch'>>> len(s)41>>> t = zlib.compress(s)>>> len(t)37>>> zlib.decompress(t)b'witch which has which witches wrist watch'>>> zlib.crc32(s)226805979

      性能度量

      有些用户对了解解决同一问题的不同方法之间的性能差异很感兴趣。Python 提供了一个度量工具,为这些问题提供了直接答案。

      例如,使用元组封装和拆封来交换元素看起来要比使用传统的方法要诱人的多,timeit 证明了现代的方法更快一些。

      >>> from timeit import Timer>>> Timer('t=a; a=b; b=t', 'a=1; b=2').timeit()0.57535828626024577>>> Timer('a,b = b,a', 'a=1; b=2').timeit()0.54962537085770791

      相对于 timeit 的细粒度,:mod:profile 和 pstats 模块提供了针对更大代码块的时间度量工具。


      测试模块

      开发高质量软件的方法之一是为每一个函数开发测试代码,并且在开发过程中经常进行测试

      doctest 模块提供了一个工具,扫描模块并根据程序中内嵌的文档字符串执行测试。

      测试构造如同简单的将它的输出结果剪切并粘贴到文档字符串中。

      通过用户提供的例子,它强化了文档,允许 doctest 模块确认代码的结果是否与文档一致:

      def average(values):    """Computes the arithmetic mean of a list of numbers.    >>> print(average([20, 30, 70]))    40.0    """    return sum(values) / len(values)import doctestdoctest.testmod()   # 自动验证嵌入测试

      unittest 模块不像 doctest 模块那么容易使用,不过它可以在一个独立的文件里提供一个更全面的测试集:

      import unittestclass TestStatisticalFunctions(unittest.TestCase):    def test_average(self):        self.assertEqual(average([20, 30, 70]), 40.0)        self.assertEqual(round(average([1, 5, 7]), 1), 4.3)        self.assertRaises(ZeroDivisionError, average, [])        self.assertRaises(TypeError, average, 20, 30, 70)unittest.main() # Calling from the command line invokes all tests


      Python 3


      Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。



      查看 Python 版本

      我们可以在命令提示符/终端中使用以下命令来查看我们使用的 Python 版本:

      python -V

      以上命令执行结果如下:

      Python 3.8.5

      在命令提示符/终端中输入python并回车可以进入 Python 的交互式编程模式,在这里也可以查看版本:

      Python 3.8.5 (tags/v3.8.5:580fbb0, Jul 20 2020, 15:57:54) [MSC v.1924 64 bit (AMD64)] on win32

      Type "help", "copyright", "credits" or "license" for more information.

      >>>


      第一个 Python3.x 程序

      1. 对于大多数程序语言,第一个入门编程代码便是"Hello World!",以下代码为使用 Python 输出"Hello World!":

      #!/usr/bin/python3print("Hello, World!")
      • ​#!/usr/bin/python3​​ :指定用什么解释器运行脚本以及解释器所在的位置,如果解释器没有装在/usr/bin/目录,改成其所在目录就行了,或者更通用的方法是:
        #!/usr/bin/env python3​。
      • 在Windows环境下这并不是必要的代码。

      2. 你可以将以上代码保存在 ​hello.py​ 文件中并使用 python 命令执行该脚本文件。

      python hello.py

      3. 以上命令输出结果为:

      Hello, World!


       本节对学习python编程没有太多实质性的帮助,但本节介绍了一些python的历史和特性,有兴趣的小伙伴可以了解一下。

      Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。

      Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有比其他语言更有特色语法结构。

      • Python 是一种解释型语言: 这意味着开发过程中没有了编译这个环节。类似于PHP和Perl语言。
      • Python 是交互式语言: 这意味着,您可以在一个 Python 提示符 >>> 后直接执行代码。
      • Python 是面向对象语言: 这意味着Python支持面向对象的风格或代码封装在对象的编程技术。
      • Python 是初学者的语言:Python 对初级程序员而言,是一种伟大的语言,它支持广泛的应用程序开发,从简单的文字处理到服务器再到游戏,它都可以胜任。

      Python 发展历史

      Python 是由 Guido van Rossum 在八十年代末和九十年代初,在荷兰国家数学和计算机科学研究所设计出来的。

      Python 本身也是由诸多其他语言发展而来的,这包括 ABC、Modula-3、C、C++、Algol-68、SmallTalk、Unix shell 和其他的脚本语言等等。

      像 Perl 语言一样,Python 源代码同样遵循 GPL(GNU General Public License)协议。

      现在 Python 是由一个核心开发团队在维护,Guido van Rossum 仍然占据着至关重要的作用,指导其进展。

      Python 2.0 于 2000 年 10 月 16 日发布,增加了实现完整的垃圾回收,并且支持 Unicode。

      Python 3.0 于 2008 年 12 月 3 日发布,此版不完全兼容之前的 Python 源代码。不过,很多新特性后来也被移植到旧的Python 2.6/2.7版本。

      Python 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。

      Python 2.7 被确定为最后一个 Python 2.x 版本,它除了支持 Python 2.x 语法外,还支持部分 Python 3.1 语法。

      Python 特点

      • 1.易于学习:Python有相对较少的关键字,结构简单,和一个明确定义的语法,学习起来更加简单。
      • 2.易于阅读:Python代码定义的更清晰。
      • 3.易于维护:Python的成功在于它的源代码是相当容易维护的。
      • 4.一个广泛的标准库:Python的最大的优势之一是丰富的库,跨平台的,在UNIX,Windows和Macintosh兼容很好。
      • 5.互动模式:互动模式的支持,您可以从终端输入执行代码并获得结果的语言,互动的测试和调试代码片断。
      • 6.可移植:基于其开放源代码的特性,Python已经被移植(也就是使其工作)到许多平台。
      • 7.可扩展:如果你需要一段运行很快的关键代码,或者是想要编写一些不愿开放的算法,你可以使用C或C++完成那部分程序,然后从你的Python程序中调用。
      • 8.数据库:Python提供所有主要的商业数据库的接口。
      • 9.GUI编程:Python支持GUI可以创建和移植到许多系统调用。
      • 10.可嵌入: 你可以将Python嵌入到C/C++程序,让你的程序的用户获得"脚本化"的能力。

      Python 应用

      • 网站建设,以下网站应用了python进行web开发:
      • Youtube - 视频社交网站
      • Reddit - 社交分享网站
      • Dropbox - 文件分享服务
      • 豆瓣网 - 图书、唱片、电影等文化产品的资料数据库网站
      • 知乎 - 一个问答网站
      • 果壳 - 一个泛科技主题网站
      • Bottle - Python微Web框架
      • EVE - 网络游戏EVE大量使用Python进行开发
      • Blender - 使用Python作为建模工具与GUI语言的开源3D绘图软件
      • Inkscape - 一个开源的SVG矢量图形编辑器。
      • 机器学习与人工智能 - TensorFlow,Keras,pytorch等机器学习库让python成为最适合机器学习的语言
      • 数据分析与数据挖掘 - 各式各样的python爬虫可以帮助数据分析工程师获取数据,而丰富的python数据处理库可以处理这些数据并以可视化形式或者可调用形式展现出来
      • 科学计算和算法设计 - 曾经matlab作为科学计算的行业标杆,但现在python正在蚕食它的市场。而简单的语法让python更适合进行算法开发(算法工程师可以轻松上手算法开发)
      • IDLE - 作为python安装时自带的IDE,这款IDE就是由 Guido van Rossum 使用python+tkinter写出来的。
      • ···

      python的缺点

      有优点就会有缺点,python作为一门解释型语言,拥有了解释型语言的优点(跨平台可移植性,动态变量等)也有解释型语言的缺点(效率较低)。另外,python作为一门近乎万能的语言,就像瑞士军刀一样,他拥有很多功能,但在具体的功能上都不如一些专精的语言,当对性能有一定要求的时候,python不是好选择!

      本章节将向大家介绍 Python 最新版开发环境的安装步骤及如何进行环境配置,刚入门的新手学员可以跟着本章内容进行学习。

      本章节需要用到的Python 最新源码,二进制文档,新闻资讯等可以在 Python 的官网查看:

      Python官网

               

        你可以在以下链接中下载 Python 的文档,你可以下载 HTML、PDF 和 PostScript 等格式的文档。

        Python官方文档下载

                 



          Python 安装


          • Python 已经被移植在许多平台上(经过改动使它能够工作在不同平台上)。
          • 您需要下载适用于您使用平台的二进制代码,然后安装 Python。
          • 如果您平台的二进制代码是不可用的,你需要使用 C 编译器手动编译源代码。
          • 编译的源代码,功能上有更多的选择性, 为 Python 安装提供了更多的灵活性。

          以下为不同平台上安装 Python 的方法:

          Unix & Linux 平台安装 Python:

          以下为在 Unix & Linux 平台上安装 Python 的简单步骤:

          • 打开 WEB 浏览器访问 https://www.python.org/downloads/source/
          • 选择适用于 Unix/Linux 的源码压缩包。
          • 下载及解压压缩包 Python-3.x.x.tgz3.x.x 为你下载的对应版本号。
          • 如果你需要自定义一些选项修改 Modules/Setup

          以 Python3.8.5 版本为例:

          Python3安装包下载linux/Unix版本

          # tar -zxvf Python-3.8.5.tgz# cd Python-3.8.5# ./configure# make && make install

          检查 Python3 是否正常可用:

          # python3 -VPython 3.8.5
          python作为Linux系统的一个依赖,很多Linux系统都会默认安装python环境(甚至误删python环境会导致系统崩溃),在很长一段时间里,很多Linux系统都默认安装了python2,这时候学习python3就需要安装新版本的python3,而且由于Linux系统依赖的是python2,所以python2版本不能卸载。但随着python2停止维护结束了他的使命,大多数Linux系统已经更新到了python3版本,如果对python3的小版本没有特殊要求的话,最新的Linux系统基本可以做到不需要安装即可使用python环境(小编之前安装的centos 8内置的python版本为3.6.8,已经能基本满足普通的python学习需求了)。

          Windows 平台安装 Python:

          以下为在 Windows 平台上安装 Python 的简单步骤:

          • 打开 WEB 浏览器访问https://www.python.org/downloads/windows/
            Python安装包windows版本下载                  
          • 在下载列表中选择 Windows 平台安装包,包格式为:python-3.8.5-amd64.exe 文件 , -3.8.5 为你要安装的版本号,-amd64为你系统的版本。
          • 下载后,双击下载包,进入 Python 安装向导,安装非常简单,你只需要使用默认的设置一直点击"下一步"直到安装完成即可。

          Windows x86-64 为 64 位版本

          Windows x86 为 32 位版本

          自python3.9起,官方不再支持在win7及以下版本安装和运行python,但我们仍可通过编译源代码的形式来给win7安装更高版本的python。

          MAC 平台安装 Python:

          MAC 系统一般都自带有 Python2.7 版本 的环境,你也可以在链接 https://www.python.org/downloads/mac-osx/ 上下载最新版安装。

          Python安装包官方下载MacOS版本



          环境变量配置

          • 程序和可执行文件可以在许多目录,而这些路径很可能不在操作系统提供可执行文件的搜索路径中。
          • path (路径)存储在环境变量中,这是由操作系统维护的一个命名的字符串。这些变量包含可用的命令行解释器和其他程序的信息。
          • Unix 或 Windows 中路径变量为 PATH(UNIX 区分大小写,Windows 不区分大小写)。
          • 在 Mac OS 中,安装程序过程中改变了 python 的安装路径。如果你需要在其他目录引用 Python,你必须在 path 中添加 Python 目录。

           简单地说,​python​这个指令(还记得上一节介绍的​python -v​嘛,这就是python指令)在系统中是不存在的,安装完python后就有了python这个指令,但我们需要告诉系统,在哪里可以找到python这个指令,而path路径变量,就是起到这样一个作用。

          在 Unix/Linux 设置环境变量

          • 在 csh shell: 输入 
            setenv PATH "$PATH:/51coolma/local/bin/python"
            按下 Enter。
          • 在 bash shell (Linux) 输入 :
            export PATH="$PATH:/51coolma/local/bin/python" 
            按下 Enter 。
          • 在 sh 或者 ksh shell 输入: 
            PATH="$PATH:/51coolma/local/bin/python"
            按下 Enter。

          注意: /51coolma/local/bin/python 是 Python 的安装目录。

          在 Windows 设置环境变量

           注意!在python安装的时候勾选自动添加python到path路径可可以免去配置环境这个过程,本教程介绍的是当在命令提示符中输入python显示指令不存在的情况下需要进行的操作。

          在环境变量中添加 Python 目录:

          在命令提示符中(cmd) : 输入

          path=%path%;C:Python 

          按下"Enter"。

          注意: C:Python 是 Python 的安装目录。

          也可以通过以下方式设置:

          • 右键点击"计算机",然后点击"属性"
          • 然后点击"高级系统设置"
          • 选择"系统变量"窗口下面的"Path",双击即可!
          • 然后在"​Path​"行,添加 python 安装路径即可(我的D:Python32),所以在后面,添加该路径即可。 ps:记住,路径直接用分号"​;​"隔开!
          • 最后设置成功以后,在 cmd 命令行,输入命令"​python​",就可以有相关显示。



          在win10中配置环境变量与win7类似:

          在电脑桌面右键点击此电脑,点击属性选项。

          右击进入计算机属性

          在关于页面中选择高级系统设置,点击环境变量进行环境变量的配置。

          环境变量的设置

          只需在 PATH 变量原有的变量上新增以下变量值即可:

          Python 的安装文件夹。

          python 安装文件夹下的 Scripts 文件夹。

          环境变量

           注意!添加python路径是为了配置python指令,使得python指令可以使用,而配置script文件夹则是为了配置pip指令(一个python包管理工具)。

          另外,在安装python的时候如果有勾选添加环境变量的话(下图 add python 3.9 to path),默认会将环境变量配置完毕。

          python安装界面


          Python 环境变量

          下面几个重要的环境变量,它应用于 Python:

          变量名描述
          PYTHONPATHPYTHONPATH 是 Python 搜索路径,默认我们 import 的模块都会从 PYTHONPATH 里面寻找。
          PYTHONSTARTUPPython 启动后,先寻找 PYTHONSTARTUP 环境变量,然后执行此变量指定的文件中的代码。
          PYTHONCASEOK加入 PYTHONCASEOK 的环境变量, 就会使 python 导入模块的时候不区分大小写.
          PYTHONHOME另一种模块搜索路径。它通常内嵌于的 PYTHONSTARTUP 或 PYTHONPATH 目录中,使得两个模块库更容易切换。

          运行Python

          有三种方式可以运行 Python:

          1. 交互式解释器:

          • 你可以通过命令行窗口进入 Python,并在交互式解释器中开始编写 Python 代码。
          • 你可以在 Unix、DOS 或任何其他提供了命令行或者 shell 的系统进行 Python 编码工作。
          $ python # Unix/Linux

          或者

          C:>python # Windows/DOS

          以下为Python命令行参数:

          选项描述
          -d在解析时显示调试信息
          -O生成优化代码 ( ​.pyo​ 文件 )
          -S启动时不引入查找 Python 路径的位置
          -V输出 Python 版本号
          -X从 1.6 版本之后基于内建的异常(仅仅用于字符串)已过时。
          -c cmd执行 Python 脚本,并将运行结果作为 cmd 字符串。
          file在给定的 python 文件执行 python 脚本。

          2. 命令行脚本

          在你的应用程序中通过引入解释器可以在命令行中执行 Python 脚本,如下所示:

          $ python script.py # Unix/Linux

          或者

          C:>python script.py # Windows/DOS

          注意:在执行脚本时,请检查脚本是否有可执行权限。

          3. 集成开发环境(IDE:Integrated Development Environment): PyCharm


          领取免费资料

          扫描下方二维码或打开微信搜一搜“51coolma编程狮”关注公众号回复关键词【Python123】或者【Python资料包】免费领取 Python 学习资料,包含软件安装包,电子书、思维导图等

          51coolma编程狮微信公众号

          python软件介绍

          python安装完后,在开始菜单会有如下的一个文件夹:

          python安装文件夹

          他们分别是:

          • IDLE:由python之父开发的一个小型的python开发环境,可以用来解释执行python代码,也可以用来写python脚本。
          • Python:这个就是python的解释器,可以用来解释执行python代码,使用命令行调用python命令的时候就是运行的这个程序。
          • Python Manuals:这个是python的使用手册,可以用来学习python的基础使用。
          • Python Module Docs:这个是python的模块文档,可以用来学习模块的使用。

          python代码执行方式

          python代码的执行方式有两种,一种是交互型的解释执行方式,另一种是将python写成脚本代码的形式,然后使用解释器执行,两种执行方式有所不同:

          交互型执行方式

          这种执行方式类似人与人之间的对话,写一句代码执行一句代码。这种类型类似人的交互行为,所以被称为交互执行方式,使用这种交互方式最大的特点是:在命令行界面中有​>>>​作为每行代码的开头。如下图所示:

          python解释器

          接下来本手册中的代码只要是带有>>>的都是在交互型解释器中运行后的结果,没有>>>的代码都是python脚本代码。

          进入交互型解释器的方式有如下几种方式:

          • 命令行方式:按win + r键,输入cmd,点击回车,进入命令行界面,然后输入python,点击回车,即可进入命令行界面,在命令行中输入python并按回车执行,即可进入命令行界面。
          • 运行方式:按win + r键,输入python,点击回车,即可直接进入python解释器页面。
          • 直接运行程序:安装的python中里面有一个选项是python,直接点击这个选项就可以进入python解释器。
          • IDLE:安装的python中里面有一个选项是IDLE,直接点击后进入的也是python解释器。

          IDLE shell界面

          交互型编程在代码调试中比较常见,更好的交互型编程的体验可以了解ipython或者jupyter notebook。

          如何退出?

          在交互型解释器中输入​exit()​按回车即可退出。

          退出

          如何换行&缩进?

          python以换行作为代码结束的标志(也就是说,点击换行立马执行这个代码),但这并不是绝对的,当代码的最后一个标识符是​:​时可以换行(因为出现​:​的时候都是进入代码块的情况,比如条件语句,循环语句,函数等)。

          python以缩进来区分代码块,所以在出现上述的换行情况的时候,需要搭配空格键(注意,不是Tab键!)来进行代码缩进(使用空格数并不强制,但同一代码块之间的缩进应该相同)。处于代码块内时,​>>>​会变成​...​。如下代码所示:

          >>>the_world_is_flat = True>>>if the_world_is_flat:...    print("Be careful not to fall off!")...Be careful not to fall off!

          在代码块需要结束的地方,换行后点击回车即可。

          所以上面的代码的输入方式应该是这样的:输入第一行语句,点击回车,输入第二行语句(注意末尾的冒号),点击回车,输入四个空格,输入第三行语句(该语句是代码块内的语句),回车,回车(结束这个代码块)。最后一行是代码运行结果。

           在交互型解释器中,代码如果会产生输出,会直接打印在控制台,输出和代码的区别是:代码前面有​>>>​。

          脚本代码执行方式

          这种方式是大多数编程语言执行方式(先写代码,然后一次执行),如果把代码解释比喻为做菜的话,交互型解释方式类似于看一个步骤做一个步骤,而脚本代码执行方式则是看完全部步骤后再逐步做。这种方式也是未来我们学习python编程中最常遇到的编程方式。

           不同工具(IDE)的编程方式不同,这里小编放到下一节介绍,这里我们介绍一下IDLE的脚本代码编写方式。

          点击打开IDLE,我们可以进入到python的shell(命令行,也就是交互型解释器)界面,点击File,选择New File。可以新建一个脚本代码文件(也可以使用Ctrl + N 进行新建脚本代码文件)。就会弹出一个窗口,这时候我们就可以在这个窗口里面写python代码了。

           虽然IDLE相对比较简单,但它也提供了代码着色等实用的功能,如果没有什么很好的python代码编辑器,不妨尝试一下它!

          写完代码后可点击run,选择run module(或者直接按F5),就可以运行代码了。


          初次运行需要先保存代码并给代码文件命名,后续代码更改也要重新保存代码。

          另外,IDLE也可以打开以​.py​为后缀的文件,与新建类似,点击File,选择Open...,可以打开本地的python代码文件(py代码文件以​.py​为后缀)。运行方式与新建方式相同。

           这意味着python可以使用其他的代码编辑器进行代码编写,再使用IDLE去运行,但是实际上我们不会这么做,因为执行python代码不一定要用IDLE,使用python命令也可以。这为我们使用vscode这样的代码编辑器去写代码然后使用命令行运行提供了一种可能,而vscode的插件把这样的功能实现了。在后续章节中我们将介绍如何使vscode来写python代码。

          如何使用命令行运行python脚本?

          在命令提示符中使用python命令就可以运行python脚本了,python命令的使用方法如下:

          python 要运行的文件.py

          示例:


          Q&A

          什么是命令行?

          命令行是系统提供的一种工具,可以用这些工具来执行一些系统提供的功能,常见的命令行有:Linux的终端,Windows的cmd,windows的powershell(进阶版的cmd)。

          命令行在一些工具中也存在,比如说vscode就提供了命令行窗口,python著名的IDEpycharm也有提供命令行窗口和交互型解释器的窗口。

           powershell作为微软用来替代老旧的cmd的终端,powershell拥有更强大的功能,所有在cmd上可以实现的指令在powershell上都可以实现。找不到命令提示符(或者想要尝试新事物)的小伙伴可以尝试使用。


          Linux/Unix 的系统上,Python 解释器通常被安装在 /usr/local/python3 这样的有效路径(目录)里。

          我们可以将路径 /usr/local/python3/bin 添加到您的 Linux/Unix 操作系统的环境变量中(最好参照您 Python 的安装路径进行添加),这样您就可以通过 shell 终端输入下面的命令来启动 Python 。

          $ PATH=$PATH:/user/local/python3/bin/python #设置环境变量$ python3 --vesionPython 3.7.6

          在 Window 系统下你可以通过以下命令来设置 Python 的环境变量,假设你的 Python 安装在 C:Python37 下:

          set path=%path%;C:python37

          交互式编程

          打开 IDLE,默认的就是交互式编程,类似于一个 cmd 窗口。

          我们可以在命令提示符中输入 "Python" 命令来启动 Python 解释器:

          $ python3

          执行以上命令后,出现如下窗口信息:

          $ python3Python 3.4。0 (default, Mar 16 2014, 09:25:04)[GCC 4.8.2] on linuxType "help", "copyright", "credits" or "license" for more information.>>>

          在 Python 提示符中输入以下语句,然后按回车键查看运行效果:

          print ("Welcome to W3Cschool!");

          以上命令执行结果如下:


          当键入一个多行结构时,续行是必须的。我们可以看下如下 if 语句:

          >>> the_world_is_flat = True>>> if the_world_is_flat:...     print("Be careful not to fall off!")...Be careful not to fall off!

          脚本式编程

          点击 File→New 后新建脚本文件,在此文件下进行的是脚本式编程。

          将如下代码拷贝至 W3C.py 文件中:

          print ("Welcome to W3Cschool!");

          通过以下命令执行该脚本:

          python W3C.py

          输出结果为:

          Welcome to W3Cschool!

          在 Linux/Unix 系统中,你可以在脚本顶部添加以下命令让 Python 脚本可以像 SHELL 脚本一样可直接执行:

          #! /usr/bin/env python3.7

          然后修改脚本权限,使其有执行权限,命令如下:

          $ chmod +x W3C.py

          执行以下命令:

          ./hello.py

          输出结果为:

          Welcome to W3Cschool!


          VSCode(全称:Visual Studio Code)是一款由微软开发的跨平台免费源代码编辑器。VSCode 开发环境非常简单易用,仅需要安装相关的插件进行简易的配置就可以与原有的python环境组成一套具有简单的代码调试运行的开发工具。对于轻量级的python开发和python学习是比较友好的。优秀的代码提示和更多插件功能让VSCode的使用体验不亚于知名pythonIDE—pycharm。

          准备工作:

          • 安装 Python 3
          • 安装 VS Code
          • 安装 VS Code Python 扩展和Pylance拓展

          安装 VS Code

          VSCode 安装比较简单,打开官网 https://code.visualstudio.com/,下载软件包,一步步安装即可,安装过程注意安装路径设置、环境变量默认自动添加到系统中,勾选以下所有选项:

          安装 VS Code Python 扩展和Pylance拓展

          接着我们安装 VS Code Python 扩展:


          Python扩展将自动安装Pylance和Jupyter扩展,以便在使用Python文件和Jupyter笔记本时获得最佳体验。

          创建一个 Python 代码文件

          打开 VScode,然后点击新建文件:


          点击选择语言:


          在搜索框输入 Python,选中 Python 选项:


          输入代码:

          print("W3Cschool")

          右击鼠标,选择在交互式窗口运行文件,如果有提示需要安装内核,直接点安装即可(没有安装会一直显示在连接 Python 内核):(这里VSCode会使用python的pip进行安装,部分版本会安装失败,小编在尝试的时候使用python3.8版本失败了,3.7版本成功了)


          另外,我们也可以打开一个已存在的文件或目录(文件夹),比如我们打开一个 pythonproject,你也可以自己创建一个:


          然后我们创建一个 test.py 文件,点击下面新建文件图标,输入文件名 test.py:


          注:pythonproject 里面包含了一个 .vscode 文件夹,是一些配置信息,可以先不用管。

          在 test.py 输入以下代码:

          print("W3Cschool")

          点击右上角绿色图标,即可运行:


          可以右击文件,选择"在终端中运行 Python 文件":


          当然也可以在代码窗口上右击鼠标,选择"在终端中运行 Python 文件"。



          本章节将一些Python3基础语法整理成手册,方便各位在日常使用和学习时查阅,包含了编码、标识符、保留字、注释、缩进、字符串等常用内容。

          注意,这部分内容是后续学习的一个基础和预览,请不要随意跳过这个章节的学习!

          编码

          默认情况下,Python 3 源码文件以 UTF-8 编码,所有字符串都是 unicode 字符串。 当然你也可以为源码文件指定不同的编码:

          # -*- coding: cp-1252 -*-

          标识符

          • 第一个字符必须是字母表中字母或下划线'_'。
          • 标识符的其他的部分有字母、数字和下划线组成。
          • 标识符对大小写敏感。

          在 Python 3中,非 ASCII 编码的标识符也是允许的了。


          Python 保留字

          保留字即关键字,我们不能把它们用作任何标识符名称。Python 的标准库提供了一个关键词模块,我们可以使用它来查看当前版本的所有保留字:

          >>> import keyword>>> keyword.kwlist

          ['False', 'None', 'True', '__peg_parser__', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']

          上面代码是在解释器执行的结果,写成python脚本代码应该写成如下样式(后续代码可能会有两种版本的代码块,但并不会多做解释,望读者周知!):
          import keywordprint(keyword.kwlist)


          注释

          Python 中单行注释以 # 开头,多行注释采用三对单引号(''')或者三对双引号(""")将注释括起来。

          #这是单行注释"""这是多行注释这是多行注释"""'''也可以用三个单引号来进行多行注释'''
          实际上python注释只有一种,就是单行注释,多行注释的这种使用方法类似于java的javadoc,三引号的这种使用方法实际上是用来声明多行长字符串的。

          缩进

          Python 最具特色的就是使用缩进来表示代码块。缩进的空格数是可变的,但是同一个代码块的语句必须包含相同的缩进空格数


          标准数据类型

          Python 中有六个标准的数据类型:

          • Number(数字)
          • String(字符串)
          • List(列表)
          • Tuple(元组)
          • Set(集合)
          • Dictionary(字典)

          Python3 的六个标准数据类型中:

          • 不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);
          • 可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。

           可变数据和不可变数据是相对于引用地址来说的,不可变数据类型不允许变量的值发生变化,如果改变了的变量的值,相当于新建了一个对象,而对于相同的值的对象,内部会有一个引用计数来记录有多少个变量引用了这个对象。可变数据类型允许变量的值发生变化。对变量进行修改操作只会改变变量的值,不会新建对象,变量引用的地址也不会发生变化,不过对于相同的值的不同对象,在内存中则会存在不同的对象,即每个对象都有自己的地址,相当于内存中对于同值的对象保存了多份,这里不存在引用计数,是实实在在的对象。

          简单地讲,可变数据和不可变数据的“变”是相对于引用地址来说的,不是不能改变其数据,而是改变数据的时候会不会改变变量的引用地址。


          类型判断

          python可以用type函数来检查一个变量的类型,使用方法如下:

          >>> x = "W3Cschool">>> type(x)<type 'str'>>>> x=100>>> type(x)<type 'int'>>>> x=('1','2','3')>>> type(x)<type 'tuple'>>>> x = ['1','2','3']>>> type(x)<type 'list'>

          在脚本代码中的使用:

          x = "W3Cschool"print(type(x))

          字符串

          • Python 中单引号和双引号使用完全相同,但单引号和双引号不能匹配。
          • 使用三对引号('''或""")可以囊括一个多行字符串。
          • 与其他语言相似,python也使用 ''作为转义字符
          • 自然字符串, 通过在字符串前加 r 或 R。 如 r"this is a line with " 则 会显示,并不是换行。
          • Python 允许处理 unicode 字符串,加前缀 u 或 U, 如 u"this is an unicode string"。
          • 字符串是不可变的。
          • 按字面意义级联字符串,如"this " "is " "string"会被自动转换为this is string。
          • 字符串可以用 + 运算符连接在一起,用 * 运算符重复。
          • Python 中的字符串有两种索引方式,从左往右以 0 开始,从右往左以 -1 开始。
          • Python中的字符串不能改变(详见上一小点的引用)。
          • Python 没有单独的字符类型,一个字符就是长度为 1 的字符串。
          • 字符串的截取的语法格式如下:变量 [头下标: 尾下标: 步长]

           关于字符串的更多内容,请前往字符串小节进行学习。

          word = '字符串'sentence = "这是一个句子。"paragraph = """这是一个段落,可以由多行组成"""

          实例:

          #!/usr/bin/python3 str='W3Cschool' print(str)                 # 输出字符串print(str[0:-1])           # 输出第一个到倒数第二个的所有字符print(str[0])              # 输出字符串第一个字符print(str[2:5])            # 输出从第三个开始到第五个的字符print(str[2:])             # 输出从第三个开始后的所有字符print(str[1:5:2])          # 输出从第二个开始到第五个且每隔两个的字符print(str * 2)             # 输出字符串两次print(str + '你好')         # 连接字符串 print('------------------------------') print('hello
          W3Cschool')      # 使用反斜杠()+n转义特殊字符print(r'hello
          W3Cschool')     # 在字符串前面添加一个 r,表示原始字符串,不会发生转义

          以上实例输出结果:

          W3CschoolW3CschooWCscCschool3sW3CschoolW3CschoolW3Cschool你好------------------------------helloW3Cschoolhello
          W3Cschool

          这里的 r 指 raw,即 raw string,会自动将反斜杠转义,例如:

          >>> print('
          ')       # 输出空行>>> print(r'
          ')      # 输出 
          >>>
          

          空行

          函数之间或类的方法之间用空行分隔,表示一段新的代码的开始。类和函数入口之间也用两行空行分隔,以突出函数入口的开始。

          空行与代码缩进不同,空行并不是 Python 语法的一部分。书写时不插入空行,Python 解释器运行也不会出错。但是空行的作用在于分隔两段不同功能或含义的代码,便于日后代码的维护或重构。

          记住:空行也是程序代码的一部分。

           在PEP8中介绍了一些python代码的格式,其中介绍了函数之间要有两行空行,如果python代码没有使用两行空行的话,部分IDE会出现修改提示(比如pycharm)。这样的代码不影响运行,但对于代码阅读不利,


          输入&等待用户输入

          input函数可以用来接受输入,它可以传入一个字符串,当input函数调用的时候,会在控制台打印这个字符串(所以这个字符串通常被用来做输入的提示信息)。

           input函数会读取输入内容直到读到回车,也就是说,内容输入完毕后要按回车键才能执行。

          input("这是一个简单的input信息") # 这是一个简单的input样例,他输出input信息并接受一个字符串x=input("请输入X的值:") # 这是一个常见的input样例,他输出提示信息,然后接受一个字符串并将值传递给一个变量Xprint(x) # 打印变量,可以看到输入的x的值print(type(x)) #查看这个变量的类型x = int(input("请输入一个数值:")) # 配合强制类型转换,可以将字符串转变为int类型(字符串类型不能参与计算)# 也可以分步写成:#x=input("请输入一个数值:") # 接受一个字符串#x=int(x)   #将x转换为int型# 这里强制转换也可以转换为其他类型,详细的转换方法请参考基本数据类型的强制转换相关内容print(x) # 打印变量,可以看到输入的x的值print(type(x)) #查看这个变量的类型input("
          
          按下 enter 键后退出。") # 其实这里并没有接受任何内容,input函数以enter作为结尾,所以只有输入回车后才会结束input函数

          以上代码中 ," "在结果输出前会输出两个新的空行。一旦用户按下 enter 键时,程序将退出。


          同一行显示多条语句

          Python 可以在同一行中使用多条语句,语句之间使用分号 (;) 分割,以下是一个简单的实例:

          实例:

          #!/usr/bin/python3 import sys; x = 'W3Cschool'; sys.stdout.write(x + '
          ')

          使用脚本执行以上代码,输出结果为:

          W3Cschool

          使用交互式命令行执行,输出结果为:

          >>> import sys; x = 'W3Cschool'; sys.stdout.write(x + '
          ')
          W3Cschool
          10

          此处的 10 表示字符数。

           python以回车作为语句结束的标志,一行一句语句的特色使得Python更加易读,而在一行中显示多条语句的这种行为会破坏python的可读性,不建议使用!


          多个语句构成代码组

          缩进相同的一组语句构成一个代码块,我们称之代码组。

          像 if、while、def 和 class 这样的复合语句,首行以关键字开始,以冒号 ( : ) 结束,该行之后的一行或多行代码构成代码组。

          我们将首行及后面的代码组称为一个子句 (clause)。

          如下实例:

          if expression : 
            suite
          elif expression :
            suite
          else :
            suite

          print 输出

          print函数是python的基本输出函数,他可以将变量输出(或者说,打印)到控制台。在第一个python程序中,我们就用到了print函数:

          #!/usr/bin/python3print("Hello, World!") #"Hello,World!"是一个字符串变量str = "Hello,World!"print(str) #上一种helloworld的另一种写法

          print 默认输出是换行的,如果要实现不换行需要在变量末尾加上 end="":

          实例:

          #!/usr/bin/python3 x="a"y="b"# 换行输出print( x )print( y ) print('---------')# 不换行输出print( x, end=" " )print( y, end=" " )print()

          以上实例执行结果为:

          a
          b
          ---------
          a b
          关于print的内容,本章只是粗略介绍,目的是为了能够基础使用print函数。后续章节中有print函数的详细介绍。

          import 与 from...import

          在 Python 用 import 或者 from...import 来导入相应的模块。

          将整个模块 (somemodule) 导入,格式为:​ import somemodule

          从某个模块中导入某个函数,格式为:​ from somemodule import somefunction

          从某个模块中导入多个函数,格式为:​ from somemodule import firstfunc, secondfunc, thirdfunc

          将某个模块中的全部函数导入,格式为:​ from somemodule import *

          导入 sys 模块

          import sysprint('================Python import mode==========================')print ('命令行参数为:')for i in sys.argv:    print (i)print ('
           python 路径为',sys.path)

          导入 sys 模块的 argv,path 成员

          from sys import argv,path  #  导入特定的成员 print('================python from import===================================')print('path:',path) # 因为已经导入path成员,所以此处引用时不需要加sys.path

          命令行参数

          很多程序可以执行一些操作来查看一些基本信息,Python 可以使用 -h 参数查看各参数帮助信息:

          $ python -h
          usage: python [option] ... [-c cmd | -m mod | file | -] [arg] ...
          Options and arguments (and corresponding environment variables):
          -c cmd : program passed in as string (terminates option list)
          -d     : debug output from parser (also PYTHONDEBUG=x)
          -E     : ignore environment variables (such as PYTHONPATH)
          -h     : print this help message and exit

          [ etc. ]



          现在,我们能使用 Python 完成比 ​2+2​ 更复杂的工作。在下例里,我们能写出一个初步的斐波纳契数列如下:

          #!/usr/bin/python3# Fibonacci series: 斐波纳契数列# 两个元素的总和确定了下一个数a, b = 0, 1while b < 10:    print(b)    a, b = b, a+b

          有关斐波那契数列的具体问题可在 斐波纳契奇数求和算法挑战 教程中进一步了解。

          其中代码​ a, b = b, a + b​ 的计算方式为先计算右边的表达式,然后同时赋值给左边,等价于:

          n = bm = a + ba = nb = m

          执行以上程序,输出结果为:

          112358

          这个例子介绍了几个新特征。

          • 第一行包含了一个复合赋值:变量 a 和 b 同时得到新值 0 和 1。
          • 最后一行也使用了复合赋值的方法:等价于 c = a,a = b,b = b + c。


          接下来尝试输出变量值:

          i = 1024 * 1024print('i 的值为:', i)

          执行以上程序,输出结果为:

          i 的值为: 1048576

          end 关键字

          关键字 end 可以用于将结果输出到同一行,或者在输出的末尾添加不同的字符,实例如下:

          # 两个元素的总和确定了下一个数a, b = 0, 1while b < 1024:    print(b, end=',')    a, b = b, a+b

          执行以上程序,输出结果为:

          1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,

          最后尝试使用 if 条件控制  

          age = int(input("请输入你家狗狗的年龄: "))print("")if age < 0:	print("请输入正确的年龄。")elif age == 1:	print("相当于 14 岁的人。")elif age == 2:	print("相当于 22 岁的人。")elif age > 2:	human = 22 + (age -2)*5	print("对应人类年龄: ", human)### 退出提示,本地环境下可以使用这样的退出提示使代码更易用input('点击 enter 键退出')


          在 Python 中,变量就是变量,它没有类型,我们所说的"类型"是变量所指的内存中对象的类型。

          Python 3 中有六个标准的数据类型:

          • Numbers(数字)
          • String(字符串)
          • List(列表)
          • Tuple(元组)
          • Sets(集合)
          • Dictionaries(字典)

          Numbers(数字)

          Python 3 支持 int(整型)、float(浮点型)、bool(布尔型)、complex(复数)。

          数值类型的赋值和计算都是很直观的,就像大多数语言一样。内置的 type() 函数可以用来查询变量所指的对象类型。

          >>> a, b, c, d = 20, 5.5, True, 4+3j>>> print(type(a), type(b), type(c), type(d))<class 'int'><class 'float'><class 'bool'><class 'complex'>

          此外还可以用isinstance来判断:

          >>>a=111>>>isinstance(a,int)True>>>

          isinstance和type的区别在于:

          • type()不会认为子类是一种父类类型。
          • isinstance()会认为子类是一种父类类型。
          >>> class A:...     pass... >>> class B(A):...     pass... >>> isinstance(A(), A)True>>> type(A()) == A True>>> isinstance(B(), A)True>>> type(B()) == AFalse

          注意:在 Python2 中是没有布尔型的,它用数字 0 表示 False,用 1 表示 True。到 Python3 中,把 True 和 False 定义成关键字了,但它们的值还是 1 和 0,它们可以和数字相加。

          当你指定一个值时,Number 对象就会被创建:

          var1 = 1var2 = 10

          您也可以使用 del 语句删除一些对象引用。

          del 语句的语法是:

          del var1[,var2[,var3[....,varN]]]

          您可以通过使用 del 语句删除单个或多个对象。例如:

          del vardel var_a, var_b

          数值运算:

          >>> 5 + 4  # 加法9>>> 4.3 - 2 # 减法2.3>>> 3 * 7  # 乘法21>>> 2 / 4  # 除法,得到一个浮点数0.5>>> 2 // 4 # 除法,得到一个整数0>>> 17 % 3 # 取余 2>>> 2 ** 5 # 乘方32

          注意:

          • 1、Python 可以同时为多个变量赋值,如 a, b = 1, 2。
          • 2、一个变量可以通过赋值指向不同类型的对象。
          • 3、数值的除法(/)总是返回一个浮点数,要获取整数使用​//​操作符。
          • 4、在混合计算时,Python 会把整型转换成为浮点数。

          String(字符串)

          Python 中的字符串 str 用单引号(' ')或双引号 (" ") 括起来,同时使用反斜杠 () 转义特殊字符。

          >>> s = 'Yes,he doesn't'>>> print(s, type(s), len(s))Yes,he doesn't  <class 'str'> 14

          如果你不想让反斜杠发生转义,可以在字符串前面添加一个 r,表示原始字符串:

          >>> print('C:some
          ame')C:someame>>> print(r'C:some
          ame')C:some
          ame

          另外,反斜杠可以作为续行符,表示下一行是上一行的延续。还可以使用"""..."""或者'''...'''跨越多行。

          字符串可以使用 + 运算符串连接在一起,或者用 * 运算符重复:

          >>> print('str'+'ing', 'my'*3)string mymymy

          Python 中的字符串有两种索引方式,第一种是从左往右,从 0 开始依次增加;第二种是从右往左,从 -1 开始依次减少。

          注意,没有单独的字符类型,一个字符就是长度为 1 的字符串。

          >>> word = 'Python'>>> print(word[0], word[5])P n>>> print(word[-1], word[-6])n P

          还可以对字符串进行切片,获取一段子串。用冒号分隔两个索引,形式为变量[头下标:尾下标]。

          截取的范围是前闭后开的(头下标取,尾下标不取),并且两个索引都可以省略:

          >>> word = 'ilovepython'>>> word[1:5]'love'>>> word[:]'ilovepython'>>> word[5:]'python'>>> word[-10:-6]'love'

          与 C 字符串不同的是,Python 字符串不能被改变。向一个索引位置赋值,比如 word[0] = 'm' 会导致错误

          注意:

          • 1、反斜杠可以用来转义,使用 r 可以让反斜杠不发生转义。
          • 2、字符串可以用 + 运算符连接在一起,用 * 运算符重复。
          • 3、Python 中的字符串有两种索引方式,从左往右以 0 开始,从右往左以 -1 开始。
          • 4、Python 中的字符串不能改变。

          List(列表)

          List(列表) 是 Python 中使用最频繁的数据类型。

          列表是写在方括号之间、用逗号分隔开的元素列表。列表中元素的类型可以不相同:

          >>> a = ['him', 25, 100, 'her']>>> print(a)['him', 25, 100, 'her']

          和字符串一样,列表同样可以被索引和切片,列表被切片后返回一个包含所需元素的新列表。详细的在这里就不赘述了。

          列表还支持串联操作,使用 + 操作符:

          >>> a = [1, 2, 3, 4, 5]>>> a + [6, 7, 8][1, 2, 3, 4, 5, 6, 7, 8]

          与 Python 字符串不一样的是,列表中的元素是可以改变的:

          >>> a = [1, 2, 3, 4, 5, 6]>>> a[0] = 9>>> a[2:5] = [13, 14, 15]>>> a[9, 2, 13, 14, 15, 6]>>> a[2:5] = []   # 删除>>> a[9, 2, 6]

          List 内置了有很多方法,例如 append()、pop() 等等,这在后面会讲到。

          注意:

          • 1、List 写在方括号之间,元素用逗号隔开。
          • 2、和字符串一样,List 可以被索引和切片。
          • 3、List 可以使用 + 操作符进行拼接。
          • 4、List 中的元素是可以改变的。

          Tuple(元组)

          元组(tuple)与列表类似,不同之处在于元组的元素不能修改。元组写在小括号里,元素之间用逗号隔开。

          元组中的元素类型也可以不相同:

          >>> a = (1991, 2014, 'physics', 'math')>>> print(a, type(a), len(a))(1991, 2014, 'physics', 'math') <class 'tuple'> 4

          元组与字符串类似,可以被索引且下标索引从 0 开始,也可以进行截取/切片(看上面,这里不再赘述)。

          其实,可以把字符串看作一种特殊的元组。

          >>> tup = (1, 2, 3, 4, 5, 6)>>> print(tup[0], tup[1:5])1 (2, 3, 4, 5)>>> tup[0] = 11  # 修改元组元素的操作是非法的

          虽然 tuple 的元素不可改变,但它可以包含可变的对象,比如 list 列表。

          构造包含 0 个或 1 个元素的 tuple 是个特殊的问题,所以有一些额外的语法规则:

          tup1 = () # 空元组tup2 = (20,) # 一个元素,需要在元素后添加逗号

          另外,元组也支持用 + 操作符:

          >>> tup1, tup2 = (1, 2, 3), (4, 5, 6)>>> print(tup1+tup2)(1, 2, 3, 4, 5, 6)

          string、list 和 tuple 都属于 sequence(序列)。

          注意:

          • 1、与字符串一样,元组的元素不能修改。
          • 2、元组也可以被索引和切片,方法都是一样的。
          • 3、注意构造包含 0 或 1 个元素的元组的特殊语法规则。
          • 4、元组也可以使用 + 操作符进行拼接。

          Sets(集合)

          集合(set)是一个无序不重复元素的集。

          基本功能是进行成员关系测试和消除重复元素。

          可以使用大括号 或者 set() 函数创建 set 集合,注意:创建一个空集合必须用 set() 而不是 { },因为{ }是用来创建一个空字典。

          >>> student = {'Tom', 'Jim', 'Mary', 'Tom', 'Jack', 'Rose'}>>> print(student)   # 重复的元素被自动去掉{'Jim', 'Jack', 'Mary', 'Tom', 'Rose'}>>> 'Rose' in student  # membership testing(成员测试)True>>> # set可以进行集合运算... >>> a = set('abracadabra')>>> b = set('alacazam')>>> a{'a', 'b', 'c', 'd', 'r'}>>> a - b     # a和b的差集{'b', 'd', 'r'}>>> a | b     # a和b的并集{'l', 'm', 'a', 'b', 'c', 'd', 'z', 'r'}>>> a & b     # a和b的交集{'a', 'c'}>>> a ^ b     # a和b中不同时存在的元素{'l', 'm', 'b', 'd', 'z', 'r'}

          Dictionaries(字典)

          字典(dictionary)是 Python 中另一个非常有用的内置数据类型。

          字典是一种映射类型(mapping type),它是一个无序的键值对(key-value)集合。

          关键字(key)必须使用不可变类型,也就是说list和包含可变类型的 tuple 不能做关键字。

          在同一个字典中,关键字(key)必须互不相同。

          >>> dic = {}  # 创建空字典>>> tel = {'Jack':1557, 'Tom':1320, 'Rose':1886}>>> tel{'Tom': 1320, 'Jack': 1557, 'Rose': 1886}>>> tel['Jack']   # 主要的操作:通过key查询1557>>> del tel['Rose']  # 删除一个键值对>>> tel['Mary'] = 4127  # 添加一个键值对>>> tel{'Tom': 1320, 'Jack': 1557, 'Mary': 4127}>>> list(tel.keys())  # 返回所有key组成的list['Tom', 'Jack', 'Mary']>>> sorted(tel.keys()) # 按key排序['Jack', 'Mary', 'Tom']>>> 'Tom' in tel       # 成员测试True>>> 'Mary' not in tel  # 成员测试False

          构造函数 dict() 直接从键值对 sequence 中构建字典,当然也可以进行推导,如下:

          >>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)]){'jack': 4098, 'sape': 4139, 'guido': 4127}>>> {x: x**2 for x in (2, 4, 6)}{2: 4, 4: 16, 6: 36}>>> dict(sape=4139, guido=4127, jack=4098){'jack': 4098, 'sape': 4139, 'guido': 4127}

          另外,字典类型也有一些内置的函数,例如 clear()、keys()、values() 等。

          注意:

          • 1、字典是一种映射类型,它的元素是键值对。
          • 2、字典的关键字必须为不可变类型,且不能重复。
          • 3、创建空字典使用 { }。


          Python3注释可以确保对模块, 函数, 方法和行内注释使用正确的风格,有专门的符号和格式,有单行与多行的区别。

          Python 中的注释有单行注释和多行注释:

          Python 中单行注释以 # 开头,例如:

          #!/usr/bin/python3 #coding=utf-8# 这是一个注释print("Hello, World") 

          多行注释用三个单引号(''')或者三个双引号(""")将需要注释的内容囊括起来,例如:

          1、单引号(''')

          #!/usr/bin/python3 #coding=utf-8'''这是多行注释,用三个单引号这是多行注释,用三个单引号 这是多行注释,用三个单引号'''print("Hello, World!") 

          2、双引号(""")

          #!/usr/bin/python3 #coding=utf-8"""这是多行注释,用三个双引号这是多行注释,用三个双引号 这是多行注释,用三个双引号"""print("Hello, World!") 

           三引号实际上是多行长字符串的声明方式,也作为python代码文档使用(类似javadoc)。


          本章节主要说明 Python 的运算符。举个简单的例子 4 + 5 = 9 。例子中,45 被称为操作数,"+" 称为运算符。

          Python 语言支持以下类型的运算符:

          接下来让我们一个个来学习 Python 的运算符。


          Python 算术运算符

          以下假设变量 a 为 21,变量 b 为 10:

          运算符描述实例
          +加 - 两个对象相加a + b 输出结果 31
          -减 - 得到负数或是一个数减去另一个数a - b 输出结果 -11
          *乘 - 两个数相乘或是返回一个被重复若干次的字符串a * b 输出结果 210
          /除 - x 除以 ya / b 输出结果 2.1
          %取模 - 返回除法的余数a % b 输出结果 1
          **幂 - 返回 x 的 y 次幂a ** b 为 10 的 21 次方
          //取整除 - 返回商的整数部分9//2 输出结果 4 , 9.0//2.0 输出结果 4.0

          以下实例演示了 Python 所有算术运算符的操作:

          #!/usr/bin/python3#coding=utf-8a = 21b = 10c = 0c = a + bprint ("a+b 的值为:", c)c = a - bprint ("a-b 的值为:", c)c = a * bprint ("a*b 的值为:", c)c = a / bprint ("a/b 的值为:", c)c = a % bprint ("a%b 的值为:", c)# 修改变量 a 、b 、ca = 2b = 3c = a**b print ("a**b 的值为:", c)a = 10b = 5c = a//b print ("a//b 的值为:", c)

          以上实例输出结果:

          a+b 的值为: 31

          a-b 的值为: 11

          a*b 的值为: 210

          a/b 的值为: 2.1

          a%b 的值为: 1

          a**b 的值为: 8

          a//b 的值为: 2


          Python 比较运算符

          以下假设变量 a 为 10,变量 b 为 20:

          运算符描述实例
          ==等于 -- 比较对象是否相等(a == b) 返回 False。
          !=不等于 -- 比较两个对象是否不相等(a != b) 返回 True.
          >大于 -- 返回 x 是否大于 y(a > b) 返回 False。
          <小于 -- 返回 x 是否小于 y。(a < b) 返回 True。
          >=大于等于 -- 返回 x 是否大于等于 y。(a >= b) 返回 False。
          <=小于等于 -- 返回 x 是否小于等于 y。(a <= b) 返回 True。

          所有比较运算符返回 1 表示真,返回 0 表示假。这分别与特殊的变量 True 和 False 等价。注意:True和False的首字母为大写。

          以下实例演示了 Python 所有比较运算符的操作:

          #!/usr/bin/python3#coding=utf-8a = 21b = 10c = 0if ( a == b ):    print ("a 等于 b")else:    print ("a 不等于 b")if ( a != b ):    print ("a 不等于 b")else:    print ("a 等于 b")if ( a < b ):    print ("a 小于 b")else:    print ("a 大于等于 b")if ( a > b ):    print ("a 大于 b")else:    print ("a 小于等于 b")# 修改变量 a 和 b 的值a = 5;b = 20;if ( a <= b ):    print ("a 小于等于 b")else:    print ("a 大于  b")if ( a >= b ):    print ("a 大于等于 b")else:    print ("a 小于 b")

          以上实例输出结果:

          a 不等于 b

          a 不等于 b

          a 大于等于 b

          a 大于 b

          a 小于等于 b

          a 小于 b


          Python 赋值运算符

          以下假设变量 a 为 10,变量 b 为 20:

          运算符描述实例
          =简单的赋值运算符c = a + b 将 a + b 的运算结果赋值为 c
          +=加法赋值运算符c += a 等效于 c = c + a
          -=减法赋值运算符c -= a 等效于 c = c - a
          *=乘法赋值运算符c *= a 等效于 c = c * a
          /=除法赋值运算符c /= a 等效于 c = c / a
          %=取模赋值运算符c %= a 等效于 c = c % a
          **=幂赋值运算符c **= a 等效于 c = c ** a
          //=取整除赋值运算符c //= a 等效于 c = c // a

          以下实例演示了 Python 所有赋值运算符的操作:

          #!/usr/bin/python3#coding=utf-8a = 21b = 10c = 0c = a + bprint ("1 - c 的值为:", c)c += aprint ("2 - c 的值为:", c)c *= aprint ("3 - c 的值为:", c)c /= a print ("4 - c 的值为:", c)c = 2c %= aprint ("5 - c 的值为:", c)c **= aprint ("6 - c 的值为:", c)c //= aprint ("7 - c 的值为:", c)

          以上实例输出结果:

          1 - c 的值为: 312 - c 的值为: 523 - c 的值为: 10924 - c 的值为: 52.05 - c 的值为: 26 - c 的值为: 20971527 - c 的值为: 99864

          Python 位运算符

          按位运算符是把数字看作二进制来进行计算的。Python 中的按位运算法则如下:

          下表中变量 a 为 60,b 为 13。

            按位与运算(a&b) 按位或运算(a|b)按位异或(a^b) 
           a(60)的二进制表示0011 1100 0011 1100 0011 1100 
           b(13)的二进制表示0000 11010000 1101 0000 1101 
           运算结果0000 11000011 11010011 0001
           结果的十进制表示 12 61 49
            按位取反(~a)左移(a<<2)右移(a>>2) 
           a(60)的二进制表示0011 1100 0011 1100 0011 1100 
           运算结果1100 0011 1111 00000000 1111
           运算结果的十进制表示 -61 240 15
          注:关于原码,补码和反码:
          原码:假设机器字长为n,原码就是用一个n位的二进制数,其中最高位为符号位:正数是0,负数是1。剩下的表示概数的绝对值,位数如果不够就用0补全。
          反码:在原码的基础上,符号位不变其他位取反,也就是就是0变1,1变0。
          补码:在反码的基础上加1。  
          PS:正数的原、反、补码都一样,0的原码跟反码都有两个,因为这里0被分为+0和-0。
          按位取反和反码有一定的相似之处但又不尽相同(反码符号位不取反)。
          在计算机中,是以补码的形式存放数据的。1100 0011刚好对应-61。
          -61的原码-> 1011 1101->反码->1100 0010->补码->1100 0011
          运算符描述实例
          &按位与运算符:参与运算的两个值,如果两个相应位都为  1,则该位的结果为 1,否则为 0(a & b) 输出结果 12 ,二进制解释: 0000 1100
          |按位或运算符:只要对应的二个二进位有一个为 1 时,结果位就为 1。(a | b) 输出结果 61 ,二进制解释: 0011 1101
          ^按位异或运算符:当两对应的二进位相异(不同)时,结果为 1(a ^ b) 输出结果 49 ,二进制解释: 0011 0001
          ~按位取反运算符:对数据的每个二进制位取反,即把 1 变为 0,把 0 变为 1(~a ) 输出结果 -61 ,二进制解释: 1100 0011
          <<左移动运算符:运算数的各二进位全部左移若干位,由"<<"右边的数指定移动的位数,高位丢弃,低位补 0。a << 2 输出结果 240 ,二进制解释: 1111 0000
          >>右移动运算符:把">>"左边的运算数的各二进位全部右移若干位,">>"右边的数指定移动的位数a >> 2 输出结果 15 ,二进制解释: 0000 1111

          以下实例演示了 Python 所有位运算符的操作:

          #!/usr/bin/python3#coding=utf-8a = 60            # 60 = 0011 1100 b = 13            # 13 = 0000 1101 c = 0c = a & b;        # 12 = 0000 1100print ("1 - c 的值为:", c)c = a | b;        # 61 = 0011 1101 print ("2 - c 的值为:", c)c = a ^ b;        # 49 = 0011 0001print ("3 - c 的值为:", c)c = ~a;           # -61 = 1100 0011print ("4 - c 的值为:", c)c = a << 2;       # 240 = 1111 0000print ("5 - c 的值为:", c)c = a >> 2;       # 15 = 0000 1111print ("6 - c 的值为:", c)

          以上实例输出结果:

          1 - c 的值为: 122 - c 的值为: 613 - c 的值为: 494 - c 的值为: -615 - c 的值为: 2406 - c 的值为: 15

          Python 逻辑运算符

          Python 语言支持逻辑运算符,以下假设变量 a 为 10, b 为 20:

          运算符逻辑表达式描述实例
          andx and y布尔"与" - 如果 x 为 False,x and y 返回 False,否则它返回 y 的计算值。(a and b) 返回 20。
          orx or y布尔"或" - 如果 x 是 True,它返回 x的值,否则它返回 y 的计算值。(a or b) 返回 10。
          notnot x布尔"非" - 如果 x 为 True,返回 False 。如果 x 为 False,它返回 True。not(a and b) 返回 False

          以上实例输出结果:

          #!/usr/bin/python3#coding=utf-8a = 10b = 20if ( a and b ):    print ("1 - 变量 a 和 b 都为 true")else:    print ("1 - 变量 a 和 b 有一个不为 true")if ( a or b ):    print ("2 - 变量 a 和 b 都为 true,或其中一个变量为 true")else:    print ("2 - 变量 a 和 b 都不为 true")# 修改变量 a 的值a = 0if ( a and b ):    print ("3 - 变量 a 和 b 都为 true")else:    print ("3 - 变量 a 和 b 有一个不为 true")if ( a or b ):    print ("4 - 变量 a 和 b 都为 true,或其中一个变量为 true")else:    print ("4 - 变量 a 和 b 都不为 true")if not( a and b ):    print ("5 - 变量 a 和 b 都为 false,或其中一个变量为 false")else:    print ("5 - 变量 a 和 b 都为 true")

          以上实例输出结果:

          1 - 变量 a 和 b 都为 true2 - 变量 a 和 b 都为 true,或其中一个变量为 true3 - 变量 a 和 b 有一个不为 true4 - 变量 a 和 b 都为 true,或其中一个变量为 true5 - 变量 a 和 b 都为 false,或其中一个变量为 false

          Python 成员运算符

          除了以上的一些运算符之外,Python 还支持成员运算符,测试实例中包含了一系列的成员,包括字符串,列表或元组。

          运算符描述实例
          in如果在指定的序列中找到值返回 True,否则返回 False。x 在 y 序列中 , 如果 x 在 y 序列中返回 True。
          not in如果在指定的序列中没有找到值返回 True,否则返回 False。x 不在 y 序列中 , 如果 x 不在 y 序列中返回 True。

          以下实例演示了 Python 所有成员运算符的操作:

          #!/usr/bin/python3#coding=utf-8a = 10b = 20list = [1, 2, 3, 4, 5 ];if ( a in list ):    print ("1 - 变量 a 在给定的列表中 list 中")else:    print ("1 - 变量 a 不在给定的列表中 list 中")if ( b not in list ):    print ("2 - 变量 b 不在给定的列表中 list 中")else:    print ("2 - 变量 b 在给定的列表中 list 中")# 修改变量 a 的值a = 2if ( a in list ):    print ("3 - 变量 a 在给定的列表中 list 中")else:    print ("3 - 变量 a 不在给定的列表中 list 中")

          以上实例输出结果:

          1 - 变量 a 不在给定的列表中 list 中2 - 变量 b 不在给定的列表中 list 中3 - 变量 a 在给定的列表中 list 中

          Python 身份运算符

          身份运算符用于比较两个对象的存储单元

          运算符描述实例
          isis 是判断两个标识符是不是引用自一个对象x is y, 如果 id(x) 等于 id(y) , is 返回结果 True
          is notis not 是判断两个标识符是不是引用自不同对象x is not y, 如果 id(x) 不等于 id(y). is not 返回结果 True

          以下实例演示了 Python 所有身份运算符的操作:

          #!/usr/bin/python3#coding=utf-8a = 20b = 20if ( a is b ):    print ("1 - a 和 b 有相同的标识")else:    print ("1 - a 和 b 没有相同的标识")if ( id(a) == id(b) ):    print ("2 - a 和 b 有相同的标识")else:    print ("2 - a 和 b 没有相同的标识")# 修改变量 b 的值b = 30if ( a is b ):    print ("3 - a 和 b 有相同的标识")else:    print ("3 - a 和 b 没有相同的标识")if ( a is not b ):    print ("4 - a 和 b 没有相同的标识")else:    print ("4 - a 和 b 有相同的标识")

          以上实例输出结果:

          1 - a 和 b 有相同的标识2 - a 和 b 有相同的标识3 - a 和 b 没有相同的标识4 - a 和 b 没有相同的标识

          Python 运算符优先级

          以下表格列出了从最高到最低优先级的所有运算符:

          运算符描述
          **指数 (最高优先级)
          ~ + -按位翻转, 一元加号和减号 (最后两个的方法名为 +@ 和 -@)
          * / % //乘,除,取模和取整除
          + -加法减法
          >> <<右移,左移运算符
          &位 'AND'
          ^ |位运算符
          <= < > >=比较运算符
          <> == !=比较运算符
          = %= /= //= -= += *= **=赋值运算符
          is is not身份运算符
          in not in成员运算符
          not or and逻辑运算符

          •  括号因为不是运算符所以没有纳入本表,但算术式中一旦出现括号,就要先算括号内的内容。
          • 同一级运算符的优先级从左往右进行计算。

          以下实例演示了 Python 所有运算符优先级的操作:

          #!/usr/bin/python3#coding=utf-8a = 20b = 10c = 15d = 5e = 0e = (a + b) * c / d       #( 30 * 15 ) / 5print ("(a + b) * c / d 运算结果为:",  e)e = ((a + b) * c) / d     # (30 * 15 ) / 5print ("((a + b) * c) / d 运算结果为:",  e)e = (a + b) * (c / d);    # (30) * (15/5)print ("(a + b) * (c / d) 运算结果为:",  e)e = a + (b * c) / d;      #  20 + (150/5)print ("a + (b * c) / d 运算结果为:",  e)

          以上实例输出结果:

          (a + b) * c / d 运算结果为: 90.0((a + b) * c) / d 运算结果为: 90.0(a + b) * (c / d) 运算结果为: 90.0a + (b * c) / d 运算结果为: 50.0



          Python 数字类型用于数值的储存。数值类型是不允许改变的,如果改变数字数据类型的值,将重新分配内存空间。

          以下实例在变量赋值时 Number 对象将被创建:

          var1 = 1var2 = 10

          您也可以使用del语句删除一些数字对象的引用。

          del语句的语法是:

          del var1[,var2[,var3[....,varN]]]

          您可以通过使用del语句删除单个或多个对象的引用,例如:

          del vardel var_a, var_b

          Python 支持三种不同的数值类型:

          • 整型(Int) - 通常被称为是整型或整数,是正或负整数,不带小数点。Python3 整型是没有限制大小的,可以当作 Long 类型使用,所以 Python3 没有 Python2 的 Long 类型。
          • 浮点型(float) - 浮点型由整数部分与小数部分组成,浮点型也可以使用科学计数法表示(2.5e2 = 2.5 x 102 = 250)
          • 复数( (complex)) - 复数由实数部分和虚数部分构成,可以用a + bj,或者complex(a,b)表示, 复数的实部a和虚部b都是浮点型。

          我们可以使用十六进制和八进制来代表整数:

          >>> number = 0xA0F # 十六进制>>> number2575>>> number=0o37 # 八进制>>> number31
          intfloatcomplex
          100.03.14j
          10015.2045.j
          -786-21.99.322e-36j
          08032.3e+18.876j
          -0490-90.-.6545+0J
          -0x260-32.54e1003e+26J
          0x6970.2E-124.53e-7j
          • Python支持复数,复数由实数部分和虚数部分构成,可以用a + bj,或者complex(a,b)表示, 复数的实部a和虚部b都是浮点型。

          Python 数字类型转换

          有时候,我们需要对数据内置的类型进行转换,数据类型的转换,你只需要将数据类型作为函数名即可。

          • int(x) 将x转换为一个整数。

          • float(x) 将x转换到一个浮点数。

          • complex(x) 将x转换到一个复数,实数部分为 x,虚数部分为 0。

          • complex(x, y) 将 x 和 y 转换到一个复数,实数部分为 x,虚数部分为 y。x 和 y 是数字表达式。

          以下实例将浮点数变量 a 转换为整数:

          >>> a = 1.0>>> int(a)1

          强制数据类型转换在某些情况下会丢失精度,在一些对精度要求比较高的环境下建议不要轻易使用强制数据类型转换!!


          Python 数字运算

          Python 解释器可以作为一个简单的计算器,您可以在解释器里输入一个表达式,它将输出表达式的值。

          表达式的语法很直白: +, -, */, 和其它语言(如Pascal或C)里一样。例如:

          >>> 2 + 24>>> 50 - 5*620>>> (50 - 5*6) / 45.0>>> 8 / 5  # 总是返回一个浮点数1.6

          注意:在不同的机器上浮点运算的结果可能会不一样。

          在整数除法中,除法 / 总是返回一个浮点数,如果只想得到整数的结果,丢弃可能的分数部分,可以使用运算符 //

          >>> 17 / 3  # 整数除法返回浮点型5.666666666666667>>>>>> 17 // 3  # 整数除法返回向下取整后的结果5>>> 17 % 3  # %操作符返回除法的余数2>>> 5 * 3 + 2 17

          注意:// 得到的并不一定是整数类型的数,它与分母分子的数据类型有关系。

          >>> 7//23>>> 7.0//23.0>>> 7//2.03.0>>> 

          等号 = 用于给变量赋值。赋值之后,除了下一个提示符,解释器不会显示任何结果。

          >>> width = 20>>> height = 5*9>>> width * height900

          Python 可以使用 ** 操作来进行幂运算:

          >>> 5 ** 2  # 5 的平方25>>> 2 ** 7  # 2的7次方128

          变量在使用前必须先"定义"(即赋予变量一个值),否则会出现错误:

          >>> n   # 尝试访问一个未定义的变量Traceback (most recent call last):  File "<stdin>", line 1, in <module>NameError: name 'n' is not defined

          不同类型的数混合运算时会将整数转换为浮点数:

          >>> 3 * 3.75 / 1.57.5>>> 7.0 / 23.5

          在交互模式中,最后被输出的表达式结果被赋值给变量 _ 。例如:

          >>> tax = 12.5 / 100>>> price = 100.50>>> price * tax12.5625>>> price + _113.0625>>> round(_, 2)113.06

          此处, _ 变量应被用户视为只读变量。


          数学函数

          函数返回值 ( 描述 )
          abs(x)返回数字的绝对值,如abs(-10) 返回 10
          ceil(x)返回数字的上入整数,如math.ceil(4.1) 返回 5

          cmp(x, y)

          如果 x < y 返回 -1, 如果 x == y 返回 0, 如果 x > y 返回 1。 Python 3 已废弃,使用 (x>y)-(x<y) 替换
          exp(x)返回e的x次幂(ex),如math.exp(1) 返回2.718281828459045
          fabs(x)返回数字的绝对值,如math.fabs(-10) 返回10.0
          floor(x)返回数字的下舍整数,如math.floor(4.9)返回 4
          log(x)如math.log(math.e)返回1.0,math.log(100,10)返回2.0
          log10(x)返回以10为基数的x的对数,如math.log10(100)返回 2.0
          max(x1, x2,...)返回给定参数的最大值,参数可以为序列。
          min(x1, x2,...)返回给定参数的最小值,参数可以为序列。
          modf(x)返回x的整数部分与小数部分,两部分的数值符号与x相同,整数部分以浮点型表示。
          pow(x, y)x**y 运算后的值。
          round(x [,n])

          返回浮点数 x 的四舍五入值,如给出 n 值,则代表舍入到小数点后的位数。

          其实准确的说是保留值将保留到离上一位更近的一端。

          sqrt(x)返回数字x的平方根。


          随机数函数

          随机数可以用于数学,游戏,安全等领域中,还经常被嵌入到算法中,用以提高算法效率,并提高程序的安全性。

          Python包含以下常用随机数函数:

          函数描述
          choice(seq)从序列的元素中随机挑选一个元素,比如random.choice(range(10)),从0到9中随机挑选一个整数。
          randrange ([start,] stop [,step])从指定范围内,按指定基数递增的集合中获取一个随机数,基数默认值为 1
          random()随机生成下一个实数,它在[0,1)范围内。
          seed([x])改变随机数生成器的种子seed。如果你不了解其原理,你不必特别去设定seed,Python会帮你选择seed。
          shuffle(lst)将序列的所有元素随机排序
          uniform(x, y)随机生成下一个实数,它在[x,y]范围内。


          三角函数

          Python包括以下三角函数:

          函数描述
          acos(x)返回x的反余弦弧度值。
          asin(x)返回x的反正弦弧度值。
          atan(x)返回x的反正切弧度值。
          atan2(y, x)返回给定的 X 及 Y 坐标值的反正切值。
          cos(x)返回x的弧度的余弦值。
          hypot(x, y)返回欧几里德范数 sqrt(x*x + y*y)。
          sin(x)返回的x弧度的正弦值。
          tan(x)返回x弧度的正切值。
          degrees(x)将弧度转换为角度,如degrees(math.pi/2) , 返回90.0
          radians(x)将角度转换为弧度


          数学常量

          常量描述
          pi数学常量 pi(圆周率,一般以π来表示)
          e数学常量 e,e即自然常数(自然常数)。



          在编程语言中,将以某种方式(比如通过编号)组合起来数据元素(如数字,字符串乃至其他数据结构)集合称为数据结构。在python中,最基本的数据结构为序列(sequence,简写为seq)

          所谓序列,指的是一块可存放多个值的连续内存空间,这些值按一定顺序排列,可通过每个值所在位置的编号(称为索引)访问它们。

          为了更形象的认识序列,可以将它看做是一家旅店,那么店中的每个房间就如同序列存储数据的一个个内存空间,每个房间所特有的房间号就相当于索引值。也就是说,通过房间号(索引)我们可以找到这家旅店(序列)中的每个房间(内存空间)。

          在 Python 中,​​序列类型包括字符串、列表、元组、集合和字典​​,这些序列支持以下几种通用的操作,但比较特殊的是,集合和字典不支持索引、切片、相加和相乘操作

          字符串也是一种常见的序列(所以以下的例子以字符串作为),它也可以直接通过索引访问字符串内的字符。

          序列索引

          序列中,每个元素都有属于自己的编号(索引)。从起始元素开始,索引值从 0 开始递增,如图 1 所示。

          序列索引值示意图

          除此之外,Python 还支持索引值是负数,此类索引是从右向左计数,换句话说,从最后一个元素开始计数,从索引值 -1 开始,如图 2 所示。

           负值索引示意图

          注意,在使用负值作为列序中各元素的索引值时,是从 -1 开始,而不是从 0 开始。

          另一种理解方式是:将序列想象成如下方的一个环:
          红色值为元素,绿色值为正索引,蓝色值为负索引
          可以发现序列的最后一个元素和第一个元素刚好相邻,方向与正索引的方向刚好相反,所以其负索引值是-1,。该序列有8个元素,所以最后一个负索引(也就是第一个元素)是-8,刚好等于该序列的长度的负值。

          无论是采用正索引值,还是负索引值,都可以访问序列中的任何元素。以字符串为例,访问“W3Cschool”的首元素和尾元素,可以使用如下的代码:

          str="W3Cschool"print(str[0],"==",str[-9])print(str[8],"==",str[-1])

          输出结果为:

          W == Wl == l

          序列切片

          切片操作是访问序列中元素的另一种方法,它可以访问一定范围内的元素,通过切片操作,可以生成一个新的序列。
          序列实现切片操作的语法格式如下:

          sname[start : end : step]

          其中,各个参数的含义分别是:

          • sname:表示序列的名称;
          • start:表示切片的开始索引位置(包括该位置),此参数也可以不指定,会默认为 0,也就是从序列的开头进行切片;
          • end:表示切片的结束索引位置(不包括该位置),如果不指定,则默认为序列的长度;
          • step:表示在切片过程中,隔几个存储位置(包含当前位置)取一次元素,也就是说,如果 step 的值大于 1,则在进行切片去序列元素时,会“跳跃式”的取元素。如果省略设置 step 的值,则最后一个冒号就可以省略。

          例如,对字符串“W3Cschool”进行切片:

          str="W3Cschool"#取索引区间为[0,2]之间(不包括索引2处的字符)的字符串print(str[:2])#隔 1 个字符取一个字符,区间是整个字符串print(str[::2])#取整个字符串,此时 [] 中只需一个冒号即可print(str[:])

          运行结果为:

          W3WCcolW3Cschool

          序列相加

          Python 中,支持两种类型相同的序列使用“+”运算符做相加操作,它会将两个序列进行连接,但不会去除重复的元素。

          这里所说的“类型相同”,指的是“+”运算符的两侧序列要么都是列表类型,要么都是元组类型,要么都是字符串。

          例如,前面章节中我们已经实现用“+”运算符连接 2 个(甚至多个)字符串,如下所示:

          protocol = "https://"url = "www.51coolma.cn"print(protocol+url)

          输出结果为:

          https://www.51coolma.cn

          序列相乘

          Python 中,使用数字 n 乘以一个序列会生成新的序列,其内容为原来序列被重复 n 次的结果。例如:

          str="W3Cschool"print(str*3)

          输出结果为:

          W3CschoolW3CschoolW3Cschool

          比较特殊的是,列表类型在进行乘法运算时,还可以实现初始化指定长度列表的功能。例如如下的代码,将创建一个长度为 5 的列表,列表中的每个元素都是 None,表示什么都没有。

          #列表的创建用 [],可以指定长度list = [None]*5print(list)

          输出结果为:

          [None, None, None, None, None]

          检查元素是否包含在序列中

          Python 中,可以使用 in 关键字检查某元素是否为序列的成员,其语法格式为:

          value in sequence​

          其中,value 表示要检查的元素,sequence 表示指定的序列。
          例如,检查字符‘C’是否包含在字符串“W3Cschool”中,可以执行如下代码:

          str="W3Cschool"print('C'in str)

          运行结果为:

          True

          和 in 关键字用法相同,但功能恰好相反的,还有 not in 关键字,它用来检查某个元素是否不包含在指定的序列中,比如说:

          str="W3Cschool"print('A' not in str)

          输出结果为:

          True

          和序列相关的内置函数

          Python提供了几个内置函数(表 3 所示),可用于实现与序列相关的一些常用操作。

          表 3 序列相关的内置函数
          函数功能
          len()计算序列的长度,即返回序列中包含多少个元素。
          max()找出序列中的最大元素。注意,对序列使用 sum() 函数时,做加和操作的必须都是数字,不能是字符或字符串,否则该函数将抛出异常,因为解释器无法判定是要做连接操作(+ 运算符可以连接两个序列),还是做加和操作。
          min()找出序列中的最小元素。
          list()将序列转换为列表。
          str()将序列转换为字符串。
          sum()计算元素和。
          sorted()对元素进行排序。
          reversed()反向序列中的元素。
          enumerate()将序列组合为一个索引序列,多用在 for 循环中。

           部分序列不能应用其中的部分函数,比如字典中不能直接使用list,详细的函数介绍请参阅相应数据类型的函数介绍。

          这里给大家给几个例子:

          str="W3Cschool"#找出最大的字符print(max(str))#找出最小的字符print(min(str))#对字符串中的元素进行排序print(sorted(str))

          输出结果为:

          s3['3', 'C', 'W', 'c', 'h', 'l', 'o', 'o', 's']


          列表(list)也是最常用的 Python 数据类型之一,它以一个方括号内包含多个其他数据项(字符串,数字等甚至是另一个列表),数据项间以逗号作为分隔的数据类型。

          列表的数据项不需要具有相同的类型。(这点是与其他语言的数组的一个区别)

          创建一个列表,只要把逗号分隔的不同的数据项使用方括号括起来即可。如下所示:

          list1 = ['Google', 'W3Cschool', 1997, 2000]list2 = [1, 2, 3, 4, 5, 6, 7 ]print ("list1: ", list1)print ("list2: ", list2)

          运行结果:

          list1:  ['Google', 'W3Cschool', 1997, 2000]list2:  [1, 2, 3, 4, 5, 6, 7]

          访问列表中的值

          与字符串的索引一样,列表索引从 0 开始,第二个索引是 1,依此类推。

          通过索引列表可以进行截取、组合等操作。

           该部分内容和字符串索引和切片内容具有很高的相似性(因为这些都是序列的基本操作),本章不做过多介绍,有需求的同学可以前往字符串章节进行回顾。

           索引
           负索引-4 -3 -2 -1
           值'Google' 'W3Cschool'1997 2000 

          以下是列表索引的操作:

          list1 = ['Google', 'W3Cschool', 1997, 2000]print ("list1的第一项: ", list1[0])print ("list1的最后一项: ", list1[-1])

          运行结果:

          list1的第一项:  Googlelist1的最后一项:  2000

          以下是列表切片的操作:

          list1 = ['Google', 'W3Cschool', 1997, 2000]print ("list1的前3项: ", list1[0:3])print ("list1的2、3项: ", list1[1:3])

          运行结果:

          list1的前3项:  ['Google', 'W3Cschool', 1997]list1的2、3项:  ['W3Cschool', 1997]

          更新列表

          你可以对列表的数据项进行修改或更新,你也可以使用 append() 方法来添加列表项,如下所示:

          list1 = ['Google', 'W3Cschool', 1997, 2000]print ("list1的第三个元素为: ", list1[2])list1[2] = "1998" #直接对想要修改的数据项赋上一个新值即可修改该数据项print ("list1的第三个元素为: ", list1[2])list1.append(2021) #append()可以在列表后追加一项列表项print ("追加列表项后的list1: ", list1)

          运行结果:

          list1的第三个元素为:  1997list1的第三个元素为:  1998追加列表项后的list1:  ['Google', 'W3Cschool', '1998', 2000, 2021]

          注意:我们会在接下来的章节讨论 append() 方法的使用。

          删除列表元素

          可以使用 del 语句来删除列表的的元素,如下实例:

          list1 = ['Google', 'W3Cschool', 1997, 2000]del list1[0] #del可以删掉一个元素print ("删除列表项后的list1: ", list1)

          运行结果:

          删除列表项后的list1:  ['W3Cschool', 1997, 2000]

          注意:使用del是删除删除一个变量的方法,所以使用del的时候要作用在变量上(也就是list[1])

          另一种删除的方式是使用remove来删除列表的元素,如下实例

          #!/usr/bin/python3list1 = ['Google', 'W3CSchool', 'Taobao', 'Baidu']list1.remove('Taobao') # remove可以按值查找列表中的元素并删除print ("列表现在为 : ", list1)list1.remove('Baidu')print ("列表现在为 : ", list1)

          运行结果

          列表现在为 :  ['Google', 'W3CSchool', 'Baidu']列表现在为 :  ['Google', 'W3CSchool']

          注意:我们会在接下来的章节讨论 remove() 方法的使用

          除此之外,pop也可以删除列表的最后一项。

          Python列表脚本操作符

          列表对 + 和 * 的操作符与字符串相似。+ 号用于组合列表,* 号用于重复列表。

          如下所示:

          Python 表达式结果描述
          len([1, 2, 3])3长度
          [1, 2, 3] + [4, 5, 6][1, 2, 3, 4, 5, 6]组合
          ['Hi!'] * 4['Hi!', 'Hi!', 'Hi!', 'Hi!']重复
          3 in [1, 2, 3]True元素是否存在于列表中
          for x in [1, 2, 3]: print(x, end=" ") 1 2 3迭代

          Python列表截取与拼接

          Python的列表截取与字符串操作类似,如下所示:

          L=['Google', 'W3Cschool', 'Taobao']

          操作:

          Python 表达式结果描述
          L[2]'Taobao'读取第三个元素
          L[-2]'W3Cschool'从右侧开始读取倒数第二个元素
          L[1:]['W3Cschool', 'Taobao']输出从第二个元素开始后的所有元素
          >>>L=['Google', 'W3Cschool', 'Taobao'] >>> L[2] 'Taobao' >>> L[-2] 'W3Cschool' >>> L[1:] ['W3Cschool', 'Taobao'] >>>

          列表还支持拼接操作:

          >>>squares = [1, 4, 9, 16, 25] >>> squares += [36, 49, 64, 81, 100] >>> squares [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] >>>

          嵌套列表

          使用嵌套列表即在列表里创建其它列表,例如:

          >>>a = ['a', 'b', 'c'] >>> n = [1, 2, 3] >>> x = [a, n] >>> x [['a', 'b', 'c'], [1, 2, 3]] >>> x[0] ['a', 'b', 'c'] >>> x[0][1] 'b'

          如果有其他语言的基础,会发现嵌套列表的使用和数据结构和多维数组很像。实际上,python的列表可以当做其他语言的数组使用!

          Python列表函数&方法

          Python列表包含以下函数:

          序号函数
          1len(list)
          列表元素个数
          2max(list)
          返回列表元素最大值
          3min(list)
          返回列表元素最小值
          4list(seq)
          将序列(元组,集合等)转换为列表

          Python列表包含以下方法:

          序号方法
          1list.append(obj)
          在列表末尾添加新的对象
          2list.count(obj)
          统计某个元素在列表中出现的次数
          3list.extend(seq)
          在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
          4list.index(obj)
          从列表中找出某个值第一个匹配项的索引位置
          5list.insert(index, obj)
          在列表的index的地方插入一个对象
          6list.pop([index=-1])
          移除列表中的一个元素(默认最后一个元素),并且返回该元素的值
          7list.remove(obj)
          移除列表中某个值的第一个匹配项
          8list.reverse()
          反向排列列表中元素
          9list.sort( key=None, reverse=False)
          对原列表进行排序
          10list.clear()
          清空列表
          11list.copy()
          复制列表


          Python 的元组(tuple,简写为tup)与列表类似,不同之处在于元组的元素不能修改。

          元组使用小括号​()​,列表使用方括号​[]​。

          元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。

          如下实例:

          tup1 = ('Google', 'W3CSchool', 1997, 2020)tup2 = (1, 2, 3, 4, 5 )tup3 = "a", "b", "c", "d" # 不需括号也可以print(type(tup3))

          运行结果:

          <class 'tuple'>

          创建空元组

          tup1 = ()

          元组中只包含一个元素时,需要在元素后面添加逗号,否则括号会被当做运算符使用。

          tup1 = (50,)

          元组与字符串类似,下标索引从 0 开始,可以进行截取,组合等。

           正索引
           值 GoogleW3Cschool 1997 2020 
           负索引-4 -3 -2 -1 



          访问元组

          元组可以使用下标索引来访问元组中的值,如下实例:

          #!/usr/bin/python3tup1 = ('Google', 'W3CSchool', 1997, 2020)tup2 = (1, 2, 3, 4, 5, 6, 7 )print ("tup1[0]: ", tup1[0])print ("tup2[1:5]: ", tup2[1:5])

          以上实例输出结果:

          tup1[0]:  Googletup2[1:5]:  (2, 3, 4, 5)

          修改元组

          元组中的元素值是不允许修改的,但我们可以对元组进行连接组合,如下实例:

          #!/usr/bin/python3tup1 = (12, 34.56);tup2 = ('abc', 'xyz')# 以下修改元组元素操作是非法的。# tup1[0] = 100# 创建一个新的元组tup3 = tup1 + tup2;print (tup3)

          以上实例输出结果:

          (12, 34.56, 'abc', 'xyz')

          删除元组

          元组中的元素值是不允许删除的,但我们可以使用del语句来删除整个元组,如下实例:

          #!/usr/bin/python3tup = ('Google', 'W3CSchool', 1997, 2020)print (tup)del tup;print ("删除后的元组 tup : ")print (tup)

          以上实例元组被删除后,输出变量会有异常信息,输出如下所示:

          删除后的元组 tup : Traceback (most recent call last):  File "test.py", line 8, in <module>    print (tup)NameError: name 'tup' is not defined

          元组运算符

          与字符串一样,元组之间可以使用 + 号和 * 号进行运算。这就意味着他们可以组合和复制,运算后会生成一个新的元组。

          Python 表达式结果描述
          len((1, 2, 3))3计算元素个数
          (1, 2, 3) + (4, 5, 6)(1, 2, 3, 4, 5, 6)连接
          ('Hi!',) * 4('Hi!', 'Hi!', 'Hi!', 'Hi!')复制
          3 in (1, 2, 3)True元素是否存在
          for x in (1, 2, 3): print x,1 2 3迭代

          元组索引,截取

          因为元组也是一个序列,所以我们可以访问元组中的指定位置的元素,也可以截取索引中的一段元素,如下所示:

          元组:

          L = ('Google', 'Taobao', 'W3CSchool')
          Python 表达式结果描述
          L[2]'W3CSchool'读取第三个元素
          L[-2]'Taobao'反向读取;读取倒数第二个元素
          L[1:]('Taobao', 'W3CSchool')截取元素,从第二个开始后的所有元素。

          运行实例如下:

          >>> L = ('Google', 'Taobao', 'W3CSchool')>>> L[2]'W3CSchool'>>> L[-2]'Taobao'>>> L[1:]('Taobao', 'W3CSchool')

          元组内置函数

          Python 元组包含了以下内置函数

          序号方法及描述实例
          1len(tuple)
          计算元组元素个数。
          >>> tuple1 = ('Google', 'W3CSchool', 'Taobao')>>> len(tuple1)3>>> 
          2max(tuple)
          返回元组中元素最大值。
          >>> tuple2 = ('5', '4', '8')>>> max(tuple2)'8'>>> 
          3min(tuple)
          返回元组中元素最小值。
          >>> tuple2 = ('5', '4', '8')>>> min(tuple2)'4'>>> 
          4
          tuple(seq)
          将列表转换为元组。
          >>> list1= ['Google', 'Taobao', 'W3CSchool', 'Baidu']>>> tuple1=tuple(list1)>>> tuple1('Google', 'Taobao', 'W3CSchool', 'Baidu')
          5operator(tuple1,tuple2)
          较两个元组元素
          >>> import operator>>> dict1 = (1, 2, 3)>>> dict2 = ('a', 'b', 'c')>>> operator.eq(dict1, dict2)False

          关于元组是不可变的

          所谓元组的不可变指的是元组所指向的内存中的内容不可变。

          >>> tup = ('W', '3', 'C', 's', 'c', 'h','o','o','l')>>> tup[0] = 'w'     # 不支持修改元素Traceback (most recent call last):  File "<stdin>", line 1, in <module>TypeError: 'tuple' object does not support item assignment>>> id(tup)     # 查看内存地址4440687904>>> tup = (1,2,3)>>> id(tup)4441088800    # 内存地址不一样了

          从以上实例可以看出,重新赋值的元组 tup,绑定到新的对象了,不是修改了原来的对象。


          在Python3中字典(dictionary ,简写为dict)是另一种可变容器模型,且可存储任意类型对象。

          字典的每个键值 (​key=>value​) 对用冒号 (:) 分割,每个对之间用逗号 (,) 分割,整个字典包括在花括号 ({}​) 中 ,格式如下所示:

          d = {key1 : value1, key2 : value2 }
           key(键)value(值) 
           'Alice''2341' 
           'Beth''9102' 
           'Cecil''3258' 
           'Danna''2341' 
           'Steven''5643' 

          键必须是唯一的,但值则不必(上表中Danna和Alice的键是不同的,值却是相同的)。

          值可以取任何数据类型,但​键必须是不可变的​,如字符串,数字或元组。

          一个简单的字典实例:

          dict = {'Alice': '2341', 'Beth': '9102', 'Cecil': '3258'}

          也可如此创建字典:

          dict1 = { 'abc': 456 }dict2 = { 'abc': 123, 98.6: 37 }

          访问字典里的值

          与列表取值类似,但列表取值时使用索引,字典取值时使用key,如下实例:

          #!/usr/bin/python3dict = {'Name': 'W3CSchool', 'Age': 7, 'Class': 'First'}print ("dict['Name']: ", dict['Name'])print ("dict['Age']: ", dict['Age'])

          以上实例输出结果:

          dict['Name']:  W3CSchooldict['Age']:  7

          如果用字典里没有的键访问数据,会输出错误如下:

          #!/usr/bin/python3 dict = {'Name': 'W3CSchool', 'Age': 7, 'Class': 'First'} print ("dict['Alice']: ", dict['Alice'])

          以上实例输出结果:

          Traceback (most recent call last):  File "test.py", line 5, in <module>    print ("dict['Alice']: ", dict['Alice'])KeyError: 'Alice'

          修改字典

          向字典添加新内容的方法是增加新的键/值对,修改或删除已有键/值对如下实例:

          #!/usr/bin/python3dict = {'Name': 'W3CSchool', 'Age': 7, 'Class': 'First'}dict['Age'] = 8;               # 更新 Agedict['School'] = "W3Cschool教程"  # 添加信息print ("dict['Age']: ", dict['Age'])print ("dict['School']: ", dict['School'])
          以上实例输出结果:
          dict['Age']:  8dict['School']:  W3Cschool教程

          删除字典元素

          del ​能删单一的元素也能清空字典。我们可以用它来删除字典中的一组键值对也可以用来删除整个字典。另外使用clear()也能删除字典。如下实例:

          #!/usr/bin/python3dict = {'Name': 'W3CSchool', 'Age': 7, 'Class': 'First'}del dict['Name'] # 删除键 'Name'dict.clear()     # 删除字典del dict         # 删除字典print ("dict['Age']: ", dict['Age'])print ("dict['School']: ", dict['School'])

          但这会引发一个异常,因为用执行 del 操作后字典不再存在:

          Traceback (most recent call last):  File "test.py", line 9, in <module>    print ("dict['Age']: ", dict['Age'])TypeError: 'type' object is not subscriptable

          注:clear() 方法后面也会讨论。

          字典键的特性

          字典值可以没有限制地取任何 Python 对象,既可以是标准的对象,也可以是用户定义的,但键不行。

          两个重要的点需要记住:

          1)不允许同一个键出现两次。创建时如果同一个键被赋值两次,后一个值会被记住,如下实例:

          #!/usr/bin/python3dict = {'Name': 'W3CSchool', 'Age': 7, 'Name': '编程狮'}print ("dict['Name']: ", dict['Name'])

          以上实例输出结果:

          dict['Name']:  编程狮

          2)键必须不可变,所以可以用数字,字符串或元组充当,而用列表就不行,如下实例:

          #!/usr/bin/python3dict = {['Name']: 'W3CSchool', 'Age': 7}print ("dict['Name']: ", dict['Name'])

          以上实例输出结果:

          Traceback (most recent call last):  File "test.py", line 3, in <module>    dict = {['Name']: 'W3CSchool', 'Age': 7}TypeError: unhashable type: 'list'

          字典内置函数&方法

          Python 字典包含了以下内置函数:

          序号函数及描述实例
          1len(dict)
          计算字典元素个数,即键的总数。
          >>> dict = {'Name': 'W3CSchool', 'Age': 7, 'Class': 'First'}>>> len(dict)3
          2str(dict)
          以可打印的字符串输出字典。
          >>> dict = {'Name': 'W3CSchool', 'Age': 7, 'Class': 'First'}>>> str(dict)"{'Name': 'W3CSchool', 'Class': 'First', 'Age': 7}"
          3type(variable)
          返回输入的变量类型,如果变量是字典就返回字典类型。
          >>> dict = {'Name': 'W3CSchool', 'Age': 7, 'Class': 'First'}>>> type(dict)<class 'dict'>

          Python 字典包含了以下内置方法:

          序号函数及描述
          1radiansdict.clear()
          删除字典内所有元素
          2radiansdict.copy()
          返回一个字典的浅复制
          3radiansdict.fromkeys()
          创建一个新字典,以序列seq中元素做字典的键,val为字典所有键对应的初始值
          4radiansdict.get(key, default=None)
          返回指定键的值,如果值不在字典中返回default值
          5key in dict
          如果键在字典dict里返回true,否则返回false
          6radiansdict.items()
          以列表返回可遍历的(键, 值) 元组数组
          7radiansdict.keys()
          以列表返回一个字典所有的键
          8radiansdict.setdefault(key, default=None)
          和get()类似, 但如果键不存在于字典中,将会添加键并将值设为default
          9radiansdict.update(dict2)
          把字典dict2的键/值对更新到dict里
          10radiansdict.values()
          以列表返回字典中的所有值


          集合(set)是一个无序的不重复元素序列。因此在每次运行的时候集合的运行结果的内容都是相同的,但元素的排列顺序却不是固定的,所以本章中部分案例的运行结果会出现与给出结果不同的情况(运行结果不唯一)。

          可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。

          创建格式:

          parame = {value01,value02,...}或者set(value)

          集合实例:

          basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}print(basket)  # 这里演示的是去重功能print('orange' in basket)                 # 快速判断元素是否在集合内print('crabgrass' in basket)

          运行结果:

          {'pear', 'banana', 'orange', 'apple'}TrueFalse

          集合的运算:

          a = set('abracadabra')b = set('alacazam')print(a)print(b)print(a-b)print(a|b)print(a&b)print(a^b)

          运行结果:

          {'b', 'd', 'a', 'c', 'r'}{'l', 'z', 'm', 'a', 'c'}{'r', 'd', 'b'}{'l', 'z', 'b', 'm', 'd', 'a', 'c', 'r'}{'c', 'a'}{'l', 'z', 'b', 'm', 'r', 'd'}
           a-b(a集合中b没有的元素) b     
           集合a b a   
           a|b(并集) b a
           集合b    a l
           a&b(交集)    a   
           a^b(不同时包含于a和b的元素)  

          类似列表推导式,同样集合支持集合推导式(Set comprehension):

          >>> a = {x for x in 'abracadabra' if x not in 'abc'}>>> a{'r', 'd'}

          集合的基本操作

          1、添加元素

          语法格式如下:

          s.add( x )

          将元素 x 添加到集合 s 中,如果元素已存在,则不进行任何操作。

          thisset = set(("Google", "W3Cschool", "Taobao"))thisset.add("Baidu")print(thisset)

          运行结果:

          {'W3Cschool', 'Taobao', 'Google', 'Baidu'}

          还有一个方法,也可以添加元素,且参数可以是列表,元组,字典等,语法格式如下:

          s.update( x )

          x 可以有多个,用逗号分开。

          实例:

          thisset = set(("Google", "w3Cschool", "Taobao"))thisset.update({1,3})print(thisset)thisset.update([1,4],[5,6])  print(thisset)
          运行结果:
          {1, 3, 'w3Cschool', 'Taobao', 'Google'}{1, 3, 4, 5, 6, 'w3Cschool', 'Taobao', 'Google'}

          2、移除元素

          语法格式如下:

          s.remove( x )

          将元素 x 从集合 s 中移除,如果元素不存在,则会发生错误。

          实例:

          thisset = set(("Google", "W3Cschool", "Taobao"))thisset.remove("Taobao")print(thisset)thisset.remove("Facebook")   # 不存在会发生错误

          运行结果:

          {'W3Cschool', 'Google'}Traceback (most recent call last):  File ".code.tio", line 5, in     thisset.remove("Facebook")   # 不存在会发生错误KeyError: 'Facebook'

          此外还有一个方法也是移除集合中的元素,且如果元素不存在,不会发生错误。格式如下所示:

          s.discard( x )

          实例:

          thisset = set(("Google", "W3Cschool", "Taobao"))thisset.discard("Facebook")  # 不存在不会发生错误print(thisset)

          运行结果:

          {'Taobao', 'Google', 'W3Cschool'}

          我们也可以设置随机删除集合中的一个元素,语法格式如下:

          s.pop() 

          实例:

          thisset = set(("Google", "W3Cschool", "Taobao", "Facebook"))x = thisset.pop()print(x)print(thisset)

          输出结果:

          Google{'Facebook', 'Taobao', 'W3Cschool'}

          多次执行测试结果都不一样。

          set 集合的 pop 方法会对集合进行无序的排列,然后将这个无序排列集合的左面第一个元素进行删除。因为这个过程是不确定的,所以删除结果也是不确定的,不建议使用这种方式进行删除。

          3、计算集合元素个数

          语法格式如下:

          len(s)

          计算集合 s 的元素个数。

          实例:

          thisset = set(("Google", "W3Cschool", "Taobao"))print(len(thisset))

          运行结果:

          3

          4、清空集合

          语法格式如下:

          s.clear()

          清空集合 s。

          实例

          thisset = set(("Google", "W3cschool", "Taobao"))thisset.clear()print(thisset)

          运行结果:

          set()

          5、判断元素是否在集合中存在

          语法格式如下:

          x in s

          判断元素 x 是否在集合 s 中,存在则返回 True,不存在则返回 False。

          实例:

          thisset = set(("Google", "W3Cschool", "Taobao"))print("W3Cschool" in thisset)print("Facebook" in thisset)

          运行结果:

          TrueFalse

          集合内置方法完整列表

          方法描述
          add()为集合添加元素
          clear()移除集合中的所有元素
          copy()拷贝一个集合
          difference()返回多个集合的差集
          difference_update()移除集合中的元素,该元素在指定的集合也存在。
          discard()删除集合中指定的元素
          intersection()返回集合的交集
          intersection_update()返回集合的交集。
          isdisjoint()判断两个集合是否包含相同的元素,如果没有返回 True,否则返回 False。
          issubset()判断指定集合是否为该方法参数集合的子集。
          issuperset()判断该方法的参数集合是否为指定集合的子集
          pop()随机移除元素
          remove()移除指定元素
          symmetric_difference()返回两个集合中不重复的元素集合。
          symmetric_difference_update()移除当前集合中在另外一个指定集合相同的元素,并将另外一个指定集合中不同的元素插入到当前集合中。
          union()返回两个集合的并集
          update()给集合添加元素


          if语句

          Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块。


          Python 中 if 语句的一般形式如下所示:

          if condition_1:    statement_block_1

          流程图如下所示:


          这种if语句只有在符合条件的时候才会执行代码块内的代码,是一种比较常见的用法。

          另一种常见的用法是:

          if condition_1:    statement_block_1else:    statement_block_2

          流程图如下所示:


          这种语句是一种常用的if-else语句,通常用于二分支结构的条件语句代码。

          在一些时候,我们可能需要多分支的条件语句代码,可以在if-else语句中混合elif语句进行使用:

          Python 中用 elif 代替了else if,所以if语句的关键字为:if – elif – else。

          if condition_1:    statement_block_1elif condition_2:    statement_block_2else:    statement_block_3

          流程图如下所示:


          如果 "condition_1" 为 True 将执行 "statement_block_1" 块语句,如果 "condition_1" 为 False,将判断 "condition_2",如果"condition_2" 为 True 将执行 "statement_block_2" 块语句,如果 "condition_2" 为 False,将执行"statement_block_3"块语句。

           使用第一种常用的if语句搭配合适的条件可以实现第二种和第三种语句的全部效果,但在执行效率和代码可读性上会变得比较糟糕。

          注意:

          • 1、每个条件后面要使用冒号(:),表示接下来是满足条件后要执行的语句块。
          • 2、使用缩进来划分语句块,相同缩进数的语句在一起组成一个语句块。
          • 3、在 Python 中没有 switch – case 语句,但在python3.10中添加了用法类似的match-case语句。

          match-case语句(python3.10新特性)

          在其他语言(比如说经典的C语言)中有一种多分支条件判断语句,可以进行模式匹配(通俗的讲,就是将传入的内容跟多个已存在的样例进行比较,找到相同的案例并按照该案例的代码进行处理,如果没有相同案例就按默认案例进行处理,可以查看其他编程语言的条件语句的Switch相关部分内容进行比较参考)。在python3.10中也引入了这样的新特性。

          match-case语句的结构一般如下所示:

          match variable: #这里的variable是需要判断的内容    case ["quit"]:         statement_block_1 # 对应案例的执行代码,当variable="quit"时执行statement_block_1    case ["go", direction]:         statement_block_2    case ["drop", *objects]:         statement_block_3    ... # 其他的case语句    case _: #如果上面的case语句没有命中,则执行这个代码块,类似于Switch的default        statement_block_default

          一个match语句的使用示例:

          def http_error(status):    match status:        case 400:            return "Bad request"        case 404:            return "Not found"        case 418:            return "I'm a teapot"        case _:            return "Something's wrong with the Internet"

           上述代码等价于:

          def http_error(status):    if status == 400:        return "Bad request"    elif status == 404:        return "Not found"    elif status == 418:        return "I'm a teapot"    else:        return "Something's wrong with the Internet"

          关于模式匹配还有更多的用法,可以参考PEP636进行详细的学习。

          实例

          以下实例演示了狗的年龄计算判断:

          age = int(input("Age of the dog: "))print()if age < 0:      print("This can hardly be true!") elif age == 1:      print("about 14 human years") elif age == 2:      print("about 22 human years") elif age > 2:    human = 22 + (age -2)*5    print("Human years: ", human)### input('press Return>')

          将以上脚本保存在 dog.py 文件中,并执行该脚本:

          python dog.pyAge of the dog: 1about 14 human years

          以下为 if 中常用的操作运算符:

          操作符 描述
          < 小于
          <= 小于或等于
          > 大于
          >= 大于或等于
          == 等于,比较对象是否相等
          != 不等于

           只要返回结果为布尔型(true或者false)的,都可以作为if的条件,所以在之前的集合等内容中涉及到的判断元素是否在集合中的​in​和​not in​,都可以作为if的条件。

          实例

          # 程序演示了 == 操作符# 使用数字print(5 == 6)# 使用变量x = 5y = 8print(x == y)

          以上实例输出结果:

          FalseFalse

          使用​in​和​not in​作为判断条件:

          thisset = set(("Google", "W3Cschool", "Taobao"))if "W3Cschool" in thisset:    print("该元素在列表中")if "baidu" not in thisset:    print("该元素不在列表中")

          运行结果如下:

          该元素在列表中该元素不在列表中

          以下示例使用if语句来实现一个猜数字游戏(建议在本地环境尝试):

          #!/usr/bin/python3 # 该实例演示了数字猜谜游戏number = 7guess = -1print("猜数字!")while guess != number:    guess = int(input("请输入你要猜的数字"))    if guess == number:        print("你猜中了,真厉害!")    elif guess < number:        print("猜小了,再猜猜?")    elif guess > number:        print("猜大了,在猜猜?")


          本章节将为大家介绍 Python 循环语句的使用。

          Python 中的循环语句有 for 和 while。

          Python 循环语句的控制结构图如下所示:


          while 循环

          Python 中 while 语句的一般形式:

          while 判断条件:    statements

          同样需要注意冒号和缩进。另外,在Python中没有 do-while 循环。

          以下实例使用了 while 来计算 1 到 100 的总和:

          #!/usr/bin/env python3n = 100sum = 0counter = 1while counter <= n:    sum = sum + counter         counter += 1  print('Sum of 1 until %d: %d' % (n,sum)) 

          执行结果如下:

          Sum of 1 until 100: 5050

          for 语句

          Python for 循环可以遍历任何序列的项目,如一个列表或者一个字符串。

          for 循环的一般格式如下:

          for <variable> in <sequence>:  <statements>else: <statements>

          Python for循环实例:

          >>> languages = ["C", "C++", "Perl", "Python"] >>> for x in languages:...     print (x)... CC++PerlPython>>> 

          以下 for 实例中使用了 break 语句,break 语句用于跳出当前循环体:

          #!/usr/bin/env python3edibles = ["ham", "spam","eggs","nuts"]for food in edibles:    if food == "spam":        print("No more spam please!")        break    print("Great, delicious " + food)else:    print("I am so glad: No spam!")print("Finally, I finished stuffing myself")

          执行脚本后,在循环到 "spam"时会跳出循环体:

          Great, delicious hamNo more spam please!Finally, I finished stuffing myself

          range()函数

          如果你需要遍历数字序列,可以使用内置 range() 函数。它会生成数列,例如:

          >>> for i in range(5):...     print(i)...01234

          你也可以使用 range 指定区间的值:

          >>> for i in range(5,9) :  print(i)    5678>>>

          也可以使 range 以指定数字开始并指定不同的增量(甚至可以是负数;有时这也叫做'步长'):

          >>> for i in range(0, 10, 3) :    print(i)    0369>>> 

          负数:

          >>> for i in range(-10, -100, -30) :   print(i)    -10-40-70>>> 

          您可以结合 range() 和 len() 函数以遍历一个序列的索引,如下所示:

          >>> a = ['Mary', 'had', 'a', 'little', 'lamb']>>> for i in range(len(a)):...     print(i, a[i])...0 Mary1 had2 a3 little4 lamb

          还可以使用 range() 函数来创建一个列表:

          >>> list(range(5))[0, 1, 2, 3, 4]>>>

          break 和 continue 语句及循环中的 else 子句

          break 语句可以跳出 for 和 while 的循环体。如果你从 for 或 while 循环中终止,任何对应的循环 else 块将不执行。

          continue 语句被用来告诉 Python 跳过当前循环中的当此循环,然后继续进行下一轮循环。

          循环语句可以有 else 子句;它在穷尽列表(以 for 循环)或条件变为假(以 while 循环)循环终止时被执行,但循环被 break 终止时不执行,如下查寻质数的循环例子:

          >>> for n in range(2, 10):...     for x in range(2, n):...         if n % x == 0:...             print(n, 'equals', x, '*', n//x)...             break...     else:...         # 循环中没有找到元素...         print(n, 'is a prime number')...2 is a prime number3 is a prime number4 equals 2 * 25 is a prime number6 equals 2 * 37 is a prime number8 equals 2 * 49 equals 3 * 3

          pass 语句

          pass 语句什么都不做。它只在语法上需要一条语句但程序不需要任何操作时使用。例如:

          >>> while True:...     pass  # 等待键盘中断 (Ctrl+C)

          最小的类:

          >>> class MyEmptyClass:...     pass


          迭代器

          迭代是 Python 最强大的功能之一,是访问集合元素的一种方式。。

          迭代器是一个可以记住遍历的位置的对象。

          迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

          迭代器有两个基本的方法:iter()next()

          字符串,列表或元组对象都可用于创建迭代器:

          >>> list=[1,2,3,4]>>> it = iter(list)    # 创建迭代器对象>>> print (next(it))   # 输出迭代器的下一个元素1>>> print (next(it))2>>> 

          迭代器对象可以使用常规 for 语句进行遍历:

          #!/usr/bin/python3list=[1,2,3,4]it = iter(list)    # 创建迭代器对象for x in it:    print (x, end=" ")

          执行以上程序,输出结果如下:

          1 2 3 4

          也可以使用 next() 函数:

          #!/usr/bin/python3import sys         # 引入 sys 模块list=[1,2,3,4]it = iter(list)    # 创建迭代器对象while True:    try:        print (next(it))    except StopIteration:        sys.exit()

          执行以上程序,输出结果如下:

          1234

          生成器

          在 Python 中,使用了 yield 的函数被称为生成器(generator)。

          跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。

          在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值。并在下一次执行 next() 方法时从当前位置继续运行。

          以下实例使用 yield 实现斐波那契数列:

          #!/usr/bin/python3import sysdef fibonacci(n): # 生成器函数 - 斐波那契    a, b, counter = 0, 1, 0    while True:        if (counter > n):             return        yield a        a, b = b, a + b        counter += 1f = fibonacci(10) # f 是一个迭代器,由生成器返回生成while True:    try:        print (next(f), end=" ")    except StopIteration:        sys.exit()

          执行以上程序,输出结果如下:

          0 1 1 2 3 5 8 13 21 34 55

          Python sys 模块介绍

          在 Python 的 sys 模块提供访问解释器使用或维护的变量,和与解释器进行交互的函数。

          通俗来讲,sys 模块负责程序与 Python 解释器的交互,提供了一系列的函数和变量,用于操控 Python 运行时的环境。

          本章节我们将为大家介绍 Python 中函数的应用。

          该章节可参阅 Python 函数应用详解

          Python 定义函数使用 def 关键字,一般格式如下:

          def  函数名(参数列表):    函数体

          让我们使用函数来输出"Hello World!":

          >>> def hello() :  print("Hello World!") >>> hello()Hello World!>>> 

          更复杂点的应用,函数中带上参数变量:

          def area(width, height):    return width * height def print_welcome(name):    print("Welcome", name)print_welcome("Fred")w = 4h = 5print("width =", w, " height =", h, " area =", area(w, h))

          以上实例输出结果:

          Welcome Fredwidth = 4  height = 5  area = 20

          函数变量作用域

          定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。

          通过以下实例,你可以清楚了解 Python 函数变量的作用域:

          #!/usr/bin/env python3a = 4  # 全局变量 def print_func1():    a = 17 # 局部变量    print("in print_func a = ", a)def print_func2():       print("in print_func a = ", a)print_func1()print_func2()print("a = ", a) 

          以上实例运行结果如下:

          in print_func a =  17in print_func a =  4a =  4

          关键字参数

          函数也可以使用 kwarg = value 的关键字参数形式被调用。例如,以下函数:

          def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):    print("-- This parrot wouldn't", action, end=' ')    print("if you put", voltage, "volts through it.")    print("-- Lovely plumage, the", type)    print("-- It's", state, "!")

          可以以下几种方式被调用:

          parrot(1000)                                          # 1 positional argumentparrot(voltage=1000)                                  # 1 keyword argumentparrot(voltage=1000000, action='VOOOOOM')             # 2 keyword argumentsparrot(action='VOOOOOM', voltage=1000000)             # 2 keyword argumentsparrot('a million', 'bereft of life', 'jump')         # 3 positional argumentsparrot('a thousand', state='pushing up the daisies')  # 1 positional, 1 keyword

          以下为错误调用方法:

          parrot()                     # required argument missingparrot(voltage=5.0, 'dead')  # non-keyword argument after a keyword argumentparrot(110, voltage=220)     # duplicate value for the same argumentparrot(actor='John Cleese')  # unknown keyword argument

          返回值

          Python 函数使用 return 语句返回函数值,可以将函数作为一个值赋值给指定变量:

          def return_sum(x,y):    c = x + y    return cres = return_sum(4,5)print(res)

          你也可以让函数返回空值:

          def empty_return(x,y):    c = x + y    returnres = empty_return(4,5)print(res)

          可变参数列表

          最后,一个较不常用的功能是可以让函数调用可变个数的参数。

          这些参数被包装进一个元组(查看元组和序列)。

          在这些可变个数的参数之前,可以有零到多个普通的参数:

          def arithmetic_mean(*args):    if len(args) == 0:        return 0    else:        sum = 0        for x in args:            sum += x        return sum/len(args)print(arithmetic_mean(45,32,89,78))print(arithmetic_mean(8989.8,78787.78,3453,78778.73))print(arithmetic_mean(45,32))print(arithmetic_mean(45))print(arithmetic_mean())

          以上实例输出结果为:

          61.042502.327538.545.00

          更详细教程请参阅参阅Python 函数应用详解


          本章节我们主要结合前面所学的知识点来介绍 Python 数据结构。


          列表

          Python 中列表是可变的,这是它区别于字符串和元组的最重要的特点,一句话概括即:列表可以修改,而字符串和元组不能修改。

          以下是 Python 中列表的方法:

          方法描述
          list.append(x)把一个元素添加到列表的结尾,相当于 a[len(a):] = [x]。
          list.extend(L)通过添加指定列表的所有元素来扩充列表,相当于 a[len(a):] = L。
          list.insert(i, x)在指定位置插入一个元素。第一个参数是准备插入到其前面的那个元素的索引,例如 a.insert(0, x) 会插入到整个列表之前,而 a.insert(len(a), x) 相当于 a.append(x) 。
          list.remove(x)删除列表中值为 x 的第一个元素。如果没有这样的元素,就会返回一个错误。
          list.pop([i])从列表的指定位置删除元素,并将其返回。如果没有指定索引,a.pop()返回最后一个元素。元素随即从列表中被删除。(方法中 i 两边的方括号表示这个参数是可选的,而不是要求你输入一对方括号,你会经常在 Python 库参考手册中遇到这样的标记。)
          list.clear()移除列表中的所有项,等于del a[:]。
          list.index(x)返回列表中第一个值为 x 的元素的索引。如果没有匹配的元素就会返回一个错误。
          list.count(x)返回 x 在列表中出现的次数。
          list.sort()对列表中的元素进行排序。
          list.reverse()倒排列表中的元素。
          list.copy()返回列表的浅复制,等于a[:]。

          下面示例演示了列表的大部分方法:

          >>> a = [66.25, 333, 333, 1, 1234.5]>>> print(a.count(333), a.count(66.25), a.count('x'))2 1 0>>> a.insert(2, -1)>>> a.append(333)>>> a[66.25, 333, -1, 333, 1, 1234.5, 333]>>> a.index(333)1>>> a.remove(333)>>> a[66.25, -1, 333, 1, 1234.5, 333]>>> a.reverse()>>> a[333, 1234.5, 1, 333, -1, 66.25]>>> a.sort()>>> a[-1, 1, 66.25, 333, 333, 1234.5]

          注意:类似 insert, remove 或 sort 等修改列表的方法没有返回值。


          将列表当做堆栈使用

          列表的方法使得列表可以很方便的作为一个堆栈来使用,堆栈作为特定的数据结构,最先进入的元素会最后一个被释放(后进先出)。用 append() 方法可以把一个元素添加到堆栈顶。用不指定索引的 pop() 方法可以把一个元素从堆栈顶释放出来。例如:

          >>> stack = [3, 4, 5]>>> stack.append(6)>>> stack.append(7)>>> stack[3, 4, 5, 6, 7]>>> stack.pop()7>>> stack[3, 4, 5, 6]>>> stack.pop()6>>> stack.pop()5>>> stack[3, 4]

          将列表当作队列使用

          也可以把列表当做队列用,在队列里第一个位置加入的元素,第一个取出来;但是拿列表用作队列效率不高。在列表的最后添加或者弹出元素速度快,然而在列表里插入或者从头部弹出速度却不快(因为所有其他的元素都得一个一个地移动)。

          >>> from collections import deque>>> queue = deque(["Eric", "John", "Michael"])>>> queue.append("Terry")           # Terry arrives>>> queue.append("Graham")          # Graham arrives>>> queue.popleft()                 # The first to arrive now leaves'Eric'>>> queue.popleft()                 # The second to arrive now leaves'John'>>> queue                           # Remaining queue in order of arrivaldeque(['Michael', 'Terry', 'Graham'])

          列表推导式

          列表推导式提供了从序列创建列表的简单途径。通常应用程序将一些操作应用于某个序列的每个元素,用其获得的结果作为生成新列表的元素,或者根据确定的判定条件创建子序列。

          每个列表推导式都在 for 之后跟一个表达式,然后有零到多个 for 或 if 子句。返回结果是一个根据表达从其后的 for 和 if 上下文环境中生成出来的列表。如果希望表达式推导出一个元组,就必须使用括号。

          这里我们将列表中每个数值乘三,获得一个新的列表:

          >>> vec = [2, 4, 6]>>> [3*x for x in vec][6, 12, 18]

          现在我们玩一点小花样:

          >>> [[x, x**2] for x in vec][[2, 4], [4, 16], [6, 36]]

          这里我们对序列里每一个元素逐个调用某方法:

          >>> freshfruit = ['  banana', '  loganberry ', 'passion fruit  ']>>> [weapon.strip() for weapon in freshfruit]['banana', 'loganberry', 'passion fruit']

          我们可以用 if 子句作为过滤器:

          >>> [3*x for x in vec if x > 3][12, 18]>>> [3*x for x in vec if x < 2] [] 

          以下是一些关于循环和其它技巧的演示:

          >>> vec1 = [2, 4, 6]>>> vec2 = [4, 3, -9]>>> [x*y for x in vec1 for y in vec2][8, 6, -18, 16, 12, -36, 24, 18, -54]>>> [x+y for x in vec1 for y in vec2][6, 5, -7, 8, 7, -5, 10, 9, -3]>>> [vec1[i]*vec2[i] for i in range(len(vec1))][8, 12, -54]

          列表推导式可以使用复杂表达式或嵌套函数:

          >>> [str(round(355/113, i)) for i in range(1, 6)]['3.1', '3.14', '3.142', '3.1416', '3.14159']

          嵌套列表解析

          Python 的列表还可以嵌套。

          以下实例展示了 3 * 4 的矩阵列表:

          >>> matrix = [...     [1, 2, 3, 4],...     [5, 6, 7, 8],...     [9, 10, 11, 12],... ]

          以下实例将 3 * 4 的矩阵列表转换为 4 * 3 列表:

          >>> [[row[i] for row in matrix] for i in range(4)][[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

          以下实例也可以使用以下方法来实现:

          >>> transposed = []>>> for i in range(4):...     transposed.append([row[i] for row in matrix])...>>> transposed[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

          另外一种实现方法:

          >>> transposed = []>>> for i in range(4):...     # the following 3 lines implement the nested listcomp...     transposed_row = []...     for row in matrix:...         transposed_row.append(row[i])...     transposed.append(transposed_row)...>>> transposed[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

          del 语句

          使用 del 语句可以从一个列表中依照索引(而不是值)来删除一个元素。这与使用 pop() 返回一个值不同。

          可以用 del 语句从列表中删除一个切片,或清空整个列表(我们以前介绍的方法是给该切片赋一个空列表)。例如:

          >>> a = [-1, 1, 66.25, 333, 333, 1234.5]>>> del a[0]>>> a[1, 66.25, 333, 333, 1234.5]>>> del a[2:4]>>> a[1, 66.25, 1234.5]>>> del a[:]>>> a[]

          也可以用 del 删除实体变量:

          >>> del a

          元组和序列

          元组由若干逗号分隔的值组成,例如:

          >>> t = 12345, 54321, 'hello!'>>> t[0]12345>>> t(12345, 54321, 'hello!')>>> # Tuples may be nested:... u = t, (1, 2, 3, 4, 5)>>> u((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))

          如你所见,元组在输出时总是有括号的,以便于正确表达嵌套结构。在输入时可能有或没有括号, 不过括号通常是必须的(如果元组是更大的表达式的一部分)。


          集合

          集合是一个无序不重复元素的集。基本功能包括关系测试和消除重复元素。

          可以用大括号 ({}) 创建集合。注意:如果要创建一个空集合,你必须用 set() 而不是 {} ;后者创建一个空的字典,下一节我们会介绍这个数据结构。

          以下是一个简单的演示:

          >>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}>>> print(basket)                      # show that duplicates have been removed{'orange', 'banana', 'pear', 'apple'}>>> 'orange' in basket                 # fast membership testingTrue>>> 'crabgrass' in basketFalse>>> # Demonstrate set operations on unique letters from two words...>>> a = set('abracadabra')>>> b = set('alacazam')>>> a                                  # unique letters in a{'a', 'r', 'b', 'c', 'd'}>>> a - b                              # letters in a but not in b{'r', 'd', 'b'}>>> a | b                              # letters in either a or b{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}>>> a & b                              # letters in both a and b{'a', 'c'}>>> a ^ b                              # letters in a or b but not both{'r', 'd', 'b', 'm', 'z', 'l'}

          集合也支持推导式:

          >>> a = {x for x in 'abracadabra' if x not in 'abc'}>>> a{'r', 'd'}

          字典

          另一个非常有用的 Python 内建数据类型是字典。

          序列是以连续的整数为索引,与此不同的是,字典以关键字为索引,关键字可以是任意不可变类型,通常用字符串或数值。

          理解字典的最佳方式是把它看做无序的键 => 值对集合。在同一个字典之内,关键字必须是互不相同。

          一对大括号创建一个空的字典:{}。

          这是一个字典运用的简单例子:

          >>> tel = {'jack': 4098, 'sape': 4139}>>> tel['guido'] = 4127>>> tel{'sape': 4139, 'guido': 4127, 'jack': 4098}>>> tel['jack']4098>>> del tel['sape']>>> tel['irv'] = 4127>>> tel{'guido': 4127, 'irv': 4127, 'jack': 4098}>>> list(tel.keys())['irv', 'guido', 'jack']>>> sorted(tel.keys())['guido', 'irv', 'jack']>>> 'guido' in telTrue>>> 'jack' not in telFalse

          构造函数 dict() 直接从键值对元组列表中构建字典。如果有固定的模式,列表推导式指定特定的键值对:

          >>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)]){'sape': 4139, 'jack': 4098, 'guido': 4127}

          此外,字典推导可以用来创建任意键和值的表达式词典:

          >>> {x: x**2 for x in (2, 4, 6)}{2: 4, 4: 16, 6: 36}

          如果关键字只是简单的字符串,使用关键字参数指定键值对有时候更方便:

          >>> dict(sape=4139, guido=4127, jack=4098){'sape': 4139, 'jack': 4098, 'guido': 4127}

          遍历技巧

          在字典中遍历时,关键字和对应的值可以使用 items() 方法同时解读出来:

          >>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}>>> for k, v in knights.items():...     print(k, v)...gallahad the purerobin the brave

          在序列中遍历时,索引位置和对应值可以使用 enumerate() 函数同时得到:

          >>> for i, v in enumerate(['tic', 'tac', 'toe']):...     print(i, v)...0 tic1 tac2 toe

          同时遍历两个或更多的序列,可以使用 zip() 组合:

          >>> questions = ['name', 'quest', 'favorite color']>>> answers = ['lancelot', 'the holy grail', 'blue']>>> for q, a in zip(questions, answers):...     print('What is your {0}?  It is {1}.'.format(q, a))...What is your name?  It is lancelot.What is your quest?  It is the holy grail.What is your favorite color?  It is blue.

          要反向遍历一个序列,首先指定这个序列,然后调用 reversed() 函数:

          >>> for i in reversed(range(1, 10, 2)):...     print(i)...97531

          要按顺序遍历一个序列,使用 sorted() 函数返回一个已排序的序列,并不修改原值:

          >>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']>>> for f in sorted(set(basket)):...     print(f)...applebananaorangepear

          其他参阅文档(Python2.x)


          在前面的几个章节中我们脚本上是用 Python 解释器来编程,如果你从 Python 解释器退出再进入,那么你定义的所有的方法和变量就都消失了。

          为此 Python 提供了一个办法,把这些定义存放在文件中,为一些脚本或者交互式的解释器实例使用,这个文件被称为模块。

          模块是一个包含所有你定义的函数和变量的文件,其后缀名是 .py。模块可以被别的程序引入,以使用该模块中的函数等功能。这也是使用 Python 标准库的方法。下面是一个使用 Python 标准库中模块的例子。 

          #!/usr/bin/python3# Filename: using_sys.pyimport sysprint('命令行参数如下:')for i in sys.argv:    print(i)print('
          
          Python 路径为:', sys.path, '
          ')

          执行结果如下所示:

          $ python using_sys.py 参数1 参数2命令行参数如下:using_sys.py参数1参数2Python 路径为: ['/root', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages']
          • 1、import sys 引入 Python 标准库中的 sys.py 模块;这是引入某一模块的方法。
          • 2、sys.argv 是一个包含命令行参数的列表。
          • 3、sys.path 包含了一个 Python 解释器自动查找所需模块的路径的列表。

          import 语句

          如果要使用 Python 源文件,只需在另一个源文件里执行 import 语句,import 语句语法如下:

          import module1[,module2[, ... moduleN]

          当解释器遇到 import 语句,如果模块在当前的搜索路径就会被导入。

          搜索路径是一个解释器会先进行搜索的所有目录的列表。如果想要导入模块 support,需要把命令放在脚本的顶端:

          #!/usr/bin/python3# Filename: support.pydef print_func( par ):    print ("Hello : ", par)    return

          test.py 引入 support 模块:

          #!/usr/bin/python3# Filename: test.py# 导入模块import support# 现在可以调用模块里包含的函数了support.print_func("51coolma")

          以上实例输出结果:

          $ python3 test.pyHello :  51coolma

          一个模块只会被导入一次,不管你执行了多少次 import。这样可以防止导入模块被一遍又一遍地执行。

          当我们使用 import 语句的时候,Python 解释器是怎样找到对应的文件的呢?

          这就涉及到 Python 的搜索路径,搜索路径是由一系列目录名组成的,Python 解释器就依次从这些目录中去寻找所引入的模块。

          这看起来很像环境变量,事实上,也可以通过定义环境变量的方式来确定搜索路径。

          搜索路径是在 Python 编译或安装的时候确定的,安装新的库应该也会修改。搜索路径被存储在 sys 模块中的 path 变量,做一个简单的实验,在交互式解释器中,输入以下代码:

          >>> import sys>>> sys.path['', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages']>>> 

          sys.path 输出是一个列表,其中第一项是空串'',代表当前目录(若是从一个脚本中打印出来的话,可以更清楚地看出是哪个目录),亦即我们执行 Python 解释器的目录(对于脚本的话就是运行的脚本所在的目录)。

          因此若像我一样在当前目录下存在与要引入模块同名的文件,就会把要引入的模块屏蔽掉。

          了解了搜索路径的概念,就可以在脚本中修改 sys.path 来引入一些不在搜索路径中的模块。

          现在,在解释器的当前目录或者 sys.path 中的一个目录里面来创建一个 fibo.py 的文件,代码如下:

          # 斐波那契数列模块(Fibonacci numbers module)def fib(n):    # 定义到 n 的斐波那契数列    a, b = 0, 1    while b < n:        print(b, end=' ')        a, b = b, a+b    print()def fib2(n): # 返回到 n 的斐波那契数列    result = []    a, b = 0, 1    while b < n:        result.append(b)        a, b = b, a+b    return result 

          然后进入 Python 解释器,使用下面的命令导入这个模块:

          >>> import fibo

          这样做并没有把直接定义在 fibo 中的函数名称写入到当前符号表里,只是把模块 fibo 的名字写到了那里。

          可以使用模块名称来访问函数:

          >>> fibo.fib(1000)1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987>>> fibo.fib2(100)[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]>>> fibo.__name__'fibo'

          如果你打算经常使用一个函数,你可以把它赋给一个本地的名称:

          >>> fib = fibo.fib>>> fib(500)1 1 2 3 5 8 13 21 34 55 89 144 233 377

          from ... import 语句

          Python 的 from 语句让你从模块中导入一个指定的部分到当前命名空间中,语法如下:

          from modname import name1[, name2[, ... nameN]

          例如,要导入模块 fibo 的 fib 函数,使用如下语句:

          >>> from fibo import fib, fib2>>> fib(500)1 1 2 3 5 8 13 21 34 55 89 144 233 377

          这个声明不会把整个 fibo 模块导入到当前的命名空间中,它只会将 fibo 里的 fib 函数引入进来。


          from ... import * 语句

          把一个模块的所有内容全都导入到当前的命名空间也是可行的,只需使用如下声明:

          from modname import *

          这提供了一个简单的方法来导入一个模块中的所有项目。然而这种声明不该被过多的使用。


          进一步了解模块

          模块除了方法定义,还可以包括可执行的代码。这些代码一般用来初始化这个模块。这些代码只有在第一次被导入时才会被执行。

          每个模块有各自独立的符号表,在模块内部为所有的函数当作全局符号表来使用。

          所以,模块的作者可以放心大胆的在模块内部使用这些全局变量,而不用担心把其他用户的全局变量搞花。

          从另一个方面,当你确实知道你在做什么的话,你也可以通过 modname.itemname 这样的表示法来访问模块内的函数。

          模块是可以导入其他模块的。在一个模块(或者脚本,或者其他地方)的最前面使用 import 来导入一个模块,当然这只是一个惯例,而不是强制的。被导入的模块的名称将被放入当前操作的模块的符号表中。

          还有一种导入的方法,可以使用 import 直接把模块内(函数,变量的)名称导入到当前操作模块。比如:

          >>> from fibo import fib, fib2>>> fib(500)1 1 2 3 5 8 13 21 34 55 89 144 233 377

          这种导入的方法不会把被导入的模块的名称放在当前的字符表中(所以在这个例子里面,fibo 这个名称是没有定义的)。

          这还有一种方法,可以一次性的把模块中的所有(函数,变量)名称都导入到当前模块的字符表:

          >>> from fibo import *>>> fib(500)1 1 2 3 5 8 13 21 34 55 89 144 233 377

          这将把所有的名字都导入进来,但是那些由单一下划线(_)开头的名字不在此例。大多数情况, Python程序员不使用这种方法,因为引入的其它来源的命名,很可能覆盖了已有的定义。


          __name__属性

          一个模块被另一个程序第一次引入时,其主程序将运行。如果我们想在模块被引入时,模块中的某一程序块不执行,我们可以用 __name__ 属性来使该程序块仅在该模块自身运行时执行。

          #!/usr/bin/python3# Filename: using_name.pyif __name__ == '__main__':    print('程序自身在运行')else:    print('我来自另一模块')

          运行输出如下:

          $ python using_name.py程序自身在运行
          $ python>>> import using_name我来自另一模块>>>

          说明:

          1. 每个模块都有一个 __name__ 属性,当其值是 '__main__' 时,表明该模块自身在运行,否则是被引入。
          2. __name__ 与 __main__ 底下是双下划线,是“_ _”去掉中间的空格。


          dir() 函数

          内置的函数 dir() 可以找到模块内定义的所有名称。以一个字符串列表的形式返回:</p><pre>>>> import fibo, sys>>> dir(fibo)['__name__', 'fib', 'fib2']>>> dir(sys)  ['__displayhook__', '__doc__', '__excepthook__', '__loader__', '__name__', '__package__', '__stderr__', '__stdin__', '__stdout__', '_clear_type_cache', '_current_frames', '_debugmallocstats', '_getframe', '_home', '_mercurial', '_xoptions', 'abiflags', 'api_version', 'argv', 'base_exec_prefix', 'base_prefix', 'builtin_module_names', 'byteorder', 'call_tracing', 'callstats', 'copyright', 'displayhook', 'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info', 'float_repr_style', 'getcheckinterval', 'getdefaultencoding', 'getdlopenflags', 'getfilesystemencoding', 'getobjects', 'getprofile', 'getrecursionlimit', 'getrefcount', 'getsizeof', 'getswitchinterval', 'gettotalrefcount', 'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info', 'intern', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1', 'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit', 'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout', 'thread_info', 'version', 'version_info', 'warnoptions']

          如果没有给定参数,那么 dir() 函数会罗列出当前定义的所有名称:

          >>> a = [1, 2, 3, 4, 5]>>> import fibo>>> fib = fibo.fib>>> dir() # 得到一个当前模块中定义的属性列表['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']>>> a = 5 # 建立一个新的变量 'a'>>> dir()['__builtins__', '__doc__', '__name__', 'a', 'sys']>>>>>> del a # 删除变量名a>>>>>> dir()['__builtins__', '__doc__', '__name__', 'sys']>>>

          标准模块

          Python 本身带着一些标准的模块库,在 Python 库参考文档中将会介绍到(就是后面的"库参考文档")。

          有些模块直接被构建在解析器里,这些虽然不是一些语言内置的功能,但是他却能很高效的使用,甚至是系统级调用也没问题。

          这些组件会根据不同的操作系统进行不同形式的配置,比如 winreg 这个模块就只会提供给 Windows 系统。

          应该注意到这有一个特别的模块 sys ,它内置在每一个 Python 解析器中。变量 sys.ps1 和 sys.ps2 定义了主提示符和副提示符所对应的字符串:

          >>> import sys>>> sys.ps1'>>> '>>> sys.ps2'... '>>> sys.ps1 = 'C> 'C> print('Yuck!')Yuck!C>

          包是一种管理 Python 模块命名空间的形式,采用"点模块名称"。

          比如一个模块的名称是 A.B, 那么他表示一个包 A 中的子模块 B 。

          就好像使用模块的时候,你不用担心不同模块之间的全局变量相互影响一样,采用点模块名称这种形式也不用担心不同库之间的模块重名的情况。

          这样不同的作者都可以提供 NumPy 模块,或者是 Python 图形库。

          不妨假设你想设计一套统一处理声音文件和数据的模块(或者称之为一个"包")。

          现存很多种不同的音频文件格式(基本上都是通过后缀名区分的,例如: .wav,:file:.aiff,:file:.au,),所以你需要有一组不断增加的模块,用来在不同的格式之间转换。

          并且针对这些音频数据,还有很多不同的操作(比如混音,添加回声,增加均衡器功能,创建人造立体声效果),所以你还需要一组怎么也写不完的模块来处理这些操作。

          这里给出了一种可能的包结构(在分层的文件系统中):

          sound/                          顶层包      __init__.py               初始化 sound 包      formats/                  文件格式转换子包              __init__.py              wavread.py              wavwrite.py              aiffread.py              aiffwrite.py              auread.py              auwrite.py              ...      effects/                  声音效果子包              __init__.py              echo.py              surround.py              reverse.py              ...      filters/                  filters 子包              __init__.py              equalizer.py              vocoder.py              karaoke.py              ...

          在导入一个包的时候,Python 会根据 sys.path 中的目录来寻找这个包中包含的子目录。

          目录只有包含一个叫做 __init__.py 的文件才会被认作是一个包,主要是为了避免一些滥俗的名字(比如叫做 string)不小心的影响搜索路径中的有效模块。

          最简单的情况,放一个空的 :file:__init__.py 就可以了。当然这个文件中也可以包含一些初始化代码或者为(将在后面介绍的) __all__变量赋值。

          用户可以每次只导入一个包里面的特定模块,比如:

          import sound.effects.echo

          这将会导入子模块: mod:song.effects.echo。 他必须使用全名去访问:

          sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

          还有一种导入子模块的方法是:

          from sound.effects import echo

          这同样会导入子模块 echo ,并且他不需要那些冗长的前缀,所以他可以这样使用:

          echo.echofilter(input, output, delay=0.7, atten=4)

          还有一种变化就是直接导入一个函数或者变量:

          from sound.effects.echo import echofilter

          同样的,这种方法会导入子模块 echo ,并且可以直接使用他的 echofilter() 函数:

          echofilter(input, output, delay=0.7, atten=4)

          注意当使用 from package import item 这种形式的时候,对应的 item 既可以是包里面的子模块(子包),或者包里面定义的其他名称,比如函数,类或者变量。

          import语法会首先把item当作一个包定义的名称,如果没找到,再试图按照一个模块去导入。如果还没找到,恭喜,一个 : exc:ImportError 异常被抛出了。

          反之,如果使用形如 import item.subitem.subsubitem 这种导入形式,除了最后一项,都必须是包,而最后一项则可以是模块或者是包,但是不可以是类,函数或者变量的名字。


          从一个包中导入*

          设想一下,如果我们使用 from sound.effects import *会发生什么?

          Python 会进入文件系统,找到这个包里面所有的子模块,一个一个的把它们都导入进来。

          但是很不幸,这个方法在 Windows平台上工作的就不是非常好,因为 Windows 是一个大小写不区分的系统。

          在这类平台上,没有人敢担保一个叫做 ECHO.py 的文件导入为模块 echo 还是 Echo 甚至 ECHO 。

          (例如,Windows 95就很讨厌的把每一个文件的首字母大写显示)而且 DOS 的 8+3 命名规则对长模块名称的处理会把问题搞得更纠结。

          为了解决这个问题,只能烦劳包作者提供一个精确的包的索引了。

          导入语句遵循如下规则:如果包定义文件 __init__.py 存在一个叫做 __all__ 的列表变量,那么在使用 from package import * 的时候就把这个列表中的所有名字作为包内容导入。

          作为包的作者,可别忘了在更新包之后保证 __all__ 也更新了啊。你说我就不这么做,我就不使用导入*这种用法,好吧,没问题,谁让你是老板呢。这里有一个例子,在 ​:file:sounds/effects/__init__.py​ 中包含如下代码:

          __all__ = ["echo", "surround", "reverse"]

          这表示当你使用 from sound.effects import * 这种用法时,你只会导入包里面这三个子模块。

          如果 __all__ 没有定义,那么使用 from sound.effects import * 这种语法的时候,就不会导入包 sound.effects 里的任何子模块。他只是把包 sound.effects 和它里面定义的所有内容导入进来(可能运行 __init__.py 里定义的初始化代码)。

          这会把 __init__.py 里面定义的所有名字导入进来。并且他不会破坏掉我们在这句话之前导入的所有明确指定的模块。看下这部分代码:

          import sound.effects.echoimport sound.effects.surroundfrom sound.effects import *

          这个例子中,在执行 from...import 前,包 sound.effects 中的 echo 和 surround 模块都被导入到当前的命名空间中了。(当然如果定义了__all__ 就更没问题了)

          通常我们并不主张使用*这种方法来导入模块,因为这种方法经常会导致代码的可读性降低。不过这样倒的确是可以省去不少敲键的功夫,而且一些模块都设计成了只能通过特定的方法导入。

          记住,使用 from Package import specific_submodule 这种方法永远不会有错。事实上,这也是推荐的方法。除非是你要导入的子模块有可能和其他包的子模块重名。

          如果在结构中包是一个子包(比如这个例子中对于包 sound 来说),而你又想导入兄弟包(同级别的包)你就得使用导入绝对的路径来导入。比如,如果模块  sound.filters.vocoder 要使用包 sound.effects 中的模块 echo ,你就要写成 from sound.effects import echo。

          from . import echofrom .. import formatsfrom ..filters import equalizer

          无论是隐式的还是显式的相对导入都是从当前模块开始的。主模块的名字永远是 "__main__",一个Python应用程序的主模块,应当总是使用绝对路径引用。

          包还提供一个额外的属性 __path__ 。这是一个目录列表,里面每一个包含的目录都有为这个包服务的 __init__.py ,你得在其他 __init__.py 被执行前定义哦。可以修改这个变量,用来影响包含在包里面的模块和子包。

          这个功能并不常用,一般用来扩展包里面的模块。


          在前面几个章节中,我们其实已经接触了 Python 的输入输出的功能。本章节我们将具体介绍 Python 的输入输出。


          输出格式美化

          Python 两种输出值的方式: 表达式语句和 print() 函数。(第三种方式是使用文件对象的 write() 方法; 标准输出文件可以用 sys.stdout 引用。)

          如果你希望输出的形式更加多样,可以使用 str.format() 函数来格式化输出值。

          如果你希望将输出的值转成字符串,可以使用 repr() 或 str() 函数来实现。

          str() 函数返回一个用户易读的表达形式。

          repr() 产生一个解释器易读的表达形式。

          例如

          >>> s = 'Hello, world.'>>> str(s)'Hello, world.'>>> repr(s)"'Hello, world.'">>> str(1/7)'0.14285714285714285'>>> x = 10 * 3.25>>> y = 200 * 200>>> s = 'The value of x is ' + repr(x) + ', and y is ' + repr(y) + '...'>>> print(s)The value of x is 32.5, and y is 40000...>>> #  repr() 函数可以转义字符串中的特殊字符... hello = 'hello, world
          '>>> hellos = repr(hello)>>> print(hellos)'hello, world
          '>>> # repr() 的参数可以是 Python 的任何对象... repr((x, y, ('spam', 'eggs')))"(32.5, 40000, ('spam', 'eggs'))"

          这里有两种方式输出一个平方与立方的表:

          >>> for x in range(1, 11):...     print(repr(x).rjust(2), repr(x*x).rjust(3), end=' ')...     # 注意前一行 'end' 的使用...     print(repr(x*x*x).rjust(4))... 1   1    1 2   4    8 3   9   27 4  16   64 5  25  125 6  36  216 7  49  343 8  64  512 9  81  72910 100 1000>>> for x in range(1, 11):...     print('{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x))... 1   1    1 2   4    8 3   9   27 4  16   64 5  25  125 6  36  216 7  49  343 8  64  512 9  81  72910 100 1000

          注意:在第一个例子中, 每列间的空格由 print() 添加。

          这个例子展示了字符串对象的 rjust() 方法, 它可以将字符串靠右, 并在左边填充空格。

          还有类似的方法, 如 ljust() 和 center()。 这些方法并不会写任何东西, 它们仅仅返回新的字符串。

          另一个方法 zfill(), 它会在数字的左边填充 0,如下所示:

          >>> '12'.zfill(5)'00012'>>> '-3.14'.zfill(7)'-003.14'>>> '3.14159265359'.zfill(5)'3.14159265359'

          str.format() 的基本使用如下:

          >>> print('We are the {} who say "{}!"'.format('knights', 'Ni'))We are the knights who say "Ni!"

          括号及其里面的字符 (称作格式化字段) 将会被 format() 中的参数替换。

          在括号中的数字用于指向传入对象在 format() 中的位置,如下所示:

          >>> print('{0} and {1}'.format('spam', 'eggs'))spam and eggs>>> print('{1} and {0}'.format('spam', 'eggs'))eggs and spam

          如果在 format() 中使用了关键字参数, 那么它们的值会指向使用该名字的参数。

          >>> print('This {food} is {adjective}.'.format(...       food='spam', adjective='absolutely horrible'))This spam is absolutely horrible.

          位置及关键字参数可以任意的结合:

          >>> print('The story of {0}, {1}, and {other}.'.format('Bill', 'Manfred',other='Georg'))The story of Bill, Manfred, and Georg.

          '!a' (使用 ascii()), '!s' (使用 str()) 和 '!r' (使用 repr()) 可以用于在格式化某个值之前对其进行转化:

          >>> import math>>> print('The value of PI is approximately {}.'.format(math.pi))The value of PI is approximately 3.14159265359.>>> print('The value of PI is approximately {!r}.'.format(math.pi))The value of PI is approximately 3.141592653589793.

          可选项 ':' 和格式标识符可以跟着字段名。 这就允许对值进行更好的格式化。 下面的例子将 Pi 保留到小数点后三位:

          >>> import math>>> print('The value of PI is approximately {0:.3f}.'.format(math.pi))The value of PI is approximately 3.142.

          在 ':' 后传入一个整数, 可以保证该域至少有这么多的宽度。 用于美化表格时很有用。

          >>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}>>> for name, phone in table.items():...     print('{0:10} ==> {1:10d}'.format(name, phone))...Jack       ==>       4098Dcab       ==>       7678Sjoerd     ==>       4127

          如果你有一个很长的格式化字符串, 而你不想将它们分开, 那么在格式化时通过变量名而非位置会是很好的事情。

          最简单的就是传入一个字典, 然后使用方括号 '[]' 来访问键值 :

          >>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}>>> print('Jack: {0[Jack]:d}; Sjoerd: {0[Sjoerd]:d}; '          'Dcab: {0[Dcab]:d}'.format(table))Jack: 4098; Sjoerd: 4127; Dcab: 8637678

          也可以通过在 table 变量前使用 '**' 来实现相同的功能:

          >>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}>>> print('Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table))Jack: 4098; Sjoerd: 4127; Dcab: 8637678

          旧式字符串格式化

          % 操作符也可以实现字符串格式化。 它将左边的参数作为类似 sprintf() 式的格式化字符串, 而将右边的代入, 然后返回格式化后的字符串. 例如:

          >>> import math>>> print('The value of PI is approximately %5.3f.' % math.pi)The value of PI is approximately 3.142.

          因为 str.format() 比较新的函数, 大多数的 Python 代码仍然使用 % 操作符。但是因为这种旧式的格式化最终会从该语言中移除, 应该更多的使用 str.format().


          读和写文件

          open() 将会返回一个 file 对象,基本语法格式如下:

          open(filename, mode)

          实例:

          >>> f = open('/tmp/workfile', 'w')
          • 第一个参数为要打开的文件名。
          • 第二个参数描述文件如何使用的字符。 mode 可以是 'r' 如果文件只读, 'w' 只用于写 (如果存在同名文件则将被删除), 和 'a' 用于追加文件内容; 所写的任何数据都会被自动增加到末尾. 'r+' 同时用于读写。 mode 参数是可选的; 'r' 将是默认值。

          文件对象的方法

          本节中剩下的例子假设已经创建了一个称为 f 的文件对象。

          f.read()

          为了读取一个文件的内容,调用 f.read(size), 这将读取一定数目的数据, 然后作为字符串或字节对象返回。

          size 是一个可选的数字类型的参数。 当 size 被忽略了或者为负, 那么该文件的所有内容都将被读取并且返回。

          >>> f.read()'This is the entire file.
          '>>> f.read()''

          f.readline()

          f.readline() 会从文件中读取单独的一行。换行符为 ' '。f.readline() 如果返回一个空字符串, 说明已经已经读取到最后一行。

          >>> f.readline()'This is the first line of the file.
          '>>> f.readline()'Second line of the file
          '>>> f.readline()''

          f.readlines()

          f.readlines() 将返回该文件中包含的所有行。

          如果设置可选参数 sizehint, 则读取指定长度的字节, 并且将这些字节按行分割。

          >>> f.readlines()['This is the first line of the file.
          ', 'Second line of the file
          ']

          另一种方式是迭代一个文件对象然后读取每行:

          >>> for line in f:...     print(line, end='')...This is the first line of the file.Second line of the file

          这个方法很简单, 但是并没有提供一个很好的控制。 因为两者的处理机制不同, 最好不要混用。

          f.write()

          f.write(string) 将 string 写入到文件中, 然后返回写入的字符数。

          >>> f.write('This is a test
          ')15

          如果要写入一些不是字符串的东西, 那么将需要先进行转换:

          >>> value = ('the answer', 42)>>> s = str(value)>>> f.write(s)18

          f.tell()

          f.tell() 返回文件对象当前所处的位置, 它是从文件开头开始算起的字节数。

          f.seek()

          如果要改变文件当前的位置, 可以使用 f.seek(offset, from_what) 函数。

          from_what 的值, 如果是 0 表示开头, 如果是 1 表示当前位置, 2 表示文件的结尾,例如:

          • seek(x, 0) : 从起始位置即文件首行首字符开始移动 x 个字符
          • seek(x, 1) : 表示从当前位置往后移动x个字符
          • seek(-x, 2):表示从文件的结尾往前移动x个字符

          from_what 值为默认为 0,即文件开头。下面给出一个完整的例子:

          >>> f = open('/tmp/workfile', 'rb+')>>> f.write(b'0123456789abcdef')16>>> f.seek(5)     # 移动到文件的第六个字节5>>> f.read(1)b'5'>>> f.seek(-3, 2) # 移动到文件的倒数第三字节13>>> f.read(1)b'd'

          f.close()

          在文本文件中 (那些打开文件的模式下没有 b 的), 只会相对于文件起始位置进行定位。

          当你处理完一个文件后, 调用 f.close() 来关闭文件并释放系统的资源,如果尝试再调用该文件,则会抛出异常。

          >>> f.close()>>> f.read()Traceback (most recent call last):  File "<stdin>", line 1, in ?ValueError: I/O operation on closed file<pre><p>当处理一个文件对象时, 使用 with 关键字是非常好的方式。在结束后, 它会帮你正确的关闭文件。 而且写起来也比 try - finally 语句块要简短:</p><pre>>>> with open('/tmp/workfile', 'r') as f:...     read_data = f.read()>>> f.closedTrue

          文件对象还有其他方法, 如 isatty() 和 trucate(), 但这些通常比较少用。


          pickle 模块

          Python 的 pickle 模块实现了基本的数据序列和反序列化。

          通过 pickle 模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储。

          通过 pickle 模块的反序列化操作,我们能够从文件中创建上一次程序保存的对象。

          基本接口:

          pickle.dump(obj, file, [,protocol])

          有了 pickle 这个对象, 就能对 file 以读取的形式打开:

          x = pickle.load(file)

          注解:从 file 中读取一个字符串,并将它重构为原来的 Python 对象。

          file: 类文件对象,有read() 和 readline() 接口。

          实例 1:

          #使用pickle模块将数据对象保存到文件import pickledata1 = {'a': [1, 2.0, 3, 4+6j],         'b': ('string', u'Unicode string'),         'c': None}selfref_list = [1, 2, 3]selfref_list.append(selfref_list)output = open('data.pkl', 'wb')# Pickle dictionary using protocol 0.pickle.dump(data1, output)# Pickle the list using the highest protocol available.pickle.dump(selfref_list, output, -1)output.close()

          实例 2:

          #使用pickle模块从文件中重构python对象import pprint, picklepkl_file = open('data.pkl', 'rb')data1 = pickle.load(pkl_file)pprint.pprint(data1)data2 = pickle.load(pkl_file)pprint.pprint(data2)pkl_file.close()


          file 文件对象使用 open 函数来创建,下表列出了 file 文件对象常用的函数:

          序号方法及描述
          1

          file.close()

          关闭文件。关闭后文件不能再进行读写操作。

          2

          file.flush()

          刷新文件内部缓冲,直接把内部缓冲区的数据立刻写入文件, 而不是被动的等待输出缓冲区写入。

          3

          file.fileno()

          返回一个整型的文件描述符 (file descriptor FD 整型), 可以用在如 os 模块的 read 方法等一些底层操作上。

          4

          file.isatty()

          如果文件连接到一个终端设备返回 True,否则返回 False。

          5

          file.next()

          返回文件下一行。

          6

          file.read([size])

          从文件读取指定的字节数,如果未给定或为负则读取所有。

          7

          file.readline([size])

          读取整行,包括 " " 字符。

          8

          file.readlines([sizehint])

          读取所有行并返回列表,若给定 sizeint>0,返回总和大约为 sizeint 字节的行, 实际读取值可能比 sizeint 较大, 因为需要填充缓冲区。

          9

          file.seek(offset[, whence])

          设置文件当前位置

          10

          file.tell()

          返回文件当前位置。

          11

          file.truncate([size])

          截取文件,截取的字节通过 size 指定,默认为当前文件位置。

          12

          file.write(str)

          将字符串写入文件,返回的是写入的字符长度。

          13

          file.writelines(sequence)

          向文件写入一个序列字符串列表,如果需要换行则要自己加入每行的换行符。


          os 模块提供了非常丰富的方法用来处理文件和目录。常用的方法如下表所示:

          序号方法及描述
          1

          os.access(path, mode)

          检验权限模式。
          2

          os.chdir(path)

          改变当前工作目录。
          3

          os.chflags(path, flags)

          设置路径的标记为数字标记。
          4

          os.chmod(path, mode)

          更改权限。
          5

          os.chown(path, uid, gid)

          更改文件所有者。
          6

          os.chroot(path)

          改变当前进程的根目录。
          7

          os.close(fd)

          关闭文件描述符 fd。
          8

          os.closerange(fd_low, fd_high)

          关闭所有文件描述符,从 fd_low (包含) 到 fd_high (不包含), 错误会忽略。
          9

          os.dup(fd)

          复制文件描述符 fd。
          10

          os.dup2(fd, fd2)

          将一个文件描述符 fd 复制到另一个 fd2。
          11

          os.fchdir(fd)

          通过文件描述符改变当前工作目录。
          12

          os.fchmod(fd, mode)

          改变一个文件的访问权限,该文件由参数 fd 指定,参数 mode 是 Unix 下的文件访问权限。
          13

          os.fchown(fd, uid, gid)

          修改一个文件的所有权,这个函数修改一个文件的用户 ID 和用户组 ID,该文件由文件描述符 fd 指定。
          14

          os.fdatasync(fd)

          强制将文件写入磁盘,该文件由文件描述符 fd 指定,但是不强制更新文件的状态信息。
          15

          os.fdopen(fd[, mode[, bufsize]])

          通过文件描述符 fd 创建一个文件对象,并返回这个文件对象。
          16

          os.fpathconf(fd, name)

          返回一个打开的文件的系统配置信息。name 为检索的系统配置的值,它也许是一个定义系统值的字符串,这些名字在很多标准中指定(POSIX.1, Unix 95, Unix 98, 和其它)。
          17

          os.fstat(fd)

          返回文件描述符 fd 的状态,像 stat()。
          18

          os.fstatvfs(fd)

          返回包含文件描述符 fd 的文件的文件系统的信息,像 statvfs()。
          19

          os.fsync(fd)

          强制将文件描述符为 fd 的文件写入硬盘。
          20

          os.ftruncate(fd, length)

          裁剪文件描述符 fd 对应的文件, 所以它最大不能超过文件大小。
          21

          os.getcwd()

          返回当前工作目录。
          22

          os.getcwdu()

          返回一个当前工作目录的 Unicode 对象。
          23

          os.isatty(fd)

          如果文件描述符 fd 是打开的,同时与 tty(-like) 设备相连,则返回 true, 否则 False。
          24

          os.lchflags(path, flags)

          设置路径的标记为数字标记,类似 chflags(),但是没有软链接。
          25

          os.lchmod(path, mode)

          修改连接文件权限。
          26

          os.lchown(path, uid, gid)

          更改文件所有者,类似 chown,但是不追踪链接。
          27

          os.link(src, dst)

          创建硬链接,名为参数 dst,指向参数 src。
          28

          os.listdir(path)

          返回 path 指定的文件夹包含的文件或文件夹的名字的列表。
          29

          os.lseek(fd, pos, how)

          设置文件描述符 fd 当前位置为 pos, how 方式修改: SEEK_SET 或者 0 设置从文件开始的计算的 pos; SEEK_CUR 或者 1 则从当前位置计算;os.SEEK_END 或者 2 则从文件尾部开始。在 unix,Windows 中有效。
          30

          os.lstat(path)

          像 stat(),但是没有软链接。
          31

          os.major(device)

          从原始的设备号中提取设备 major 号码 (使用 stat 中的 st_dev 或者 st_rdev field)。
          32

          os.makedev(major, minor)

          以 major 和 minor 设备号组成一个原始设备号。
          33

          os.makedirs(path[, mode])

          递归文件夹创建函数。像 mkdir(), 但创建的所有 intermediate-level 文件夹需要包含子文件夹。
          34

          os.minor(device)

          从原始的设备号中提取设备 minor 号码 (使用 stat 中的 st_dev 或者 st_rdev field )。
          35

          os.mkdir(path[, mode])

          以数字 mode 的 mode 创建一个名为 path 的文件夹。默认的 mode 是 0777 (八进制)。
          36

          os.mkfifo(path[, mode])

          创建命名管道,mode 为数字,默认为 0666 (八进制)。
          37

          os.mknod(filename[, mode=0600, device])
          创建一个名为 filename 文件系统节点(文件,设备特别文件或者命名 pipe)。

          38

          os.open(file, flags[, mode])

          打开一个文件,并且设置需要的打开选项,mode 参数是可选的。
          39

          os.openpty()

          打开一个新的伪终端对。返回 pty 和 tty 的文件描述符。
          40

          os.pathconf(path, name)

          返回相关文件的系统配置信息。
          41

          os.pipe()

          创建一个管道. 返回一对文件描述符 (r, w) 分别为读和写
          42

          os.popen(command[, mode[, bufsize]])

          从一个 command 打开一个管道。
          43

          os.read(fd, n)

          从文件描述符 fd 中读取最多 n 个字节,返回包含读取字节的字符串,文件描述符 fd 对应文件已达到结尾,返回一个空字符串。
          44

          os.readlink(path)

          返回软链接所指向的文件。
          45

          os.remove(path)

          删除路径为 path 的文件。如果 path 是一个文件夹,将抛出 OSError; 查看下面的 rmdir() 删除一个 directory。
          46

          os.removedirs(path)

          递归删除目录。
          47

          os.rename(src, dst)

          重命名文件或目录,从 src 到 dst。
          48

          os.renames(old, new)

          递归地对目录进行更名,也可以对文件进行更名。
          49

          os.rmdir(path)

          删除 path 指定的空目录,如果目录非空,则抛出一个 OSError 异常。
          50

          os.stat(path)

          获取 path 指定的路径的信息,功能等同于 C API 中的 stat() 系统调用。
          51

          os.stat_float_times([newvalue])
          决定 stat_result 是否以 float 对象显示时间戳。

          52

          os.statvfs(path)

          获取指定路径的文件系统统计信息。
          53

          os.symlink(src, dst)

          创建一个软链接。
          54

          os.tcgetpgrp(fd)

          返回与终端 fd(一个由 os.open() 返回的打开的文件描述符)关联的进程组。
          55

          os.tcsetpgrp(fd, pg)

          设置与终端 fd(一个由 os.open() 返回的打开的文件描述符)关联的进程组为 pg。
          56

          os.tempnam([dir[, prefix]])

          返回唯一的路径名用于创建临时文件。
          57

          os.tmpfile()

          返回一个打开的模式为 (w+b) 的文件对象,这文件对象没有文件夹入口,没有文件描述符,将会自动删除。
          58

          os.tmpnam()

          为创建一个临时文件返回一个唯一的路径。
          59

          os.ttyname(fd)

          返回一个字符串,它表示与文件描述符 fd 关联的终端设备。如果 fd 没有与终端设备关联,则引发一个异常。
          60

          os.unlink(path)

          删除文件路径。
          61

          os.utime(path, times)

          返回指定的 path 文件的访问和修改的时间。
          62

          os.walk(top[, topdown=True[, onerror=None[, followlinks=False]]])

          输出在文件夹中的文件名通过在树中游走,向上或者向下。
          63

          os.write(fd, str)

          写入字符串到文件描述符 fd 中,返回实际写入的字符串长度


          作为 Python 初学者,在刚学习 Python 编程时,经常会看到一些报错信息,在前面我们没有提及,这章节我们会专门介绍。

          Python 有两种错误很容易辨认:语法错误和异常。

          语法错误

          Python 的语法错误或者称之为解析错,是初学者经常碰到的,如下实例

          >>> while True print('Hello world')  File "<stdin>", line 1, in ?    while True print('Hello world')                   ^SyntaxError: invalid syntax

          这个例子中,函数 print() 被检查到有错误,是它前面缺少了一个冒号(:)。

          语法分析器指出了出错的一行,并且在最先找到的错误的位置标记了一个小小的箭头。

          异常

          即便 Python 程序的语法是正确的,在运行它的时候,也有可能发生错误。运行期检测到的错误被称为异常。

          大多数的异常都不会被程序处理,都以错误信息的形式展现在这里:

          >>> 10 * (1/0)Traceback (most recent call last):  File "<stdin>", line 1, in ?ZeroDivisionError: division by zero>>> 4 + spam*3Traceback (most recent call last):  File "<stdin>", line 1, in ?NameError: name 'spam' is not defined>>> '2' + 2Traceback (most recent call last):  File "<stdin>", line 1, in ?TypeError: Can't convert 'int' object to str implicitly

          异常以不同的类型出现,这些类型都作为信息的一部分打印出来: 例子中的类型有 ZeroDivisionError,NameError 和 TypeError。

          错误信息的前面部分显示了异常发生的上下文,并以调用栈的形式显示具体信息。

          异常处理

          以下例子中,让用户输入一个合法的整数,但是允许用户中断这个程序(使用 Control-C 或者操作系统提供的方法)。用户中断的信息会引发一个 KeyboardInterrupt 异常。

          >>> while True:        try:            x = int(input("Please enter a number: "))            break        except ValueError:            print("Oops!  That was no valid number.  Try again   ")   

          try 语句按照如下方式工作;

          • 首先,执行 try 子句(在关键字 try 和关键字 except 之间的语句)
          • 如果没有异常发生,忽略 except 子句,try 子句执行后结束。
          • 如果在执行 try 子句的过程中发生了异常,那么 try 子句余下的部分将被忽略。如果异常的类型和 except 之后的名称相符,那么对应的 except 子句将被执行。最后执行 try 语句之后的代码。
          • 如果一个异常没有与任何的 except 匹配,那么这个异常将会传递给上层的 try 中。

          一个 try 语句可能包含多个 except 子句,分别来处理不同的特定的异常。最多只有一个分支会被执行。

          处理程序将只针对对应的 try 子句中的异常进行处理,而不是其他的 try 的处理程序中的异常。

          一个 except 子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组,例如:

          >>> except (RuntimeError, TypeError, NameError):        pass

          最后一个 except 子句可以忽略异常的名称,它将被当作通配符使用。你可以使用这种方法打印一个错误信息,然后再次把异常抛出。

          import systry:    f = open('myfile.txt')    s = f.readline()    i = int(s.strip())except OSError as err:    print("OS error: {0}".format(err))except ValueError:    print("Could not convert data to an integer.")except:    print("Unexpected error:", sys.exc_info()[0])    raise

          try except 语句还有一个可选的 else 子句,如果使用这个子句,那么必须放在所有的 except 子句之后。这个子句将在 try 子句没有发生任何异常的时候执行。例如:

          for arg in sys.argv[1:]:    try:        f = open(arg, 'r')    except IOError:        print('cannot open', arg)    else:        print(arg, 'has', len(f.readlines()), 'lines')        f.close()

          使用 else 子句比把所有的语句都放在 try 子句里面要好,这样可以避免一些意想不到的、而except又没有捕获的异常。

          异常处理并不仅仅处理那些直接发生在try子句中的异常,而且还能处理子句中调用的函数(甚至间接调用的函数)里抛出的异常。例如:

          >>> def this_fails():        x = 1/0   >>> try:        this_fails()    except ZeroDivisionError as err:        print('Handling run-time error:', err)   Handling run-time error: int division or modulo by zero

          抛出异常

          Python 使用 raise 语句抛出一个指定的异常。例如:

          >>> raise NameError('HiThere')Traceback (most recent call last):  File "<stdin>", line 1, in ?NameError: HiThere

          raise 唯一的一个参数指定了要被抛出的异常。它必须是一个异常的实例或者是异常的类(也就是 Exception 的子类)。

          如果你只想知道这是否抛出了一个异常,并不想去处理它,那么一个简单的 raise 语句就可以再次把它抛出。

          >>> try:        raise NameError('HiThere')    except NameError:        print('An exception flew by!')        raise   An exception flew by!Traceback (most recent call last):  File "<stdin>", line 2, in ?NameError: HiThere

          用户自定义异常

          你可以通过创建一个新的 exception 类来拥有自己的异常。异常应该继承自 Exception 类,或者直接继承,或者间接继承,例如:

          >>> class MyError(Exception):        def __init__(self, value):            self.value = value        def __str__(self):            return repr(self.value)   >>> try:        raise MyError(2*2)    except MyError as e:        print('My exception occurred, value:', e.value)   My exception occurred, value: 4>>> raise MyError('oops!')Traceback (most recent call last):  File "<stdin>", line 1, in ?__main__.MyError: 'oops!'

          在这个例子中,类 Exception 默认的 __init__() 被覆盖。

          异常的类可以像其他的类一样做任何事情,但是通常都会比较简单,只提供一些错误相关的属性,并且允许处理异常的代码方便的获取这些信息。

          当创建一个模块有可能抛出多种不同的异常时,一种通常的做法是为这个包建立一个基础异常类,然后基于这个基础类为不同的错误情况创建不同的子类:

          class Error(Exception):    """Base class for exceptions in this module."""    passclass InputError(Error):    """Exception raised for errors in the input.    Attributes:        expression -- input expression in which the error occurred        message -- explanation of the error    """    def __init__(self, expression, message):        self.expression = expression        self.message = messageclass TransitionError(Error):    """Raised when an operation attempts a state transition that's not    allowed.    Attributes:        previous -- state at beginning of transition        next -- attempted new state        message -- explanation of why the specific transition is not allowed    """    def __init__(self, previous, next, message):        self.previous = previous        self.next = next        self.message = message

          大多数的异常的名字都以"Error"结尾,就跟标准的异常命名一样。


          定义清理行为

          try 语句还有另外一个可选的子句,它定义了无论在任何情况下都会执行的清理行为。 例如:

          >>> try:        raise KeyboardInterrupt    finally:        print('Goodbye, world!')   Goodbye, world!KeyboardInterrupt

          以上例子不管 try 子句里面有没有发生异常,finally 子句都会执行。

          如果一个异常在 try 子句里(或者在 except 和 else 子句里)被抛出,而又没有任何的 except 把它截住,那么这个异常会在 finally 子句执行后再次被抛出。

          下面是一个更加复杂的例子(在同一个 try 语句里包含 except 和 finally 子句):

          >>> def divide(x, y):        try:            result = x / y        except ZeroDivisionError:            print("division by zero!")        else:            print("result is", result)        finally:            print("executing finally clause")   >>> divide(2, 1)result is 2.0executing finally clause>>> divide(2, 0)division by zero!executing finally clause>>> divide("2", "1")executing finally clauseTraceback (most recent call last):  File "<stdin>", line 1, in ?  File "<stdin>", line 3, in divideTypeError: unsupported operand type(s) for /: 'str' and 'str'

          预定义的清理行为

          一些对象定义了标准的清理行为,无论系统是否成功的使用了它,一旦不需要它了,那么这个标准的清理行为就会执行。

          这面这个例子展示了尝试打开一个文件,然后把内容打印到屏幕上:

          for line in open("myfile.txt"):    print(line, end="")

          以上这段代码的问题是,当执行完毕后,文件会保持打开状态,并没有被关闭。

          关键词 with 语句就可以保证诸如文件之类的对象在使用完之后一定会正确的执行他的清理方法:

          with open("myfile.txt") as f:    for line in f:        print(line, end="")

          以上这段代码执行完毕后,就算在处理过程中出问题了,文件 f 总是会关闭。


          Python 从设计之初就是一门面向对象的语言,正因为如此,在 Python 中创建一个类和对象是很容易的。本章节我们将详细介绍 Python 的面向对象编程。

          如果你以前没有接触过面向对象的编程语言,那你可能需要先了解一些面向对象语言的一些基本特征,在头脑里头形成一个基本的面向对象的概念,这样有助于你更容易的学习 Python 的面向对象编程。

          接下来我们先来简单的了解下面向对象的一些基本特征。


          Python3 面向对象技术简介

          • 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
          • 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
          • 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
          • 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
          • 局部变量:定义在方法中的变量,只作用于当前实例的类。
          • 实例变量:在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。
          • 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个 Dog 类型的对象派生自 Animal 类,这是模拟"是一个(is-a)"关系(例图,Dog 是一个 Animal)。
          • 实例化:创建一个类的实例,类的具体对象。
          • 方法:类中定义的函数。
          • 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

          和其它编程语言相比,Python 在尽可能不增加新的语法和语义的情况下加入了类机制。

          Python 中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法。

          对象可以包含任意数量和类型的数据。

          类定义

          语法格式如下:

          class ClassName:    <statement-1>    .    .    .    <statement-N>

          类实例化后,可以使用其属性,实际上,创建一个类之后,可以通过类名访问其属性。

          类对象

          类对象支持两种操作:属性引用和实例化。

          属性引用使用和 Python 中所有的属性引用一样的标准语法:obj.name

          类对象创建后,类命名空间中所有的命名都是有效属性名。所以如果类定义是这样:

          #!/usr/bin/python3class MyClass:    """一个简单的类实例"""    i = 12345    def f(self):        return 'hello world'# 实例化类x = MyClass()# 访问类的属性和方法print("MyClass 类的属性 i 为:", x.i)print("MyClass 类的方法 f 输出为:", x.f())

          实例化类:

          # 实例化类x = MyClass()# 访问类的属性和方法

          以上创建了一个新的类实例并将该对象赋给局部变量 x,x 为空的对象。

          执行以上程序输出结果为:

          MyClass 类的属性 i 为: 12345MyClass 类的方法 f 输出为: hello world

          很多类都倾向于将对象创建为有初始状态的。因此类可能会定义一个名为 __init__() 的特殊方法(构造方法),像下面这样:

          def __init__(self):    self.data = []

          类定义了 __init__() 方法的话,类的实例化操作会自动调用 __init__() 方法。所以在下例中,可以这样创建一个新的实例:

          x = MyClass()

          当然, __init__() 方法可以有参数,参数通过 __init__() 传递到类的实例化操作上。例如:

          >>> class Complex:...     def __init__(self, realpart, imagpart):...         self.r = realpart...         self.i = imagpart...>>> x = Complex(3.0, -4.5)>>> x.r, x.i(3.0, -4.5)

          类的方法

          在类的内部,使用 def 关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数:

          #!/usr/bin/python3#类定义class people:    #定义基本属性    name = ''    age = 0    #定义私有属性,私有属性在类外部无法直接进行访问    __weight = 0    #定义构造方法    def __init__(self,n,a,w):        self.name = n        self.age = a        self.__weight = w    def speak(self):        print("%s 说: 我 %d 岁。" %(self.name,self.age))# 实例化类p = people('W3Cschool',10,30)p.speak()

          执行以上程序输出结果为:

          W3Cschool 说:  10 岁。

          继承

          Python 同样支持类的继承,如果一种语言不支持继承,类就没有什么意义。派生类的定义如下所示:

          class DerivedClassName(BaseClassName1):    <statement-1>    .    .    .    <statement-N>

          需要注意圆括号中基类的顺序,若是基类中有相同的方法名,而在子类使用时未指定,Python 从左至右搜索 即方法在子类中未找到时,从左到右查找基类中是否包含方法。

          BaseClassName(示例中的基类名)必须与派生类定义在一个作用域内。除了类,还可以用表达式,基类定义在另一个模块中时这一点非常有用:

          class DerivedClassName(modname.BaseClassName):

          实例

          #!/usr/bin/python3#类定义class people:    #定义基本属性    name = ''    age = 0    #定义私有属性,私有属性在类外部无法直接进行访问    __weight = 0    #定义构造方法    def __init__(self,n,a,w):        self.name = n        self.age = a        self.__weight = w    def speak(self):        print("%s 说: 我 %d 岁。" %(self.name,self.age))#单继承示例class student(people):    grade = ''    def __init__(self,n,a,w,g):        #调用父类的构函        people.__init__(self,n,a,w)        self.grade = g    #覆写父类的方法    def speak(self):        print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))s = student('ken',10,60,3)s.speak()

          执行以上程序输出结果为:

          ken 说:  10 岁了,我在读 3 年级

          多继承

          Python 同样有限的支持多继承形式。多继承的类定义形如下例:

          class DerivedClassName(Base1, Base2, Base3):    <statement-1>    .    .    .    <statement-N>

          需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,Python 从左至右搜索 即方法在子类中未找到时,从左到右查找父类中是否包含方法。

          #!/usr/bin/python3#类定义class people:    #定义基本属性    name = ''    age = 0    #定义私有属性,私有属性在类外部无法直接进行访问    __weight = 0    #定义构造方法    def __init__(self,n,a,w):        self.name = n        self.age = a        self.__weight = w    def speak(self):        print("%s 说: 我 %d 岁。" %(self.name,self.age))#单继承示例class student(people):    grade = ''    def __init__(self,n,a,w,g):        #调用父类的构函        people.__init__(self,n,a,w)        self.grade = g    #覆写父类的方法    def speak(self):        print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))#另一个类,多重继承之前的准备class speaker():    topic = ''    name = ''    def __init__(self,n,t):        self.name = n        self.topic = t    def speak(self):        print("我叫 %s,我是一个演说家,我演讲的主题是 %s"%(self.name,self.topic))#多重继承class sample(speaker,student):    a =''    def __init__(self,n,a,w,g,t):        student.__init__(self,n,a,w,g)        speaker.__init__(self,n,t)test = sample("Tim",25,80,4,"Python")test.speak()   #方法名同,默认调用的是在括号中排前地父类的方法

          执行以上程序输出结果为:

          我叫 Tim,我是一个演说家,我演讲的主题是 Python

          方法重写

          如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法,实例如下:

          #!/usr/bin/python3class Parent:        # 定义父类   def myMethod(self):      print ('调用父类方法')class Child(Parent): # 定义子类   def myMethod(self):      print ('调用子类方法')c = Child()          # 子类实例c.myMethod()         # 子类调用重写方法

          执行以上程序输出结果为:

          调用子类方法

          类属性与方法

          类的私有属性

          __private_attrs:两个下划线开头,声明该属性为私有,不能在类地外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs

          类的方法

          在类地内部,使用 def 关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数 self, 且为第一个参数

          类的私有方法

          __private_method:两个下划线开头,声明该方法为私有方法,不能在类地外部调用。在类的内部调用 slef.__private_methods

          实例如下:

          #!/usr/bin/python3class JustCounter:    __secretCount = 0  # 私有变量    publicCount = 0    # 公开变量    def count(self):        self.__secretCount += 1        self.publicCount += 1        print (self.__secretCount)counter = JustCounter()counter.count()counter.count()print (counter.publicCount)print (counter.__secretCount)  # 报错,实例不能访问私有变量

          执行以上程序输出结果为:

          122Traceback (most recent call last):  File "test.py", line 16, in <module>    print (counter.__secretCount)  # 报错,实例不能访问私有变量AttributeError: 'JustCounter' object has no attribute '__secretCount'

          类的专有方法:

          • __init__ : 构造函数,在生成对象时调用
          • __del__ : 析构函数,释放对象时使用
          • __repr__ : 打印,转换
          • __setitem__ : 按照索引赋值
          • __getitem__: 按照索引获取值
          • __len__: 获得长度
          • __cmp__: 比较运算
          • __call__: 函数调用
          • __add__: 加运算
          • __sub__: 减运算
          • __mul__: 乘运算
          • __div__: 除运算
          • __mod__: 求余运算
          • __pow__: 乘方

          运算符重载

          Python 同样支持运算符重载,我么可以对类的专有方法进行重载,实例如下:

          #!/usr/bin/python3class Vector:   def __init__(self, a, b):      self.a = a      self.b = b   def __str__(self):      return 'Vector (%d, %d)' % (self.a, self.b)      def __add__(self,other):      return Vector(self.a + other.a, self.b + other.b)v1 = Vector(2,10)v2 = Vector(5,-2)print (v1 + v2)

          以上代码执行结果如下所示:

          Vector(7,8)


          Python 语言参考手册描述了具体语法和语义,并介绍了与 Python 一起发布的标准库。本文还描述了发行版中通常包含的一些可选组件。

          操作系统接口

          os 模块提供了不少与操作系统相关联的函数。

          >>> import os>>> os.getcwd()      # 返回当前的工作目录'C:Python34'>>> os.chdir('/server/accesslogs')   # 修改当前的工作目录>>> os.system('mkdir today')   # 执行系统命令 mkdir 0

          建议使用 "import os" 风格而非 "from os import *"。这样可以保证随操作系统不同而有所变化的 os.open() 不会覆盖内置函数 open()。

          在使用 os 这样的大型模块时内置的 dir() 和 help() 函数非常有用:

          >>> import os>>> dir(os)<returns a list of all module functions>>>> help(os)<returns an extensive manual page created from the module's docstrings>

          针对日常的文件和目录管理任务,:mod:shutil 模块提供了一个易于使用的高级接口:

          >>> import shutil>>> shutil.copyfile('data.db', 'archive.db')>>> shutil.move('/build/executables', 'installdir')

          文件通配符

          glob 模块提供了一个函数用于从目录通配符搜索中生成文件列表:

          >>> import glob>>> glob.glob('*.py')['primes.py', 'random.py', 'quote.py']

          命令行参数

          通用工具脚本经常调用命令行参数。这些命令行参数以链表形式存储于 sys 模块的 argv 变量。例如在命令行中执行 "python demo.py one two three" 后可以得到以下输出结果:

          >>> import sys>>> print(sys.argv)['demo.py', 'one', 'two', 'three']

          错误输出重定向和程序终止

          sys 还有 stdin,stdout 和 stderr 属性,即使在 stdout 被重定向时,后者也可以用于显示警告和错误信息。

          >>> sys.stderr.write('Warning, log file not found starting a new one
          ')Warning, log file not found starting a new one

          大多脚本的定向终止都使用 "sys.exit()"。


          字符串正则匹配

          re 模块为高级字符串处理提供了正则表达式工具。对于复杂的匹配和处理,正则表达式提供了简洁、优化的解决方案:

          >>> import re>>> re.findall(r'f[a-z]*', 'which foot or hand fell fastest')['foot', 'fell', 'fastest']>>> re.sub(r'([a-z]+) 1', r'1', 'cat in the the hat')'cat in the hat'

          如果只需要简单的功能,应该首先考虑字符串方法,因为它们非常简单,易于阅读和调试:

          >>> 'tea for too'.replace('too', 'two')'tea for two'

          数学

          math 模块为浮点运算提供了对底层 C 函数库的访问:

          >>> import math>>> math.cos(math.pi / 4)0.70710678118654757>>> math.log(1024, 2)10.0

          random 提供了生成随机数的工具。

          >>> import random>>> random.choice(['apple', 'pear', 'banana'])'apple'>>> random.sample(range(100), 10)   # sampling without replacement[30, 83, 16, 4, 8, 81, 41, 50, 18, 33]>>> random.random()    # random float0.17970987693706186>>> random.randrange(6)    # random integer chosen from range(6)4

          访问 互联网

          有几个模块用于访问互联网以及处理网络通信协议。其中最简单的两个是用于处理从 urls 接收的数据的 urllib.request 以及用于发送电子邮件的 smtplib:

          >>> from urllib.request import urlopen>>> for line in urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'):...     line = line.decode('utf-8')  # Decoding the binary data to text....     if 'EST' in line or 'EDT' in line:  # look for Eastern Time...         print(line)<BR>Nov. 25, 09:43:32 PM EST>>> import smtplib>>> server = smtplib.SMTP('localhost')>>> server.sendmail('soothsayer@example.org', 'jcaesar@example.org',... """To: jcaesar@example.org... From: soothsayer@example.org...... Beware the Ides of March.... """)>>> server.quit()

          注意第二个例子需要本地有一个在运行的邮件服务器。


          日期和时间

          datetime 模块为日期和时间处理同时提供了简单和复杂的方法。

          支持日期和时间算法的同时,实现的重点放在更有效的处理和格式化输出。

          该模块还支持时区处理:

          >>> # dates are easily constructed and formatted>>> from datetime import date>>> now = date.today()>>> nowdatetime.date(2003, 12, 2)>>> now.strftime("%m-%d-%y. %d %b %Y is a %A on the %d day of %B.")'12-02-03. 02 Dec 2003 is a Tuesday on the 02 day of December.'>>> # dates support calendar arithmetic>>> birthday = date(1964, 7, 31)>>> age = now - birthday>>> age.days14368

          数据压缩

          以下模块直接支持通用的数据打包和压缩格式:zlib,gzip,bz2,zipfile,以及 tarfile。

          >>> import zlib>>> s = b'witch which has which witches wrist watch'>>> len(s)41>>> t = zlib.compress(s)>>> len(t)37>>> zlib.decompress(t)b'witch which has which witches wrist watch'>>> zlib.crc32(s)226805979

          性能度量

          有些用户对了解解决同一问题的不同方法之间的性能差异很感兴趣。Python 提供了一个度量工具,为这些问题提供了直接答案。

          例如,使用元组封装和拆封来交换元素看起来要比使用传统的方法要诱人的多,timeit 证明了现代的方法更快一些。

          >>> from timeit import Timer>>> Timer('t=a; a=b; b=t', 'a=1; b=2').timeit()0.57535828626024577>>> Timer('a,b = b,a', 'a=1; b=2').timeit()0.54962537085770791

          相对于 timeit 的细粒度,:mod:profile 和 pstats 模块提供了针对更大代码块的时间度量工具。


          测试模块

          开发高质量软件的方法之一是为每一个函数开发测试代码,并且在开发过程中经常进行测试

          doctest 模块提供了一个工具,扫描模块并根据程序中内嵌的文档字符串执行测试。

          测试构造如同简单的将它的输出结果剪切并粘贴到文档字符串中。

          通过用户提供的例子,它强化了文档,允许 doctest 模块确认代码的结果是否与文档一致:

          def average(values):    """Computes the arithmetic mean of a list of numbers.    >>> print(average([20, 30, 70]))    40.0    """    return sum(values) / len(values)import doctestdoctest.testmod()   # 自动验证嵌入测试

          unittest 模块不像 doctest 模块那么容易使用,不过它可以在一个独立的文件里提供一个更全面的测试集:

          import unittestclass TestStatisticalFunctions(unittest.TestCase):    def test_average(self):        self.assertEqual(average([20, 30, 70]), 40.0)        self.assertEqual(round(average([1, 5, 7]), 1), 4.3)        self.assertRaises(ZeroDivisionError, average, [])        self.assertRaises(TypeError, average, 20, 30, 70)unittest.main() # Calling from the command line invokes all tests

          python3.10版本于2021年10月4日发布正式版,该版本带来了七大新特性。为了让大家对新版本有更好的认识,接下来的介绍会尽量添加python3.10版本和旧版本的代码进行对比。

           带*号的为比较重要的特性。

          *类型检查改进

          Python3.10版本中,联合运算符使用“|”线来代替了旧版本中的Union[]方法,使得程序更加简洁,不仅如此,Python3.10在一些内置函数中,同样可以利用“|”线的联合运算符来提升程序的性能。

          在函数中:

          from typing import Union # 使用Union需要引入对应的包

          # 旧版本

          def oldFunc(para: Union[int, float]) -> Union[int, float]: 

              return para ** 2

          # 新版本

          def newFunc(para: int | float) -> int | float:

              return para ** 2

          print(newFunc(3))

          在内置函数中使用联合运算符:

          # 旧版本

          print(isinstance("W3Cschool", (str, int)))

          # 新版本

          print(isinstance("W3Cschool", str | int))

          *上下文管理器

          python3.10 中,with 支持使用外层圆括号来使用多个上下文管理器,可以连续多行地书写。这允许将过长的上下文管理器集能够以与之前 import 语句类似的方式格式化为多行的形式。例如,以下这些示例写法现在都是有效的:

          with (CtxManager() as example):    passwith (CtxManager1(),    CtxManager2()):    passwith (CtxManager1() as example,      CtxManager2()):    passwith (CtxManager1(),      CtxManager2() as example):    passwith (CtxManager1() as example1,    CtxManager2() as example2):    pass

          *模板匹配

          Python 3.10 引入了结构化的模式匹配,通过match...case关键词来完成,可以匹配字典,类以及其他更复杂的结构。match...case的模式匹配,在使用的方式上与C++中的switch有很多的相似之处。

          下面的函数中,case函数通过匹配grade,如果grade为'A',则匹配到第一个例子,如果grade为'B',则匹配到第二个例子...如果前面的案例都不满足时,则输出最后的默认结果。

          grade = 'B'
          match grade: # 看grade变量,并与下面的case做对比(类似其他语言的switch
          case 'A': # 如果grade为'A',则执行该代码块
          print("很棒")
          case 'B': # 如果grade为'B',则执行该代码块
          print("做得好")
          case 'C': # 如果grade为'C',则执行该代码块
          print("您通过了")
          case "D":
          print("最好再试一下")
          case _: # 如果上面的所有case都未命中,则执行该代码块(类似于其他语言的default)
          print("无效的成绩")

          字典增加mapping属性

          在Python3.10中,针对于字典的三个方法,items,keys和values都增加了一个新的“mapping”属性,通过上述的程序可以发现,对三个方法调用mapping属性后都会返回原字典数据。

          mydict = {"W3Cschool": 1, "baidu": 2, "Google": 3}

          # 旧版本
          print(mydict.keys())
          print(mydict.values())
          print(mydict.items())

          # 新版本
          keys = mydict.keys()
          values = mydict.values()
          items = mydict.items()

          print(keys.mapping)
          print(values.mapping)
          print(items.mapping)

          # 可以理解为我们可以根据字典的keys,values,items反向推出这个字典

          函数 zip() 增加 strict 参数

          Python3.10中对于zip函数添加了strict参数,顾名思义,strict参数就是要严格的遵守参数长度的匹配原则,下面程序中,keys和values列表的长度并不一致。

          旧版本的zip函数会根据长度最短的参数来创建字典。新版本的zip函数中,当设定strict参数设置为True时,则要求zip的输入参数必须要长度一致,否则就会报错。

          keys = ['W3Cschool', 'Baidu', 'Google']
          values = [1,2,3,4]
          #旧版本
          try:
          print(dict(zip(keys,values)))
          except:
          print("字典创建失败")

          try:
          print(dict(zip(keys, values, strict=True)))
          # 增加strict参数后,如果两个列表长度不等,创建的时候会报错
          except:
          print("字典创建失败")#报错后使用try-except语句捕获

          二进制表示中的频率为1的数量统计

          在Python3.10版本中,可以通过调用bit_count函数来统计二进制中数字“1”的个数,当然,在旧版本中,也可以通过很简单的代码实现这个功能。

          value = 5#旧版本print(bin(value).count("1"))#新版本print(value.bit_count())

          类型别名的更改

          在旧版本中,可以直接通过不同类型的赋值操作来赋予类型新的名字,而在Python3.10版本中,则通过TypeAlias来规定了类型名字的替换。这样操作的优势在于能够让程序开发人员和Python编辑器更加清楚的知道newname是一个变量名还是一个类型的别名,提升程序开发的可靠性。

          from typing import TypeAlias # 使用TypeAlias需要导入相关的包

          #旧版本oldname = strdef oldFunc(paran:olaname)->oldname:    return param+param#新版本newname:TypeAlias = strdef newFunc(param:newname)->newname:    return param+paramprint(newFunc("W3Cschool"))

          准备弃用Distutils 内置库

          由于Distutils库的功能已经被此setuptools和package库取代了,所以本着简洁性的原则,Distutils在不久的将来(3.12版本)将会被完全的删除掉。

           Distutils包为将待构建和安装的额外的模块,打包成 Python 安装包提供支持。新模块既可以是百分百的纯 Python,也可以是用 C 写的扩展模块,或者可以是一组包含了同时用 Python 和 C 编码的 Python 包。

          大多数 Python 用户 不会 想要直接使用这个包,而是使用 Python 包官方维护的跨版本工具。特别地, setuptools 是一个对于 distutils 的增强选项,它能提供:

          • 对声明项目依赖的支持
          • 额外的用于配置哪些文件包含在源代码发布中的机制(包括与版本控制系统集成需要的插件)
          • 生成项目“进入点”的能力,进入点可用作应用插件系统的基础
          • 自动在安装时间生成 Windows 命令行可执行文件的能力,而不是需要预编译它们
          • 跨所有受支持的 Python 版本上的一致的表现


          回溯中增强的错误位置

          打印回溯时,解释器现在将指向导致错误的确切表达式,而不仅仅是行。例如:

          Traceback (most recent call last):
          File "distance.py", line 11, in <module>
            print(manhattan_distance(p1, p2))
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^
          File "distance.py", line 6, in manhattan_distance
            return abs(point_1.x - point_2.x) + abs(point_1.y - point_2.y)
                                    ^^^^^^^^^
          AttributeError: 'NoneType' object has no attribute 'x'

          以前版本的解释器只会指向使对象不明确的那一行None。在处理深度嵌套的字典对象和多个函数调用时,这些增强的错误也很有帮助,

          Traceback (most recent call last):
          File "query.py", line 37, in <module>
            magic_arithmetic('foo')
            ^^^^^^^^^^^^^^^^^^^^^^^
          File "query.py", line 18, in magic_arithmetic
            return add_counts(x) / 25
                    ^^^^^^^^^^^^^
          File "query.py", line 24, in add_counts
            return 25 + query_user(user1) + query_user(user2)
                        ^^^^^^^^^^^^^^^^^
          File "query.py", line 32, in query_user
            return 1 + query_count(db, response['a']['b']['c']['user'], retry=True)
                                        ~~~~~~~~~~~~~~~~~~^^^^^
          TypeError: 'NoneType' object is not subscriptable

          以及复杂的算术表达式:

          Traceback (most recent call last):
          File "calculation.py", line 54, in <module>
            result = (x / y / z) * (a / b / c)
                      ~~~~~~^~~
          ZeroDivisionError: division by zero

          此功能需要将列位置存储在代码对象中,这可能会导致编译 Python 文件的磁盘使用量或解释器内存使用量略有增加。为了避免存储额外信息和/或停用打印额外回溯信息, 命令行标志或-X no_debug_rangesPYTHONNODEBUGRANGES 可以使用环境变量。

          代码对象的列信息

          增强回溯功能使用的信息作为通用 API 提供,可用于将字节码指令与源代码相关联。可以使用以下方法检索此信息:

          选项和环境变量 -X no_debug_rangesPYTHONNODEBUGRANGES可用于禁用此功能。

          PEP 657了解更多详情。(由 Pablo Galindo、Batuhan Taskaya 和 Ammar Askar 在bpo-43950中贡献。)

          异常可以用字符串丰富__note__

          该__note__字段已添加到BaseException. 默认情况None 下,但可以设置为添加到异常回溯的字符串。(由 Irit Katriel 在bpo-45607中贡献。)

          其他语言变化

          其他 CPython 实现更改

          • 特殊方法complex.__complex__()和bytes.__bytes__()实现支持typing.SupportsComplextyping.SupportsBytes协议。(由 Mark Dickinson 和 Dong-hee Na 在bpo-24234中贡献。)
          • siphash13被添加为新的内部散列算法。它具有类似的安全属性,siphash24但对于长输入来说它稍快一些。str,bytes和其他一些类型现在使用它作为hash().PEP 552 基于散列的 pyc 文件现在siphash13也使用 . (由 Inada Naoki 在bpo-29410中贡献。)
          • 当不带参数的语句重新引发活动异常时raise,附加到此异常的回溯现在始终为sys.exc_info()[1].__traceback__. 这意味着对当前except子句中的回溯所做的更改会反映在重新引发的异常中。(由 Irit Katriel 在bpo-45711中贡献。)
          • 解释器状态表示的已处理异常(又名 exc_info 或 _PyErr_StackItem)现在只有该exc_value字段,exc_type并且exc_traceback 已被删除,因为它们的值可以从exc_value. (由 Irit Katriel 在bpo-45711中贡献。)
          • 为 Windows 安装程序AppendPath添加了一个新的命令行选项。它的行为类似于PrependPath但附加了 install 和 scripts 目录,而不是前面。(由 Bastian Neuburger 在bpo-44934中贡献。)

          新模块

          改进的模块

          fractions

          • 支持PEP 515Fraction -从字符串初始化(由 Sergey B Kirpichev 在bpo-44258中贡献。)
          • Fraction现在实现一个__int__方法,以便检查通过。(由 Mark Dickinson 在bpo-44547中贡献。)isinstance(some_fraction, typing.SupportsInt)

          空闲和空闲库

          • 对.pyi文件应用语法高亮。(由 Alex Waygood 和 Terry Jan Reedy 在bpo-45447中贡献。)

          inspect

          math

          • math.exp2():返回 2 的 x 次方。(由 Gideon Mitchell 在bpo-45917中贡献。)
          • 添加math.cbrt():返回 x 的立方根。(由 Ajith Ramachandran 在bpo-44357中贡献。)
          • math.pow()为了与 IEEE 754 规范保持一致,更改了两个极端情况的行为。操作 ,现在返回 。以前他们提出了. (由 Mark Dickinson 在bpo-44339中贡献。)math.pow(0.0, -math.inf)``math.pow(-0.0, -math.inf)``inf ValueError

          operator

          • 添加了一个新功能operator.call,例如 . (由 Antony Lee 在bpo-44019中贡献。)operator.call(obj, *args, **kwargs) == obj(*args, **kwargs)

          os

          • 在 Windows 上,os.urandom()现在使用BCryptGenRandom(),而不是CryptGenRandom()已弃用。(由 Dong-hee Na 在bpo-44611中提供。)

          socket

          • 添加对 NetBSD 的 CAN Socket 支持。(由 Thomas Klausner 在bpo-30512中贡献。)

          sqlite3

          sys

          • sys.exc_info()现在从(异常实例)派生typeandtraceback字段value,因此当异常在处理过程中被修改时,更改会反映在对 . 的后续调用的结果中exc_info()。(由 Irit Katriel 在bpo-45711中贡献。)
          • 添加sys.exception()返回活动异常实例(相当于sys.exc_info()[1])。(由 Irit Katriel 在bpo-46328中贡献。)

          threading

          time

          • 在 Unix 上,time.sleep()现在使用clock_nanosleep()or nanosleep()函数(如果可用),其分辨率为 1 纳秒(10 -9秒),而不是使用select()其分辨率为 1 微秒(10 -6秒)。(由 Benjamin Szőke 和 Victor Stinner 在bpo-21302中贡献。)
          • 在 Windows 8.1 和更新版本上,time.sleep()现在使用基于高分辨率计时器的可等待计时器 ,其分辨率为 100 纳秒(10 -7秒)。以前,它的分辨率为 1 毫秒(10 -3秒)。(由 Benjamin Szőke、Dong-hee Na、Eryk Sun 和 Victor Stinner 在bpo-21302bpo-45429 中贡献。)

          unicodedata

          • Unicode 数据库已更新至版本 14.0.0。( bpo-45190 )。

          fcntl

          • 在 FreeBSD 上,F_DUP2FD和F_DUP2FD_CLOEXECflags 分别被支持,前者相当于dup2使用,后者FD_CLOEXEC额外设置了 flag。

          Optimizations

          • 编译器现在使用仅包含格式代码的文字格式优化简单的 C 样式格式%s,%r并%a使其与相应的 f 字符串表达式一样快。(由 Serhiy Storchaka 在bpo-28307中贡献。)
          • 实施“零成本”例外。try当不引发异常时,语句的成本几乎可以消除。(由 Mark Shannon 在bpo-40222中贡献。)
          • 由于避免创建绑定方法实例的字节码更改,现在使用关键字的方法调用更快。以前,此优化仅适用于具有纯位置参数的方法调用。(由 Ken Jin 和 Mark Shannon 在bpo-26110中贡献,基于 PyPy 中实现的想法。)
          • 纯 ASCII 字符串现在在常数时间内通过unicodedata.normalize(). (由 Dong-hee Na 在bpo-44987中提供。)
          • math函数comb()perm()现在对于大参数来说速度提高了 10 倍或更多(对于较大的k速度更快)。(由 Serhiy Storchaka 在bpo-37295中贡献。)
          • 当所有插入的键都是 Unicode 对象时,字典不存储哈希值。这减少了字典大小。例如,sys.getsizeof(dict.fromkeys("abcdefg")) 在 64 位平台上从 352 字节变为 272 字节。(由 Inada Naoki 在bpo-46845中贡献。)

          CPython 字节码更改

          • 用单个 实现替换了所有数字BINARY_*和指令。INPLACE_*BINARY_OP
          • 将三个调用指令:CALL_FUNCTION和 CALL_FUNCTION_KW替换CALL_METHOD为 PUSH_NULLPRECALLCALL KW_NAMES。这将方法的参数转移与关键字参数的处理分离,并允许更好地专门化调用。
          • 删除COPY_DICT_WITHOUT_KEYS和GEN_START。
          • MATCH_CLASS并且MATCH_KEYS不再推送一个额外的布尔值来指示匹配是成功还是失败。相反,它们指示失败 None (否则提取值的元组会出现)。
          • 用 new 和指令替换几个堆栈操作指令(DUP_TOP、DUP_TOP_TWO、 ROT_TWO、ROT_THREE、ROT_FOUR和) 。ROT_NCOPY SWAP
          • 添加POP_JUMP_IF_NOT_NONEPOP_JUMP_IF_NONE操作码以加速条件跳转。
          • JUMP_IF_NOT_EXC_MATCH不再弹出活动异常。

          Deprecated

          Removed

          • smtpd.MailmanProxy现在已删除,因为没有外部模块就无法使用mailman. (由 Dong-hee Na 在bpo-35800中提供。)
          • 该binhex模块在 Python 3.9 中已弃用,现在已删除。在 Python 3.9 中不推荐使用的以下binascii函数现在也被删除:a2b_hqx(), b2a_hqx();rlecode_hqx(), rledecode_hqx().该binascii.crc_hqx()功能仍然可用。(由 Victor Stinner 在bpo-45085中贡献。)
          • bdist_msi在 Python 3.9 中不推荐使用的 distutils命令现在已被删除。改用bdist_wheel(车轮包)。(由 Hugo van Kemenade 在bpo-45124中贡献。)
          • 由于重大的安全问题, Python 3.9 中禁用的 的reuse_address参数 asyncio.loop.create_datagram_endpoint()现在已完全删除。这是因为 SO_REUSEADDRUDP 中套接字选项的行为。(由 Hugo van Kemenade 在bpo-45129中贡献。)
          • 自Python 3.9 起已不推荐使用和 的__getitem__()方法 。(由 Hugo van Kemenade 在bpo-45132中贡献。)xml.dom.pulldom.DOMEventStreamwsgiref.util.FileWrapperfileinput.FileInput
          • gettext 模块中删除了以下不推荐使用的函数和方法:lgettext()、ldgettext()和 。lngettext()``ldngettext()Function bind_textdomain_codeset()、 methods output_charset()和 set_output_charset()以及函数的codeset 参数translation()and install() 也被删除,因为它们仅用于l*gettext()函数。(由 Dong-hee Na 和 Serhiy Storchaka 在bpo-44235中贡献。)
          • 使基于生成器的旧协程与 async/await 代码兼容的@asyncio.coroutine 装饰器。该函数自 Python 3.8 起已被弃用,最初计划在 Python 3.10 中删除。改为使用。(由 Illia Volochii 在bpo-43216中贡献。) async def
          • asyncio.coroutines.CoroWrapper用于在调试模式下包装遗留的基于生成器的协程对象。(由 Illia Volochii 在bpo-43216中贡献。)
          • 删除了已弃用split()的_tkinter.TkappType. (由 Erlend E. Aasland 在bpo-38371中贡献。)
          • inspect模块中删除:该getargspec函数,自 Python 3.0 起已弃用;使用inspect.signature()orinspect.getfullargspec()代替。该formatargspec函数,自 Python 3.5 起已弃用;直接使用inspect.signature()函数和Signature对象。自 Python 3.5 起已弃用的未记录Signature.from_builtin和Signature.from_function 函数;改用该 Signature.from_callable()方法。(由 Hugo van Kemenade 在bpo-45320中贡献。)
          • 从 unittest 发现中删除命名空间包支持。它是在 Python 3.4 中引入的,但自 Python 3.7 以来已被破坏。(由 Inada Naoki 在bpo-23882中贡献。)
          • 从 中删除__class_getitem__方法pathlib.PurePath,因为在以前的版本中没有使用和错误添加。(由 Nikita Sobolev 在bpo-46483中贡献。)
          • 删除未记录的私有方法,以前在 Python 3.7 中float.__set_format__()称为。float.__setformat__()它的文档字符串说:“你可能不想使用这个函数。它的存在主要是为了在 Python 的测试套件中使用。” (由 Victor Stinner 在bpo-46852中贡献。)

          移植到 Python 3.11

          本节列出了之前描述的更改和其他可能需要更改代码的错误修正。

          Python API 的变化

          构建更改

          • 构建 Python 现在需要一个没有可选 C11 功能的 C11 编译器。(由 Victor Stinner 在bpo-46656中贡献。)
          • 现在可以使用 ThinLTO 选项通过--with-lto=thin. (由 Dong-hee Na 和 Brett Holman 在bpo-44340中贡献。)
          • libpython 不再与 libcrypt 链接。(由 Mike Gilbert 在bpo-45433中贡献。)
          • 构建 Python 现在需要一个<math.h>提供以下函数的 C99 头文件:copysign(), hypot(), isfinite(), isinf(), isnan(), round(). (由 Victor Stinner 在bpo-45440中贡献。)
          • 构建 Python 现在需要一个<math.h>提供NAN常量或__builtin_nan()内置函数的 C99 头文件。(由 Victor Stinner 在bpo-46640中贡献。)
          • 构建 Python 现在需要支持浮点非数字 (NaN):删除Py_NO_NAN宏。(由 Victor Stinner 在bpo-46656中贡献。)
          • 现在可以禁用对象结构的空闲列表。一个新的配置 选项--without-freelists可用于禁用除空元组单例之外的所有空闲列表。(由 Christian Heimes 在bpo-45522中贡献)
          • Modules/Setup并Modules/makesetup进行了改进和捆绑。扩展模块现在可以通过makesetup. 除了一些测试模块之外的所有模块都可以静态链接到主二进制文件或库中。(由 Brett Cannon 和 Christian Heimes 在bpo-45548bpo-45570bpo-45571bpo-43974 中贡献。)
          • configure现在可以检测大多数 stdlib 扩展模块的构建依赖项、编译器标志和链接器标志。libffi、libnsl、libsqlite3、zlib、bzip2、liblzma、libcrypt 和 uuid 标志由 pkg-config(如果可用)检测。(由 Christian Heimes 和 Erlend Egeberg Aasland 在 bpo-bpo-45847bpo-45747bpo-45763 中贡献。)
          • CPython 现在有对交叉编译到 WebAssembly 平台的实验性支持wasm32-emscripten。这项工作受到了 Pyodide 等先前工作的启发。(由 Christian Heimes 和 Ethan Smith 在bpo-40280中贡献。)
          • CPython 现在将默认使用 30 位数字来int 实现 Python。以前,默认是在带有 的平台上使用 30 位数字,否则使用 15 位数字。仍然可以通过配置脚本的选项或(对于 Windows)中的 变量显式请求使用 15 位数字 ,但将来可能会删除此选项。(由 Mark Dickinson 在 bpo-45569中贡献。)SIZEOF_VOID_P >= 8``--enable-big-digits``PYLONG_BITS_IN_DIGIT``PC/pyconfig.h

          C API

          • PyErr_SetExcInfo()不再使用typeand参数,解释器现在从异常实例(参数)traceback 派生这些值。value该函数仍然窃取所有三个参数的引用。(由 Irit Katriel 在 bpo-45711中贡献。)
          • PyErr_GetExcInfo()现在 从异常实例(字段)派生结果的type和字段。(由 Irit Katriel 在bpo-45711中贡献。)traceback``value
          • _frozen有一个新is_package字段来指示冻结的模块是否是一个包。以前,该字段中的负值size是指标。现在只有非负值用于size. (由 Kumar Aditya 在bpo-46608中贡献。)

          新功能



            在 Python3 中正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。

            Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式。

            re 模块使 Python 语言拥有全部的正则表达式功能。

            compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。

            re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数。

            本章节主要介绍 Python 中常用的正则表达式处理函数。


            re.match 函数

            re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match() 就返回 none。

            函数语法

            re.match(pattern, string, flags=0)

            函数参数说明:

            参数描述
            pattern匹配的正则表达式
            string要匹配的字符串。
            flags标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

            匹配成功 re.match 方法返回一个匹配的对象,否则返回 None。

            我们可以使用 group(num) 或 groups() 匹配对象函数来获取匹配表达式。

            匹配对象方法描述
            group(num=0)匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。
            groups()返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。

            实例 1:

            #!/usr/bin/pythonimport reprint(re.match('www', 'www.51coolma.cn').span())  # 在起始位置匹配print(re.match('cn', 'www.51coolma.cn'))         # 不在起始位置匹配

            以上实例运行输出结果为:

            (0, 3)None

            实例 2:

            #!/usr/bin/python3import reline = "Cats are smarter than dogs"matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I)if matchObj:    print ("matchObj.group() : ", matchObj.group())    print ("matchObj.group(1) : ", matchObj.group(1))    print ("matchObj.group(2) : ", matchObj.group(2))else:    print ("No match!!")

            以上实例执行结果如下:

            matchObj.group() :  Cats are smarter than dogsmatchObj.group(1) :  CatsmatchObj.group(2) :  smarter

            re.search 方法

            re.search 扫描整个字符串并返回第一个成功的匹配。

            函数语法:

            re.search(pattern, string, flags=0)

            函数参数说明:

            参数描述
            pattern匹配的正则表达式
            string要匹配的字符串。
            flags标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

            匹配成功 re.search 方法返回一个匹配的对象,否则返回 None。

            我们可以使用 group(num) 或 groups() 匹配对象函数来获取匹配表达式。

            匹配对象方法描述
            group(num=0)匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。
            groups()返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。

            实例 1:

            #!/usr/bin/python3import reprint(re.search('www', 'www.51coolma.cn').span())  # 在起始位置匹配print(re.search('cn', 'www.51coolma.cn').span())         # 不在起始位置匹配

            以上实例运行输出结果为:

            (0, 3)(14, 16)

            实例 2:

            #!/usr/bin/python3import reline = "Cats are smarter than dogs";searchObj = re.search( r'(.*) are (.*?) .*', line, re.M|re.I)if searchObj:    print ("searchObj.group() : ", searchObj.group())    print ("searchObj.group(1) : ", searchObj.group(1))    print ("searchObj.group(2) : ", searchObj.group(2))else:    print ("Nothing found!!")

            以上实例执行结果如下:

            searchObj.group() :  Cats are smarter than dogssearchObj.group(1) :  CatssearchObj.group(2) :  smarter

            re.match 与 re.search 的区别

            re.match 只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回 None;而 re.search 匹配整个字符串,直到找到一个匹配。

            实例:

            #!/usr/bin/python3import reline = "Cats are smarter than dogs";matchObj = re.match( r'dogs', line, re.M|re.I)if matchObj:    print ("match --> matchObj.group() : ", matchObj.group())else:    print ("No match!!")matchObj = re.search( r'dogs', line, re.M|re.I)if matchObj:    print ("search --> matchObj.group() : ", matchObj.group())else:    print ("No match!!")

            以上实例运行结果如下:

            No match!!search --> matchObj.group() :  dogs

            检索和替换

            Python 的 re 模块提供了 re.sub 用于替换字符串中的匹配项。

            语法:

            re.sub(pattern, repl, string, max=0)

            返回的字符串是在字符串中用 re 最左边不重复的匹配来替换。如果模式没有发现,字符将被没有改变地返回。

            可选参数 count 是模式匹配后替换的最大次数;count 必须是非负整数。缺省值是 0 表示替换所有的匹配。

            实例:

            #!/usr/bin/python3import rephone = "2004-959-559 # 这是一个电话号码"# 删除注释num = re.sub(r'#.*$', "", phone)print ("电话号码 : ", num)# 移除非数字的内容num = re.sub(r'D', "", phone)print ("电话号码 : ", num)

            以上实例执行结果如下:

            电话号码 :  2004-959-559 电话号码 :  2004959559

            正则表达式修饰符 - 可选标志

            正则表达式可以包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标志。多个标志可以通过按位 or(|) 它们来指定。如 re.L | re.M 被设置成 L 和 M 标志:

            修饰符描述
            re.I使匹配对大小写不敏感
            re.L做本地化识别(locale-aware)匹配
            re.M多行匹配,影响 ^ 和 $
            re.S使 . 匹配包括换行在内的所有字符
            re.U根据Unicode字符集解析字符。这个标志影响 w, W, , B.
            re.X该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。

            正则表达式模式

            模式字符串使用特殊的语法来表示一个正则表达式:

            字母和数字表示他们自身。一个正则表达式模式中的字母和数字匹配同样的字符串。

            多数字母和数字前加一个反斜杠时会拥有不同的含义。

            标点符号只有被转义时才匹配自身,否则它们表示特殊的含义。

            反斜杠本身需要使用反斜杠转义。

            由于正则表达式通常都包含反斜杠,所以你最好使用原始字符串来表示它们。模式元素(如 r'/t',等价于'//t')匹配相应的特殊字符。

            下表列出了正则表达式模式语法中的特殊元素。如果你使用模式的同时提供了可选的标志参数,某些模式元素的含义会改变。

            模式描述
            ^匹配字符串的开头
            $匹配字符串的末尾。
            .匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。
            [...]用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k'
            [^...]不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。
            re*匹配0个或多个的表达式。
            re+匹配1个或多个的表达式。
            re?匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式
            re{ n}匹配n个前面表达式。例如,"o{2}"不能匹配"Bob"中的"o",但是能匹配"food"中的两个o。
            re{ n,}精确匹配n个前面表达式。例如,"o{2,}"不能匹配"Bob"中的"o",但能匹配"foooood"中的所有o。"o{1,}"等价于"o+"。"o{0,}"则等价于"o*"。
            re{ n, m}匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式
            a| b匹配a或b
            (re)G匹配括号内的表达式,也表示一个组
            (?imx)正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。
            (?-imx)正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。
            (?: re)类似 (...), 但是不表示一个组
            (?imx: re)在括号中使用i, m, 或 x 可选标志
            (?-imx: re)在括号中不使用i, m, 或 x 可选标志
            (?#...)注释.
            (?= re)前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。
            (?! re)前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功
            (?> re)匹配的独立模式,省去回溯。
            w匹配字母数字
            W匹配非字母数字
            s匹配任意空白字符,等价于 [ f].
            S匹配任意非空字符
            d匹配任意数字,等价于 [0-9].
            D匹配任意非数字
            A匹配字符串开始
            匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。c
            z匹配字符串结束
            G匹配最后匹配完成的位置。
            匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
            B匹配非单词边界。'erB' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
            , , 等.匹配一个换行符。匹配一个制表符。等
            1...9匹配第n个分组的子表达式。
            10匹配第n个分组的子表达式,如果它经匹配。否则指的是八进制字符码的表达式。

            正则表达式实例

            字符匹配

            实例描述
            python匹配 "python".

            字符类

            实例描述
            [Pp]ython匹配 "Python" 或 "python"
            rub[ye]匹配 "ruby" 或 "rube"
            [aeiou]匹配中括号内的任意一个字母
            [0-9]匹配任何数字。类似于 [0123456789]
            [a-z]匹配任何小写字母
            [A-Z]匹配任何大写字母
            [a-zA-Z0-9]匹配任何字母及数字
            [^aeiou]除了aeiou字母以外的所有字符
            [^0-9]匹配除了数字外的字符

            特殊字符类

            实例描述
            .匹配除 " " 之外的任何单个字符。要匹配包括 ' ' 在内的任何字符,请使用象 '[. ]' 的模式。
            d匹配一个数字字符。等价于 [0-9]。
            D匹配一个非数字字符。等价于 [^0-9]。
            s匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ f v]。
            S匹配任何非空白字符。等价于 [^ f v]。
            w匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。
            W匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。


            本文我们为大家介绍 Python3 使用 PyMySQL 连接数据库,并实现简单的增删改查。

            什么是 PyMySQL?

            PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库,Python2 中则使用mysqldb。

            PyMySQL 遵循 Python 数据库 API v2.0 规范,并包含了 pure-Python MySQL 客户端库。


            PyMySQL 安装

            在使用 PyMySQL 之前,我们需要确保 PyMySQL 已安装。

            PyMySQL 下载地址:https://github.com/PyMySQL/PyMySQL。

            如果还未安装,我们可以使用以下命令安装最新版的 PyMySQL:

            $ pip install PyMySQL

            如果你的系统不支持 pip 命令,可以使用以下方式安装:

            1、使用 git 命令下载安装包安装(你也可以手动下载):

            $ git clone https://github.com/PyMySQL/PyMySQL$ cd PyMySQL/$ python3 setup.py install

            2、如果需要制定版本号,可以使用 curl 命令来安装:

            $ # X.X 为 PyMySQL 的版本号$ curl -L https://github.com/PyMySQL/PyMySQL/tarball/pymysql-X.X | tar xz$ cd PyMySQL*$ python3 setup.py install$ # 现在你可以删除 PyMySQL* 目录

            注意:请确保您有 root 权限来安装上述模块。

            安装的过程中可能会出现"ImportError: No module named setuptools"的错误提示,意思是你没有安装setuptools,你可以访问https://pypi.python.org/pypi/setuptools 找到各个系统的安装方法。

            Linux 系统安装实例:

            $ wget https://bootstrap.pypa.io/ez_setup.py$ python3 ez_setup.py

            数据库连接

            连接数据库前,请先确认以下事项:

            • 您已经创建了数据库 TESTDB.
            • 在 TESTDB 数据库中您已经创建了表 EMPLOYEE
            • EMPLOYEE 表字段为 FIRST_NAME, LAST_NAME, AGE, SEX 和 INCOME。
            • 连接数据库 TESTDB 使用的用户名为 "testuser" ,密码为 "test123",你可以可以自己设定或者直接使用 root 用户名及其密码,Mysql 数据库用户授权请使用 Grant 命令。
            • 在你的机子上已经安装了 Python MySQLdb 模块。
            • 如果您对 sql 语句不熟悉,可以访问我们的 SQL教程

            实例:

            以下实例链接 Mysql 的 TESTDB 数据库:

            #!/usr/bin/python3import pymysql# 打开数据库连接db = pymysql.connect("localhost","testuser","test123","TESTDB" )# 使用 cursor() 方法创建一个游标对象 cursorcursor = db.cursor()# 使用 execute()  方法执行 SQL 查询 cursor.execute("SELECT VERSION()")# 使用 fetchone() 方法获取单条数据.data = cursor.fetchone()print ("Database version : %s " % data)# 关闭数据库连接db.close()

            执行以上脚本输出结果如下:

            Database version : 5.5.20-log

            创建数据库表

            如果数据库连接存在我们可以使用 execute() 方法来为数据库创建表,如下所示创建表EMPLOYEE:

            #!/usr/bin/python3import pymysql# 打开数据库连接db = pymysql.connect("localhost","testuser","test123","TESTDB" )# 使用 cursor() 方法创建一个游标对象 cursorcursor = db.cursor()# 使用 execute() 方法执行 SQL,如果表存在则删除cursor.execute("DROP TABLE IF EXISTS EMPLOYEE")# 使用预处理语句创建表sql = """CREATE TABLE EMPLOYEE (         FIRST_NAME  CHAR(20) NOT NULL,         LAST_NAME  CHAR(20),         AGE INT,           SEX CHAR(1),         INCOME FLOAT )"""cursor.execute(sql)# 关闭数据库连接db.close()

            数据库插入操作

            以下实例使用执行 SQL INSERT 语句向表 EMPLOYEE 插入记录:

            #!/usr/bin/python3import pymysql# 打开数据库连接db = pymysql.connect("localhost","testuser","test123","TESTDB" )# 使用cursor()方法获取操作游标 cursor = db.cursor()# SQL 插入语句sql = """INSERT INTO EMPLOYEE(FIRST_NAME,         LAST_NAME, AGE, SEX, INCOME)         VALUES ('Mac', 'Mohan', 20, 'M', 2000)"""try:   # 执行sql语句   cursor.execute(sql)   # 提交到数据库执行   db.commit()except:   # 如果发生错误则回滚   db.rollback()# 关闭数据库连接db.close()

            以上例子也可以写成如下形式:

            #!/usr/bin/python3import pymysql# 打开数据库连接db = pymysql.connect("localhost","testuser","test123","TESTDB" )# 使用cursor()方法获取操作游标 cursor = db.cursor()# SQL 插入语句sql = "INSERT INTO EMPLOYEE(FIRST_NAME,        LAST_NAME, AGE, SEX, INCOME)        VALUES ('%s', '%s', '%d', '%c', '%d' )" %        ('Mac', 'Mohan', 20, 'M', 2000)try:   # 执行sql语句   cursor.execute(sql)   # 执行sql语句   db.commit()except:   # 发生错误时回滚   db.rollback()# 关闭数据库连接db.close()

            以下代码使用变量向 SQL 语句中传递参数:

            ..................................user_id = "test123"password = "password"con.execute('insert into Login values("%s", "%s")' %              (user_id, password))..................................

            数据库查询操作

            Python 查询 Mysql 使用 fetchone() 方法获取单条数据, 使用 fetchall() 方法获取多条数据。

            • fetchone(): 该方法获取下一个查询结果集。结果集是一个对象
            • fetchall(): 接收全部的返回结果行.
            • rowcount: 这是一个只读属性,并返回执行 execute() 方法后影响的行数。

            实例:

            查询 EMPLOYEE 表中 salary(工资)字段大于 1000 的所有数据:

            #!/usr/bin/python3import pymysql# 打开数据库连接db = pymysql.connect("localhost","testuser","test123","TESTDB" )# 使用cursor()方法获取操作游标 cursor = db.cursor()# SQL 查询语句sql = "SELECT * FROM EMPLOYEE        WHERE INCOME > '%d'" % (1000)try:   # 执行SQL语句   cursor.execute(sql)   # 获取所有记录列表   results = cursor.fetchall()   for row in results:      fname = row[0]      lname = row[1]      age = row[2]      sex = row[3]      income = row[4]       # 打印结果      print ("fname=%s,lname=%s,age=%d,sex=%s,income=%d" %              (fname, lname, age, sex, income ))except:   print ("Error: unable to fecth data")# 关闭数据库连接db.close()

            以上脚本执行结果如下:

            fname=Mac, lname=Mohan, age=20, sex=M, income=2000

            数据库更新操作

            更新操作用于更新数据表的的数据,以下实例将 TESTDB 表中的 SEX 字段全部修改为 'M',AGE 字段递增 1:

            #!/usr/bin/python3import pymysql# 打开数据库连接db = pymysql.connect("localhost","testuser","test123","TESTDB" )# 使用cursor()方法获取操作游标 cursor = db.cursor()# SQL 更新语句sql = "UPDATE EMPLOYEE SET AGE = AGE + 1                          WHERE SEX = '%c'" % ('M')try:   # 执行SQL语句   cursor.execute(sql)   # 提交到数据库执行   db.commit()except:   # 发生错误时回滚   db.rollback()# 关闭数据库连接db.close()

            删除操作

            删除操作用于删除数据表中的数据,以下实例演示了删除数据表 EMPLOYEE 中 AGE 大于 20 的所有数据:

            #!/usr/bin/python3import pymysql# 打开数据库连接db = pymysql.connect("localhost","testuser","test123","TESTDB" )# 使用cursor()方法获取操作游标 cursor = db.cursor()# SQL 删除语句sql = "DELETE FROM EMPLOYEE WHERE AGE > '%d'" % (20)try:   # 执行SQL语句   cursor.execute(sql)   # 提交修改   db.commit()except:   # 发生错误时回滚   db.rollback()# 关闭连接db.close()

            执行事务

            事务机制可以确保数据一致性。

            事务应该具有 4 个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为 ACID 特性。

            • 原子性(atomicity)。一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。
            • 一致性(consistency)。事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
            • 隔离性(isolation)。一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
            • 持久性(durability)。持续性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

            Python DB API 2.0 的事务提供了两个方法 commit 或 rollback。

            实例

            # SQL删除记录语句sql = "DELETE FROM EMPLOYEE WHERE AGE > '%d'" % (20)try:   # 执行SQL语句   cursor.execute(sql)   # 向数据库提交   db.commit()except:   # 发生错误时回滚   db.rollback()

            对于支持事务的数据库, 在 Python 数据库编程中,当游标建立之时,就自动开始了一个隐形的数据库事务。

            commit() 方法游标的所有更新操作,rollback()方法回滚当前游标的所有操作。每一个方法都开始了一个新的事务。


            错误处理

            DB API 中定义了一些数据库操作的错误及异常,下表列出了这些错误和异常:

            异常描述
            Warning当有严重警告时触发,例如插入数据是被截断等等。必须是 StandardError 的子类。
            Error警告以外所有其他错误类。必须是 StandardError 的子类。
            InterfaceError当有数据库接口模块本身的错误(而不是数据库的错误)发生时触发。 必须是 Error 的子类。
            DatabaseError和数据库有关的错误发生时触发。 必须是 Error 的子类。
            DataError当有数据处理时的错误发生时触发,例如:除零错误,数据超范围等等。 必须是 DatabaseError 的子类。
            OperationalError指非用户控制的,而是操作数据库时发生的错误。例如:连接意外断开、 数据库名未找到、事务处理失败、内存分配错误等等操作数据库是发生的错误。 必须是 DatabaseError 的子类。
            IntegrityError完整性相关的错误,例如外键检查失败等。必须是 DatabaseError 子类。
            InternalError数据库的内部错误,例如游标(cursor)失效了、事务同步失败等等。 必须是 DatabaseError 子类。
            ProgrammingError程序错误,例如数据表(table)没找到或已存在、SQL 语句语法错误、 参数数量错误等等。必须是 DatabaseError 的子类。
            NotSupportedError不支持错误,指使用了数据库不支持的函数或API等。例如在连接对象上 使用 .rollback() 函数,然而数据库并不支持事务或者事务已关闭。 必须是 DatabaseError 的子类。


            Python 提供了两个级别访问的网络服务。:

            • 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统 Socket 接口的全部方法。
            • 高级别的网络服务模块 SocketServer, 它提供了服务器中心类,可以简化网络服务器的开发。

            什么是 Socket?

            Socket 又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。


            socket()函数

            Python 中,我们用 socket()函数来创建套接字,语法格式如下:

            socket.socket([family[, type[, proto]]])

            参数

            • family: 套接字家族可以使 AF_UNIX 或者 AF_INET
            • type: 套接字类型可以根据是面向连接的还是非连接分为SOCK_STREAMSOCK_DGRAM
            • protocol: 一般不填默认为0.

            Socket 对象(内建)方法

            函数描述
            服务器端套接字
            s.bind()绑定地址(host,port)到套接字, 在 AF_INET 下,以元组(host,port)的形式表示地址。
            s.listen()开始 TCP 监听。backlog 指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为 1,大部分应用程序设为 5 就可以了。
            s.accept()被动接受 TCP 客户端连接,(阻塞式)等待连接的到来
            客户端套接字
            s.connect()主动初始化 TCP 服务器连接,。一般 address 的格式为元组(hostname,port),如果连接出错,返回 socket.error 错误。
            s.connect_ex()connect() 函数的扩展版本,出错时返回出错码,而不是抛出异常
            公共用途的套接字函数
            s.recv()接收 TCP 数据,数据以字符串形式返回,bufsize指定要接收的最大数据量。flag 提供有关消息的其他信息,通常可以忽略。
            s.send()发送 TCP 数据,将 string 中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于 string 的字节大小。
            s.sendall()完整发送 TCP 数据,完整发送 TCP 数据。将 string 中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回 None,失败则抛出异常。
            s.recvfrom()接收 UDP 数据,与 recv() 类似,但返回值是(data,address)。其中 data 是包含接收数据的字符串,address 是发送数据的套接字地址。
            s.sendto()发送 UDP 数据,将数据发送到套接字,address 是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。
            s.close()关闭套接字
            s.getpeername()返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。
            s.getsockname()返回套接字自己的地址。通常是一个元组(ipaddr,port)
            s.setsockopt(level,optname,value)设置给定套接字选项的值。
            s.getsockopt(level,optname[.buflen])返回套接字选项的值。
            s.settimeout(timeout)设置套接字操作的超时期,timeout 是一个浮点数,单位是秒。值为 None 表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如 connect())
            s.gettimeout()返回当前超时期的值,单位是秒,如果没有设置超时期,则返回 None。
            s.fileno()返回套接字的文件描述符。
            s.setblocking(flag)如果 flag 为 0,则将套接字设为非阻塞模式,否则将套接字设为阻塞模式(默认值)。非阻塞模式下,如果调用 recv() 没有发现任何数据,或 send() 调用无法立即发送数据,那么将引起 socket.error 异常。
            s.makefile()创建一个与该套接字相关连的文件

            简单实例

            服务端

            我们使用 socket 模块的 socket 函数来创建一个 socket 对象。socket 对象可以通过调用其他函数来设置一个 socket 服务。

            现在我们可以通过调用 bind(hostname, port) 函数来指定服务的 port(端口)

            接着,我们调用 socket 对象的 accept 方法。该方法等待客户端的连接,并返回 connection 对象,表示已连接到客户端。

            完整代码如下:

            #!/usr/bin/python3# 文件名:server.py# 导入 socket、sys 模块import socketimport sys# 创建 socket 对象serversocket = socket.socket(            socket.AF_INET, socket.SOCK_STREAM) # 获取本地主机名host = socket.gethostname()port = 9999# 绑定端口serversocket.bind((host, port))# 设置最大连接数,超过后排队serversocket.listen(5)while True:    # 建立客户端连接    clientsocket,addr = serversocket.accept()          print("连接地址: %s" % str(addr))        msg='欢迎访问W3Cschool教程!'+ "
            "    clientsocket.send(msg.encode('utf-8'))    clientsocket.close()

            客户端

            接下来我们写一个简单的客户端实例连接到以上创建的服务。端口号为 12345。

            socket.connect(hosname, port ) 方法打开一个 TCP 连接到主机为 hostname 端口为 port 的服务商。连接后我们就可以从服务端后期数据,记住,操作完成后需要关闭连接。

            完整代码如下:

            #!/usr/bin/python3# 文件名:client.py# 导入 socket、sys 模块import socketimport sys# 创建 socket 对象s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 获取本地主机名host = socket.gethostname() # 设置端口好port = 9999# 连接服务,指定主机和端口s.connect((host, port))# 接收小于 1024 字节的数据msg = s.recv(1024)s.close()print (msg.decode('utf-8'))

            现在我们打开连个终端,第一个终端执行 server.py 文件:

            $ python3 server.py

            第二个终端执行 client.py 文件:

            $ python3 client.py 欢迎访问W3Cschool教程!

            这是我们再打开第一个终端,就会看到有以下信息输出:

            连接地址: ('192.168.0.118', 33397)

            Python Internet 模块

            以下列出了 Python 网络编程的一些重要模块:

            协议功能用处端口号Python 模块
            HTTP网页访问80httplib, urllib, xmlrpclib
            NNTP阅读和张贴新闻文章,俗称为"帖子"119nntplib
            FTP文件传输20ftplib, urllib
            SMTP发送邮件25smtplib
            POP3接收邮件110poplib
            IMAP4获取邮件143imaplib
            Telnet命令行23telnetlib
            Gopher信息查找70gopherlib, urllib

            更多内容可以参阅官网的 Python Socket Library and Modules

            在Python3 中应用的SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。

            python的 smtplib 提供了一种很方便的途径发送电子邮件。它对 smtp 协议进行了简单的封装。

            Python创建 SMTP 对象语法如下:

            import smtplibsmtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] )

            参数说明:

            • host: SMTP 服务器主机。 你可以指定主机的 ip 地址或者域名如:51coolma.cn,这个是可选参数。
            • port: 如果你提供了 host 参数, 你需要指定 SMTP 服务使用的端口号,一般情况下 SMTP 端口号为 25。
            • local_hostname: 如果 SMTP 在你的本机上,你只需要指定服务器地址为 localhost 即可。

            Python SMTP 对象使用 sendmail 方法发送邮件,语法如下:

            SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options]

            参数说明:

            • from_addr: 邮件发送者地址。
            • to_addrs: 字符串列表,邮件发送地址。
            • msg: 发送消息

            这里要注意一下第三个参数,msg 是字符串,表示邮件。我们知道邮件一般由标题,发信人,收件人,邮件内容,附件等构成,发送邮件的时候,要注意 msg 的格式。这个格式就是 smtp 协议中定义的格式。

            实例

            以下是一个使用 Python 发送邮件简单的实例:

            #!/usr/bin/python3import smtplibfrom email.mime.text import MIMETextfrom email.header import Headersender = 'from@51coolma.cn'receivers = ['429240967@qq.com']  # 接收邮件,可设置为你的QQ邮箱或者其他邮箱# 三个参数:第一个为文本内容,第二个 plain 设置文本格式,第三个 utf-8 设置编码message = MIMEText('Python 邮件发送测试...', 'plain', 'utf-8')message['From'] = Header("W3Cschool教程", 'utf-8')message['To'] =  Header("测试", 'utf-8')subject = 'Python SMTP 邮件测试'message['Subject'] = Header(subject, 'utf-8')try:    smtpObj = smtplib.SMTP('localhost')    smtpObj.sendmail(sender, receivers, message.as_string())    print ("邮件发送成功")except smtplib.SMTPException:    print ("Error: 无法发送邮件")

            我们使用三个引号来设置邮件信息,标准邮件需要三个头部信息: From, To, 和 Subject ,每个信息直接使用空行分割。

            我们通过实例化 smtplib 模块的 SMTP 对象 smtpObj 来连接到 SMTP 访问,并使用 sendmail 方法来发送信息。

            执行以上程序,如果你本机安装 sendmail,就会输出:

            $ python3 test.py 邮件发送成功

            查看我们的收件箱(一般在垃圾箱),就可以查看到邮件信息:

            运行结果

            如果我们本机没有 sendmail 访问,也可以使用其他服务商的 SMTP 访问(QQ、网易、Google等)。

            #!/usr/bin/python3import smtplibfrom email.mime.text import MIMETextfrom email.header import Header# 第三方 SMTP 服务mail_host="smtp.XXX.com"  #设置服务器mail_user="XXXX"    #用户名mail_pass="XXXXXX"   #口令 sender = 'from@51coolma.cn'receivers = ['429240967@qq.com']  # 接收邮件,可设置为你的QQ邮箱或者其他邮箱message = MIMEText('Python 邮件发送测试...', 'plain', 'utf-8')message['From'] = Header("W3Cschool教程", 'utf-8')message['To'] =  Header("测试", 'utf-8')subject = 'Python SMTP 邮件测试'message['Subject'] = Header(subject, 'utf-8')try:    smtpObj = smtplib.SMTP()     smtpObj.connect(mail_host, 25)    # 25 为 SMTP 端口号    smtpObj.login(mail_user,mail_pass)    smtpObj.sendmail(sender, receivers, message.as_string())    print ("邮件发送成功")except smtplib.SMTPException:    print ("Error: 无法发送邮件")

            使用Python发送HTML格式的邮件

            Python 发送 HTML 格式的邮件与发送纯文本消息的邮件不同之处就是将 MIMEText 中 _subtype 设置为 html。具体代码如下:

            #!/usr/bin/python3import smtplibfrom email.mime.text import MIMETextfrom email.header import Headersender = 'from@51coolma.cn'receivers = ['429240967@qq.com']  # 接收邮件,可设置为你的QQ邮箱或者其他邮箱mail_msg = """<p>Python 邮件发送测试...</p><p><a href="http://www.51coolma.cn">这是一个链接</a></p>"""message = MIMEText(mail_msg, 'html', 'utf-8')message['From'] = Header("W3Cschool教程", 'utf-8')message['To'] =  Header("测试", 'utf-8')subject = 'Python SMTP 邮件测试'message['Subject'] = Header(subject, 'utf-8')try:    smtpObj = smtplib.SMTP('localhost')    smtpObj.sendmail(sender, receivers, message.as_string())    print ("邮件发送成功")except smtplib.SMTPException:    print ("Error: 无法发送邮件")

            执行以上程序,如果你本机安装 sendmail,就会输出:

            $ python3 test.py 邮件发送成功

            查看我们的收件箱(一般在垃圾箱),就可以查看到邮件信息:

            运行结果


            Python 发送带附件的邮件

            发送带附件的邮件,首先要创建 MIMEMultipart() 实例,然后构造附件,如果有多个附件,可依次构造,最后利用 smtplib.smtp 发送。

            #!/usr/bin/python3import smtplibfrom email.mime.text import MIMETextfrom email.mime.multipart import MIMEMultipartfrom email.header import Headersender = 'from@51coolma.cn'receivers = ['429240967@qq.com']  # 接收邮件,可设置为你的QQ邮箱或者其他邮箱#创建一个带附件的实例message = MIMEMultipart()message['From'] = Header("W3Cschool教程", 'utf-8')message['To'] =  Header("测试", 'utf-8')subject = 'Python SMTP 邮件测试'message['Subject'] = Header(subject, 'utf-8')#邮件正文内容message.attach(MIMEText('这是W3Cschool教程Python 邮件发送测试……', 'plain', 'utf-8'))# 构造附件1,传送当前目录下的 test.txt 文件att1 = MIMEText(open('test.txt', 'rb').read(), 'base64', 'utf-8')att1["Content-Type"] = 'application/octet-stream'# 这里的filename可以任意写,写什么名字,邮件中显示什么名字att1["Content-Disposition"] = 'attachment; filename="test.txt"'message.attach(att1)# 构造附件2,传送当前目录下的 51coolma.txt 文件att2 = MIMEText(open('51coolma.txt', 'rb').read(), 'base64', 'utf-8')att2["Content-Type"] = 'application/octet-stream'att2["Content-Disposition"] = 'attachment; filename="51coolma.txt"'message.attach(att2)try:    smtpObj = smtplib.SMTP('localhost')    smtpObj.sendmail(sender, receivers, message.as_string())    print ("邮件发送成功")except smtplib.SMTPException:    print ("Error: 无法发送邮件")
            $ python3 test.py 邮件发送成功

            查看我们的收件箱(一般在垃圾箱),就可以查看到邮件信息:



            在 HTML 文本中添加图片

            邮件的 HTML 文本中一般邮件服务商添加外链是无效的,正确添加图片的实例如下所示:

            #!/usr/bin/python3import smtplibfrom email.mime.image import MIMEImagefrom email.mime.multipart import MIMEMultipartfrom email.mime.text import MIMETextfrom email.header import Headersender = 'from@51coolma.cn'receivers = ['429240967@qq.com']  # 接收邮件,可设置为你的QQ邮箱或者其他邮箱msgRoot = MIMEMultipart('related')msgRoot['From'] = Header("W3Cschool教程", 'utf-8')msgRoot['To'] =  Header("测试", 'utf-8')subject = 'Python SMTP 邮件测试'msgRoot['Subject'] = Header(subject, 'utf-8')msgAlternative = MIMEMultipart('alternative')msgRoot.attach(msgAlternative)mail_msg = """<p>Python 邮件发送测试...</p><p><a href="http://www.51coolma.cn">W3Cschool教程链接</a></p><p>图片演示:</p><p><img src="cid:image1"></p>"""msgAlternative.attach(MIMEText(mail_msg, 'html', 'utf-8'))# 指定图片为当前目录fp = open('test.png', 'rb')msgImage = MIMEImage(fp.read())fp.close()# 定义图片 ID,在 HTML 文本中引用msgImage.add_header('Content-ID', '<image1>')msgRoot.attach(msgImage)try:    smtpObj = smtplib.SMTP('localhost')    smtpObj.sendmail(sender, receivers, msgRoot.as_string())    print ("邮件发送成功")except smtplib.SMTPException:    print ("Error: 无法发送邮件")
            $ python3 test.py 邮件发送成功

            查看我们的收件箱(如果在垃圾箱可能需要移动到收件箱才可正常显示),就可以查看到邮件信息:


            更多内容请参阅:https://docs.python.org/3/library/email-examples.html


            多线程类似于同时执行多个不同程序,多线程运行有如下优点:

            • 使用线程可以把占据长时间的程序中的任务放到后台去处理。
            • 用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度
            • 程序的运行速度可能加快
            • 在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下我们可以释放一些珍贵的资源如内存占用等等。

            线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

            每个线程都有他自己的一组 CPU 寄存器,称为线程的上下文,该上下文反映了线程上次运行该线程的 CPU 寄存器的状态。

            指令指针和堆栈指针寄存器是线程上下文中两个最重要的寄存器,线程总是在进程得到上下文中运行的,这些地址都用于标志拥有线程的进程地址空间中的内存。

            • 线程可以被抢占(中断)。
            • 在其他线程正在运行时,线程可以暂时搁置(也称为睡眠) -- 这就是线程的退让。

            线程可以分为:

            • 内核线程:由操作系统内核创建和撤销。
            • 用户线程:不需要内核支持而在用户程序中实现的线程。

            Python3 线程中常用的两个模块为:

            • _thread
            • threading(推荐使用)

            thread 模块已被废弃。用户可以使用 threading 模块代替。所以,在 Python3 中不能再使用"thread" 模块。为了兼容性,Python3 将 thread 重命名为 "_thread"。


            开始学习 Python 线程

            Python 中使用线程有两种方式:函数或者用类来包装线程对象。

            函数式:调用 _thread 模块中的 start_new_thread() 函数来产生新线程。语法如下:

            _thread.start_new_thread ( function, args[, kwargs] )

            参数说明:

            • function - 线程函数。
            • args - 传递给线程函数的参数,他必须是个 tuple 类型。
            • kwargs - 可选参数。

            实例:

            #!/usr/bin/python3import _threadimport time# 为线程定义一个函数def print_time( threadName, delay):   count = 0   while count < 5:      time.sleep(delay)      count += 1      print ("%s: %s" % ( threadName, time.ctime(time.time()) ))# 创建两个线程try:   _thread.start_new_thread( print_time, ("Thread-1", 2, ) )   _thread.start_new_thread( print_time, ("Thread-2", 4, ) )except:   print ("Error: 无法启动线程")while 1:   pass

            执行以上程序输出结果如下:

            Thread-1: Wed Apr  6 11:36:31 2016Thread-1: Wed Apr  6 11:36:33 2016Thread-2: Wed Apr  6 11:36:33 2016Thread-1: Wed Apr  6 11:36:35 2016Thread-1: Wed Apr  6 11:36:37 2016Thread-2: Wed Apr  6 11:36:37 2016Thread-1: Wed Apr  6 11:36:39 2016Thread-2: Wed Apr  6 11:36:41 2016Thread-2: Wed Apr  6 11:36:45 2016Thread-2: Wed Apr  6 11:36:49 2016

            执行以上程后可以按下 ctrl-c to 退出。


            线程模块

            Python3 通过两个标准库 _thread 和 threading 提供对线程的支持。

            _thread 提供了低级别的、原始的线程以及一个简单的锁,它相比于 threading 模块的功能还是比较有限的。

            threading 模块除了包含 _thread 模块中的所有方法外,还提供的其他方法:

            • threading.currentThread(): 返回当前的线程变量。
            • threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
            • threading.activeCount(): 返回正在运行的线程数量,与 len(threading.enumerate()) 有相同的结果。

            除了使用方法外,线程模块同样提供了 Thread 类来处理线程,Thread 类提供了以下方法:

            • run(): 用以表示线程活动的方法。
            • start():启动线程活动。

            • join([time]): 等待至线程中止。这阻塞调用线程直至线程的 join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。
            • isAlive(): 返回线程是否活动的。
            • getName(): 返回线程名。
            • setName(): 设置线程名。

            使用 threading 模块创建线程

            我们可以通过直接从 threading.Thread 继承创建一个新的子类,并实例化后调用 start() 方法启动新线程,即它调用了线程的 run() 方法:

            #!/usr/bin/python3import threadingimport timeexitFlag = 0class myThread (threading.Thread):    def __init__(self, threadID, name, counter):        threading.Thread.__init__(self)        self.threadID = threadID        self.name = name        self.counter = counter    def run(self):        print ("开始线程:" + self.name)        print_time(self.name, self.counter, 5)        print ("退出线程:" + self.name)def print_time(threadName, delay, counter):    while counter:        if exitFlag:            threadName.exit()        time.sleep(delay)        print ("%s: %s" % (threadName, time.ctime(time.time())))        counter -= 1# 创建新线程thread1 = myThread(1, "Thread-1", 1)thread2 = myThread(2, "Thread-2", 2)# 开启新线程thread1.start()thread2.start()thread1.join()thread2.join()print ("退出主线程")

            以上程序执行结果如下;

            开始线程:Thread-1开始线程:Thread-2Thread-1: Wed Apr  6 11:46:46 2016Thread-1: Wed Apr  6 11:46:47 2016Thread-2: Wed Apr  6 11:46:47 2016Thread-1: Wed Apr  6 11:46:48 2016Thread-1: Wed Apr  6 11:46:49 2016Thread-2: Wed Apr  6 11:46:49 2016Thread-1: Wed Apr  6 11:46:50 2016退出线程:Thread-1Thread-2: Wed Apr  6 11:46:51 2016Thread-2: Wed Apr  6 11:46:53 2016Thread-2: Wed Apr  6 11:46:55 2016退出线程:Thread-2退出主线程

            线程同步

            如果多个线程共同对某个数据修改,则可能出现不可预料的结果,为了保证数据的正确性,需要对多个线程进行同步。

            使用 Thread 对象的 Lock 和 Rlock 可以实现简单的线程同步,这两个对象都有 acquire 方法和 release 方法,对于那些需要每次只允许一个线程操作的数据,可以将其操作放到 acquire 和 release 方法之间。如下:

            多线程的优势在于可以同时运行多个任务(至少感觉起来是这样)。但是当线程需要共享数据时,可能存在数据不同步的问题。

            考虑这样一种情况:一个列表里所有元素都是 0,线程"set"从后向前把所有元素改成 1,而线程"print"负责从前往后读取列表并打印。

            那么,可能线程"set"开始改的时候,线程"print"便来打印列表了,输出就成了一半 0 一半 1,这就是数据的不同步。为了避免这种情况,引入了锁的概念。

            锁有两种状态——锁定和未锁定。每当一个线程比如"set"要访问共享数据时,必须先获得锁定;如果已经有别的线程比如"print"获得锁定了,那么就让线程"set"暂停,也就是同步阻塞;等到线程"print"访问完毕,释放锁以后,再让线程"set"继续。

            经过这样的处理,打印列表时要么全部输出 0,要么全部输出 1,不会再出现一半 0 一半 1 的尴尬场面。

            实例:

            #!/usr/bin/python3import threadingimport timeclass myThread (threading.Thread):    def __init__(self, threadID, name, counter):        threading.Thread.__init__(self)        self.threadID = threadID        self.name = name        self.counter = counter    def run(self):        print ("开启线程: " + self.name)        # 获取锁,用于线程同步        threadLock.acquire()        print_time(self.name, self.counter, 3)        # 释放锁,开启下一个线程        threadLock.release()def print_time(threadName, delay, counter):    while counter:        time.sleep(delay)        print ("%s: %s" % (threadName, time.ctime(time.time())))        counter -= 1threadLock = threading.Lock()threads = []# 创建新线程thread1 = myThread(1, "Thread-1", 1)thread2 = myThread(2, "Thread-2", 2)# 开启新线程thread1.start()thread2.start()# 添加线程到线程列表threads.append(thread1)threads.append(thread2)# 等待所有线程完成for t in threads:    t.join()print ("退出主线程")

            执行以上程序,输出结果为:

            开启线程: Thread-1开启线程: Thread-2Thread-1: Wed Apr  6 11:52:57 2016Thread-1: Wed Apr  6 11:52:58 2016Thread-1: Wed Apr  6 11:52:59 2016Thread-2: Wed Apr  6 11:53:01 2016Thread-2: Wed Apr  6 11:53:03 2016Thread-2: Wed Apr  6 11:53:05 2016退出主线程

            线程优先级队列( Queue)

            Python 的 Queue 模块中提供了同步的、线程安全的队列类,包括 FIFO(先入先出)队列 Queue,LIFO(后入先出)队列 LifoQueue,和优先级队列 PriorityQueue。

            这些队列都实现了锁原语,能够在多线程中直接使用,可以使用队列来实现线程间的同步。

            Queue 模块中的常用方法:

            • Queue.qsize() 返回队列的大小
            • Queue.empty() 如果队列为空,返回 True,反之 False
            • Queue.full() 如果队列满了,返回 True,反之 False
            • Queue.full 与 maxsize 大小对应
            • Queue.get([block[, timeout]]) 获取队列,timeout 等待时间
            • Queue.get_nowait() 相当 Queue.get(False)
            • Queue.put(item) 写入队列,timeout 等待时间
            • Queue.put_nowait(item) 相当 Queue.put(item, False)
            • Queue.task_done() 在完成一项工作之后,Queue.task_done() 函数向任务已经完成的队列发送一个信号
            • Queue.join() 实际上意味着等到队列为空,再执行别的操作

            实例:

            #!/usr/bin/python3import queueimport threadingimport timeexitFlag = 0class myThread (threading.Thread):    def __init__(self, threadID, name, q):        threading.Thread.__init__(self)        self.threadID = threadID        self.name = name        self.q = q    def run(self):        print ("开启线程:" + self.name)        process_data(self.name, self.q)        print ("退出线程:" + self.name)def process_data(threadName, q):    while not exitFlag:        queueLock.acquire()        if not workQueue.empty():            data = q.get()            queueLock.release()            print ("%s processing %s" % (threadName, data))        else:            queueLock.release()        time.sleep(1)threadList = ["Thread-1", "Thread-2", "Thread-3"]nameList = ["One", "Two", "Three", "Four", "Five"]queueLock = threading.Lock()workQueue = queue.Queue(10)threads = []threadID = 1# 创建新线程for tName in threadList:    thread = myThread(threadID, tName, workQueue)    thread.start()    threads.append(thread)    threadID += 1# 填充队列queueLock.acquire()for word in nameList:    workQueue.put(word)queueLock.release()# 等待队列清空while not workQueue.empty():    pass# 通知线程是时候退出exitFlag = 1# 等待所有线程完成for t in threads:    t.join()print ("退出主线程")

            以上程序执行结果:

            开启线程:Thread-1开启线程:Thread-2开启线程:Thread-3Thread-3 processing OneThread-1 processing TwoThread-2 processing ThreeThread-3 processing FourThread-1 processing Five退出线程:Thread-3退出线程:Thread-2退出线程:Thread-1退出主线程

            什么是XML?

            XML 指可扩展标记语言(eXtensible Markup Language),标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。 你可以通过本站学习 XML教程

            XML 被设计用来传输和存储数据。

            XML 是一套定义语义标记的规则,这些标记将文档分成许多部件并对这些部件加以标识。

            它也是元标记语言,即定义了用于定义其他与特定领域有关的、语义的、结构化的标记语言的句法语言。


            python对XML的解析

            常见的 XML 编程接口有 DOM 和 SAX,这两种接口处理 XML 文件的方式不同,当然使用场合也不同。

            Python 有三种方法解析 XML,SAX,DOM,以及 ElementTree:

            1.SAX (simple API for XML )

            Python 标准库包含 SAX 解析器,SAX 用事件驱动模型,通过在解析 XML 的过程中触发一个个的事件并调用用户定义的回调函数来处理 XML 文件。

            2.DOM(Document Object Model)

            将 XML 数据在内存中解析成一个树,通过对树的操作来操作 XML。

            本章节使用到的 XML 实例文件 movies.xml 内容如下:

            <collection shelf="New Arrivals"><movie title="Enemy Behind">   <type>War, Thriller</type>   <format>DVD</format>   <year>2003</year>   <rating>PG</rating>   <stars>10</stars>   <description>Talk about a US-Japan war</description></movie><movie title="Transformers">   <type>Anime, Science Fiction</type>   <format>DVD</format>   <year>1989</year>   <rating>R</rating>   <stars>8</stars>   <description>A schientific fiction</description></movie>   <movie title="Trigun">   <type>Anime, Action</type>   <format>DVD</format>   <episodes>4</episodes>   <rating>PG</rating>   <stars>10</stars>   <description>Vash the Stampede!</description></movie><movie title="Ishtar">   <type>Comedy</type>   <format>VHS</format>   <rating>PG</rating>   <stars>2</stars>   <description>Viewable boredom</description></movie></collection>

            Python 使用 SAX 解析 xml

            SAX 是一种基于事件驱动的 API。

            利用 SAX 解析 XML 文档牵涉到两个部分:解析器和事件处理器。

            解析器负责读取 XML 文档,并向事件处理器发送事件,如元素开始跟元素结束事件;

            而事件处理器则负责对事件作出相应,对传递的 XML 数据进行处理。

            • 1、对大型文件进行处理;
            • 2、只需要文件的部分内容,或者只需从文件中得到特定信息。
            • 3、想建立自己的对象模型的时候。

            在 Python 中使用 sax 方式处理 xml 要先引入 xml.sax 中的 parse 函数,还有 xml.sax.handler 中的 ContentHandler。

            ContentHandler 类方法介绍

            characters(content) 方法

            调用时机:

            从行开始,遇到标签之前,存在字符,content 的值为这些字符串。

            从一个标签,遇到下一个标签之前, 存在字符,content 的值为这些字符串。

            从一个标签,遇到行结束符之前,存在字符,content 的值为这些字符串。

            标签可以是开始标签,也可以是结束标签。

            startDocument() 方法

            文档启动的时候调用。

            endDocument() 方法

            解析器到达文档结尾时调用。

            startElement(name, attrs) 方法

            遇到XML开始标签时调用,name 是标签的名字,attrs 是标签的属性值字典。

            endElement(name) 方法

            遇到XML结束标签时调用。


            make_parser 方法

            以下方法创建一个新的解析器对象并返回。

            xml.sax.make_parser( [parser_list] )

            参数说明:

            • parser_list - 可选参数,解析器列表

            parser 方法

            以下方法创建一个 SAX 解析器并解析xml文档:

            xml.sax.parse( xmlfile, contenthandler[, errorhandler])

            参数说明:

            • xmlfile - xml文件名
            • contenthandler - 必须是一个 ContentHandler 的对象
            • errorhandler - 如果指定该参数,errorhandler 必须是一个 SAX ErrorHandler 对象

            parseString 方法

            parseString 方法创建一个 XML 解析器并解析 xml 字符串:

            xml.sax.parseString(xmlstring, contenthandler[, errorhandler])

            参数说明:

            • xmlstring - xml字符串
            • contenthandler - 必须是一个 ContentHandler 的对象
            • errorhandler - 如果指定该参数,errorhandler 必须是一个 SAX ErrorHandler对象

            Python 解析XML实例

            #!/usr/bin/python3import xml.saxclass MovieHandler( xml.sax.ContentHandler ):   def __init__(self):      self.CurrentData = ""      self.type = ""      self.format = ""      self.year = ""      self.rating = ""      self.stars = ""      self.description = ""   # 元素开始调用   def startElement(self, tag, attributes):      self.CurrentData = tag      if tag == "movie":         print ("*****Movie*****")         title = attributes["title"]         print ("Title:", title)   # 元素结束调用   def endElement(self, tag):      if self.CurrentData == "type":         print ("Type:", self.type)      elif self.CurrentData == "format":         print ("Format:", self.format)      elif self.CurrentData == "year":         print ("Year:", self.year)      elif self.CurrentData == "rating":         print ("Rating:", self.rating)      elif self.CurrentData == "stars":         print ("Stars:", self.stars)      elif self.CurrentData == "description":         print ("Description:", self.description)      self.CurrentData = ""   # 读取字符时调用   def characters(self, content):      if self.CurrentData == "type":         self.type = content      elif self.CurrentData == "format":         self.format = content      elif self.CurrentData == "year":         self.year = content      elif self.CurrentData == "rating":         self.rating = content      elif self.CurrentData == "stars":         self.stars = content      elif self.CurrentData == "description":         self.description = content  if ( __name__ == "__main__"):      # 创建一个 XMLReader   parser = xml.sax.make_parser()   # 关闭命名空间   parser.setFeature(xml.sax.handler.feature_namespaces, 0)   # 重写 ContextHandler   Handler = MovieHandler()   parser.setContentHandler( Handler )      parser.parse("movies.xml")

            以上代码执行结果如下:

            *****Movie*****Title: Enemy BehindType: War, ThrillerFormat: DVDYear: 2003Rating: PGStars: 10Description: Talk about a US-Japan war*****Movie*****Title: TransformersType: Anime, Science FictionFormat: DVDYear: 1989Rating: RStars: 8Description: A schientific fiction*****Movie*****Title: TrigunType: Anime, ActionFormat: DVDRating: PGStars: 10Description: Vash the Stampede!*****Movie*****Title: IshtarType: ComedyFormat: VHSRating: PGStars: 2Description: Viewable boredom

            完整的 SAX API 文档请查阅 Python SAX APIs


            使用xml.dom解析xml

            文件对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展置标语言的标准编程接口。

            一个 DOM 的解析器在解析一个 XML 文档时,一次性读取整个文档,把文档中所有元素保存在内存中的一个树结构里,之后你可以利用DOM 提供的不同的函数来读取或修改文档的内容和结构,也可以把修改过的内容写入xml文件。

            python中用xml.dom.minidom来解析xml文件,实例如下:

            #!/usr/bin/python3from xml.dom.minidom import parseimport xml.dom.minidom# 使用minidom解析器打开 XML 文档DOMTree = xml.dom.minidom.parse("movies.xml")collection = DOMTree.documentElementif collection.hasAttribute("shelf"):   print ("Root element : %s" % collection.getAttribute("shelf"))# 在集合中获取所有电影movies = collection.getElementsByTagName("movie")# 打印每部电影的详细信息for movie in movies:   print ("*****Movie*****")   if movie.hasAttribute("title"):      print ("Title: %s" % movie.getAttribute("title"))   type = movie.getElementsByTagName('type')[0]   print ("Type: %s" % type.childNodes[0].data)   format = movie.getElementsByTagName('format')[0]   print ("Format: %s" % format.childNodes[0].data)   rating = movie.getElementsByTagName('rating')[0]   print ("Rating: %s" % rating.childNodes[0].data)   description = movie.getElementsByTagName('description')[0]   print ("Description: %s" % description.childNodes[0].data)

            以上程序执行结果如下:

            Root element : New Arrivals*****Movie*****Title: Enemy BehindType: War, ThrillerFormat: DVDRating: PGDescription: Talk about a US-Japan war*****Movie*****Title: TransformersType: Anime, Science FictionFormat: DVDRating: RDescription: A schientific fiction*****Movie*****Title: TrigunType: Anime, ActionFormat: DVDRating: PGDescription: Vash the Stampede!*****Movie*****Title: IshtarType: ComedyFormat: VHSRating: PGDescription: Viewable boredom

            完整的 DOM API 文档请查阅 Python DOM APIs


            Python3 JSON 数据解析

            JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于 ECMAScript 的一个子集。

            Python3 中可以使用 json 模块来对 JSON 数据进行编解码,它包含了两个函数:

            • json.dumps(): 对数据进行编码。
            • json.loads(): 对数据进行解码。

            在json的编解码过程中,Python 的原始类型与 json 类型会相互转换,具体的转化对照如下:

            Python 编码为 JSON 类型转换对应表:

            PythonJSON
            dictobject
            list, tuplearray
            strstring
            int, float, int- & float-derived Enumsnumber
            Truetrue
            Falsefalse
            Nonenull

            JSON 解码为 Python 类型转换对应表:

            JSONPython
            objectdict
            arraylist
            stringstr
            number (int)int
            number (real)float
            trueTrue
            falseFalse
            nullNone

            json.dumps 与 json.loads 实例

            以下实例演示了 Python 数据结构转换为 JSON:

            #!/usr/bin/python3import json# Python 字典类型转换为 JSON 对象data = {    'no' : 1,    'name' : 'W3CSchool',    'url' : 'http://www.51coolma.cn'}json_str = json.dumps(data)print ("Python 原始数据:", repr(data))print ("JSON 对象:", json_str)

            执行以上代码输出结果为:

            Python 原始数据: {'url': 'http://www.51coolma.cn', 'no': 1, 'name': 'W3CSchool'}JSON 对象: {"url": "http://www.51coolma.cn", "no": 1, "name": "W3CSchool"}

            通过输出的结果可以看出,简单类型通过编码后跟其原始的repr()输出结果非常相似。

            接着以上实例,我们可以将一个JSON编码的字符串转换回一个Python数据结构:

            #!/usr/bin/python3import json# Python 字典类型转换为 JSON 对象data1 = {    'no' : 1,    'name' : 'W3CSchool',    'url' : 'http://www.51coolma.cn'}json_str = json.dumps(data1)print ("Python 原始数据:", repr(data1))print ("JSON 对象:", json_str)# 将 JSON 对象转换为 Python 字典data2 = json.loads(json_str)print ("data2['name']: ", data2['name'])print ("data2['url']: ", data2['url'])

            执行以上代码输出结果为:

            ython 原始数据: {'name': 'W3CSchool', 'no': 1, 'url': 'http://www.51coolma.cn'}JSON 对象: {"name": "W3CSchool", "no": 1, "url": "http://www.51coolma.cn"}data2['name']:  W3CSchooldata2['url']:  http://www.51coolma.cn

            如果你要处理的是文件而不是字符串,你可以使用 json.dump()json.load() 来编码和解码 JSON 数据。例如:

            # 写入 JSON 数据with open('data.json', 'w') as f:    json.dump(data, f)# 读取数据with open('data.json', 'r') as f:    data = json.load(f)

            更多资料请参考:https://docs.python.org/3/library/json.html

            Python3 日期和时间

            Python 程序能用很多方式处理日期和时间,转换日期格式是一个常见的功能。

            Python 提供了一个 time 和 calendar 模块可以用于格式化日期和时间。

            时间间隔是以秒为单位的浮点小数。

            每个时间戳都以自从 1970 年 1 月 1 日午夜(历元)经过了多长时间来表示。

            Python 的 time 模块下有很多函数可以转换常见日期格式。如函数 time.time() 用于获取当前时间戳, 如下实例:

            #!/usr/bin/python3import time;  # 引入time模块ticks = time.time()print ("当前时间戳为:", ticks)

            以上实例输出结果:

            当前时间戳为: 1459996086.7115328

            时间戳单位最适于做日期运算。但是 1970 年之前的日期就无法以此表示了。太遥远的日期也不行,UNIX 和 Windows 只支持到 2038 年。


            什么是时间元组?

            很多 Python 函数用一个元组装起来的9组数字处理时间:

            序号字段
            04 位数年2020
            11 到 12
            21 到 31
            3小时0 到 23
            4分钟0 到 59
            50 到 61 (60 或 61 是闰秒)
            6一周的第几日0 到 6 (0 是周一)
            7一年的第几日1 到 366 (儒略历)
            8夏令时-1, 0, 1, -1是决定是否为夏令时的旗帜

            上述也就是struct_time元组。这种结构具有如下属性:

            序号属性
            0tm_year2020
            1tm_mon1 到 12
            2tm_mday1 到 31
            3tm_hour0 到 23
            4tm_min0 到 59
            5tm_sec0 到 61 (60或61 是闰秒)
            6tm_wday0到6 (0是周一)
            7tm_yday一年中的第几天,1 到 366
            8tm_isdst是否为夏令时,值有:1(夏令时)、0(不是夏令时)、-1(未知),默认 -1


            获取当前时间

            从返回浮点数的时间辍方式向时间元组转换,只要将浮点数传递给如 localtime 之类的函数。

            #!/usr/bin/python3
            import time

            localtime
            = time.localtime(time.time())
            print
            ("本地时间为 :", localtime)

            以上实例输出结果:

            本地时间为 : time.struct_time(tm_year=2016, tm_mon=4, tm_mday=7, tm_hour=10, tm_min=28, tm_sec=49, tm_wday=3, tm_yday=98, tm_isdst=0)

            获取格式化的时间

            你可以根据需求选取各种格式,但是最简单的获取可读的时间模式的函数是 asctime():

            #!/usr/bin/python3
            import
            time

            localtime
            = time.asctime( time.localtime(time.time()) )
            print
            ("本地时间为 :", localtime)

            以上实例输出结果:

            本地时间为 : Thu Apr  7 10:29:13 2020

            格式化日期

            我们可以使用 time 模块的 strftime 方法来格式化日期,:

            time.strftime(format[, t])
            #!/usr/bin/python3
            import
            time

            # 格式化成2020-03-20 11:45:39形式

            print
            (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

            # 格式化成Sat Mar 28 22:24:24 2020形式
            print (time.strftime("%a %b %d %H:%M:%S %Y", time.localtime()))

            # 将格式字符串转换为时间戳

            a
            = "Sat Mar 28 22:24:24 2020"
            print (time.mktime(time.strptime(a,"%a %b %d %H:%M:%S %Y")))

            以上实例输出结果:

            2020-04-07 10:29:46
            Thu Apr 07 10:29:46
            2020
            1459175064.0

            Python 中时间日期格式化符号:

            • %y 两位数的年份表示(00-99)
            • %Y 四位数的年份表示(000-9999)
            • %m 月份(01-12)
            • %d 月内中的一天(0-31)
            • %H 24 小时制小时数(0-23)
            • %I 12 小时制小时数(01-12)
            • %M 分钟数(00=59)
            • %S 秒(00-59)
            • %a 本地简化星期名称
            • %A 本地完整星期名称
            • %b 本地简化的月份名称
            • %B 本地完整的月份名称
            • %c 本地相应的日期表示和时间表示
            • %j 年内的一天(001-366)
            • %p 本地 A.M. 或 P.M. 的等价符
            • %U 一年中的星期数(00-53)星期天为星期的开始
            • %w 星期(0-6),星期天为星期的开始
            • %W 一年中的星期数(00-53)星期一为星期的开始
            • %x 本地相应的日期表示
            • %X 本地相应的时间表示
            • %Z 当前时区的名称
            • %% %号本身

            获取某月日历

            Calendar 模块有很广泛的方法用来处理年历和月历,例如打印某月的月历:

            #!/usr/bin/python3

            import calendar
            cal
            = calendar.month(2020, 9)
            print ("以下输出2020年9月份的日历:")
            print (cal)

            以上实例输出结果:

            以下输出20209月份的日历:    
            September 2020
            Mo Tu We Th Fr Sa Su
            1 2 3
            4
            5 6 7 8 9 10
            11
            12 13 14 15 16 17
            18
            19 20 21 22 23 24
            25
            26 27 28 29 30 31


            Time 模块

            Time 模块包含了以下内置函数,既有时间处理相的,也有转换时间格式的:

            序号函数及描述实例
            1time.altzone
            返回格林威治西部的夏令时地区的偏移秒数。如果该地区在格林威治东部会返回负值(如西欧,包括英国)。对夏令时启用地区才能使用。

            以下实例展示了 altzone()函数的使用方法:

            >>> import time
            >>> print ("time.altzone %d " % time.altzone)
            time.altzone -28800
            2time.asctime([tupletime])
            接受时间元组并返回一个可读的形式为"Tue Dec 11 18:07:14 2008"(2008年12月11日 周二18时07分14秒)的24个字符的字符串。

            以下实例展示了 asctime()函数的使用方法:

            >>> import time
            >>> t = time.localtime()
            >>> print ("time.asctime(t): %s " % time.asctime(t))
            time.asctime(t): Thu Apr 7 10:36:20 2016
            3time.clock()
            用以浮点数计算的秒数返回当前的CPU时间。用来衡量不同程序的耗时,比time.time()更有用。
            实例
            4time.ctime([secs])
            作用相当于asctime(localtime(secs)),未给参数相当于asctime()

            以下实例展示了 ctime()函数的使用方法:

            >>> import time
            >>> print ("time.ctime() : %s" % time.ctime())
            time
            .ctime() : Thu Apr 7 10:51:58 2016
            5time.gmtime([secs])
            接收时间辍(1970纪元后经过的浮点秒数)并返回格林威治天文时间下的时间元组t。注:t.tm_isdst始终为0

            以下实例展示了 gmtime()函数的使用方法:

            >>> import time
            >>> print ("gmtime :", time.gmtime(1455508609.34375))
            gmtime
            : time.struct_time(tm_year=2016, tm_mon=2, tm_mday=15, tm_hour=3, tm_min=56, tm_sec=49, tm_wday=0, tm_yday=46, tm_isdst=0)
            6time.localtime([secs]
            接收时间辍(1970纪元后经过的浮点秒数)并返回当地时间下的时间元组t(t.tm_isdst可取0或1,取决于当地当时是不是夏令时)。

            以下实例展示了 localtime()函数的使用方法:

            >>> import time
            >>>
            print ("localtime(): ", time.localtime(1455508609.34375))
            localtime(): time.struct_time(tm_year=2016, tm_mon=2, tm_mday=15, tm_hour=11, tm_min=56, tm_sec=49, tm_wday=0, tm_yday=46, tm_isdst=0)
            7time.mktime(tupletime)
            接受时间元组并返回时间辍(1970纪元后经过的浮点秒数)。
            实例
            8time.sleep(secs)
            推迟调用线程的运行,secs指秒数。

            以下实例展示了 sleep()函数的使用方法:

            #!/usr/bin/python3
            import
            time

            print
            ("Start : %s" % time.ctime())
            time.sleep( 5 )
            print
            ("End : %s" % time.ctime())
            9time.strftime(fmt[,tupletime])
            接收以时间元组,并返回以可读字符串表示的当地时间,格式由fmt决定。

            以下实例展示了 strftime()函数的使用方法:

            >>> import time
            >>> print (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
            2016
            -04-07 11:18:05
            10time.strptime(str,fmt='%a %b %d %H:%M:%S %Y')
            根据fmt的格式把一个时间字符串解析为时间元组。

            以下实例展示了 strptime()函数的使用方法:

            >>> import time
            >>> struct_time = time.strptime("30 Nov 00", "%d %b %y")
            >>> print ("返回元组: ", struct_time)
            返回元组:
            time.struct_time(tm_year=2000, tm_mon=11, tm_mday=30, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=335, tm_isdst=-1)
            11time.time( )
            返回当前时间的时间戳(1970纪元后经过的浮点秒数)。

            以下实例展示了 time()函数的使用方法:

            >>> import time
            >>>
            print(time.time())
            1459999336.1963577
            12time.tzset()
            根据环境变量TZ重新初始化时间相关设置。
            实例

            Time 模块包含了以下 2 个非常重要的属性:

            序号属性及描述
            1time.timezone
            属性time.timezone是当地时区(未启动夏令时)距离格林威治的偏移秒数(>0,美洲;<=0大部分欧洲,亚洲,非洲)。
            2time.tzname
            属性time.tzname包含一对根据情况的不同而不同的字符串,分别是带夏令时的本地时区名称,和不带的。


            日历(Calendar)模块

            此模块的函数都是日历相关的,例如打印某月的字符月历。

            星期一是默认的每周第一天,星期天是默认的最后一天。更改设置需调用calendar.setfirstweekday() 函数。模块包含了以下内置函数:

            序号函数及描述
            1calendar.calendar(year,w=2,l=1,c=6)
            返回一个多行字符串格式的 year 年年历,3 个月一行,间隔距离为 c。 每日宽度间隔为 w 字符。每行长度为 21* W+18+2* C。l 是每星期行数。
            2calendar.firstweekday( )
            返回当前每周起始日期的设置。默认情况下,首次载入 calendar 模块时返回 0,即星期一。
            3calendar.isleap(year)
            是闰年返回 True,否则为 False。
            4calendar.leapdays(y1,y2)
            返回在 Y1,Y2 两年之间的闰年总数。
            5calendar.month(year,month,w=2,l=1)
            返回一个多行字符串格式的 year 年 month 月日历,两行标题,一周一行。每日宽度间隔为 w 字符。每行的长度为 7* w+6。l 是每星期的行数。
            6calendar.monthcalendar(year,month)
            返回一个整数的单层嵌套列表。每个子列表装载代表一个星期的整数。Year 年 month 月外的日期都设为 0;范围内的日子都由该月第几日表示,从 1 开始。
            7calendar.monthrange(year,month)
            返回两个整数。第一个是该月的星期几的日期码,第二个是该月的日期码。日从 0(星期一)到 6 (星期日);月从 1 到 12。
            8calendar.prcal(year,w=2,l=1,c=6)
            相当于 print calendar.calendar(year,w,l,c).
            9calendar.prmonth(year,month,w=2,l=1)
            相当于 print calendar.calendar(year,w,l,c)。
            10calendar.setfirstweekday(weekday)
            设置每周的起始日期码。0(星期一)到 6(星期日)。
            11calendar.timegm(tupletime)
            和 time.gmtime 相反:接受一个时间元组形式,返回该时刻的时间辍(1970 纪元后经过的浮点秒数)。
            12calendar.weekday(year,month,day)
            返回给定日期的日期码。0(星期一)到6(星期日)。月份为 1(一月) 到 12(12月)。


            其他相关模块和函数

            在 Python中,其他处理日期和时间的模块还有:


            本节介绍了 Python3 中的内置函数以及调试的两种方法。

            内置函数
            abs()dict()help()min()setattr()
            all()dir()hex()next()slice()
            any()divmod()id()object()sorted()
            ascii()enumerate()input()oct()staticmethod()
            bin()eval()int()open()str()
            bool()exec()isinstance()ord()sum()
            bytearray()filter()issubclass()pow()super()
            bytes()float()iter()print()tuple()
            callable()format()len()property()type()
            chr()frozenset()list()range()vars()
            classmethod()getattr()locals()repr()zip()
            compile()globals()map()reversed()__import__()
            complex()hasattr()max()round() 
            delattr()hash()memoryview()set() 

            Python 调试方法

            1、print

            print('here')# 可以发现某段逻辑是否执行# 打印出变量的内容

            2、assert

            assert false, 'blabla'# 如果条件不成立,则打印出 'blabla' 并抛出AssertionError异常

            3、debugger

            可以通过 pdb、IDE 等工具进行调试。

            调试的具体方法这里不展开。

            Python 中有两个内置方法在这里也很有帮助:

            •  locals: 执行 locals() 之后, 返回一个字典, 包含(current scope)当前范围下的局部变量。
            •  globals: 执行 globals() 之后, 返回一个字典, 包含(current scope)当前范围下的全局变量。


            Python的备忘单是用于Python 3的编程语言中的单页参考表。

            开始

            介绍

            Hello World

            >>> print("Hello, World!")Hello, World!

            Python 中著名的“Hello World”程序

            变量

            x = 4        # x is of type intx = "Sally"  # x is now of type strprint(x)

            Python 没有用于声明变量的命令。

            数据类型

            str文本
            int, float,complex数字
            list, tuple,range序列
            dict映射
            set, frozenset集合
            bool布尔值
            bytes, bytearray,memoryview二进制

            请参阅:数据类型

            切片字符串

            >>> b = "Hello, World!">>> print(b[2:5])llo

            请参阅:字符串

            列表

            mylist = []mylist.append(1)mylist.append(2)for x in mylist:    print(x) # prints out 1,2

            请参阅:列表

            if-else

            a = 200if a > 0:    print("a is greater than 0")else:    print("a is not greater than 0")

            请参阅:流量控制

            循环

            for x in range(6):    if x == 3: break    print(x)else:    print("Finally finished!")

            请参阅:循环

            函数

            >>> def my_function():...     print("Hello from a function")...>>> my_function()Hello from a function

            请参阅:函数

            文件处理

            with open("myfile.txt", "r", encoding='utf8') as file:    for x in file:        print(x)

            请参阅:文件处理

            算术运算符

            result = 10 + 30  # =>  40result = 40 - 10  # =>  30result = 50 * 5   # =>  250result = 16 / 4   # =>  4result = 25 % 2   # =>  1result = 5 ** 3   # =>  125

            加等于

            counter = 0counter += 10           # => 10counter = 0counter = counter + 10  # => 10message = "Part 1."# => Part 1.Part 2.message += "Part 2."   

            Python 数据类型

            字符串

            s = "Hello World"s = 'Hello World'a = """Multiline StringsLorem ipsum dolor sit amet,consectetur adipiscing elit """

            请参阅:字符串

            数字

            x = 1    # inty = 2.8  # floatz = 1j   # complex>>> print(type(x))<class 'int'>

            布尔值

            a = True b = Falsebool(0)     # => Falsebool(1)     # => True

            列表

            list1 = ["apple", "banana", "cherry"]list2 = [True, False, False]list3 = [1, 5, 7, 9, 3]list4 = list((1, 5, 7, 9, 3))

            请参阅:列表

            元组

            a = (1, 2, 3)a = tuple((1, 2, 3))

            类似于 List 但不可变

            集合

            set1 = {"a", "b", "c"}   set2 = set(("a", "b", "c"))

            一组独特的项目/对象

            字典

            >>> empty_dict = {}>>> a = {"one": 1, "two": 2, "three": 3}>>> a["one"]1>>> a.keys()dict_keys(['one', 'two', 'three'])>>> a.values()dict_values([1, 2, 3])>>> a.update({"four": 4})>>> a.keys()dict_keys(['one', 'two', 'three', 'four'])>>> a['four']4

            键:值对,类JSON对象

            赋值

            整数

            x = int(1)   # x will be 1y = int(2.8) # y will be 2z = int("3") # z will be 3

            浮动

            x = float(1)     # x will be 1.0y = float(2.8)   # y will be 2.8z = float("3")   # z will be 3.0w = float("4.2") # w will be 4.2

            字符串

            x = str("s1") # x will be 's1'y = str(2)    # y will be '2'z = str(3.0)  # z will be '3.0'

            Python 字符串

            类似数组

            >>> a = "Hello, World">>> print(a[1])e>>> print(a[len(a)-1])d

            获取位置 1 处的字符

            循环

            >>> for x in "abc":...     print(x)abc

            循环遍历单词“banana”中的字母

            切片字符串

             ┌───┬───┬───┬───┬───┬───┬───┐ | m | y | b | a | c | o | n | └───┴───┴───┴───┴───┴───┴───┘ 0   1   2   3   4   5   6   7-7  -6  -5  -4  -3  -2  -1

            >>> s = 'mybacon'>>> s[2:5]'bac'>>> s[0:2]'my'
            >>> s = 'mybacon'>>> s[:2]'my'>>> s[2:]'bacon'>>> s[:2] + s[2:]'mybacon'>>> s[:]'mybacon'
            >>> s = 'mybacon'>>> s[-5:-1]'baco'>>> s[2:6]'baco'

            切片方式

            >>> s = '12345' * 5>>> s'1234512345123451234512345'>>> s[::5]'11111'>>> s[4::5]'55555'>>> s[::-5]'55555'>>> s[::-1]'5432154321543215432154321'

            字符串长度

            >>> a = "Hello, World!">>> print(len(a))13

            len() 函数返回字符串的长度

            多次复制

            >>> s = '===+'>>> n = 8>>> s * n'===+===+===+===+===+===+===+===+'

            检查字符串

            >>> s = 'spam'>>> s in 'I saw spamalot!'True>>> s not in 'I saw The Holy Grail!'True

            连接

            >>> s = 'spam'>>> t = 'egg'>>> s + t'spamegg'>>> 'spam' 'egg''spamegg'

            格式化

            name = "John"print("Hello, %s!" % name)
            name = "John"age = 23print("%s is %d years old." % (name, age))

            format() 方法

            txt1 = "My name is {fname}, I'm {age}".format(fname = "John", age = 36)txt2 = "My name is {0}, I'm {1}".format("John",36)txt3 = "My name is {}, I'm {}".format("John",36)

            input

            >>> name = input("Enter your name: ")Enter your name: Tom>>> name'Tom'

            从控制台获取输入数据

            join

            >>> "#".join(["John", "Peter", "Vicky"])'John#Peter#Vicky'

            endswith

            >>> "Hello, world!".endswith("!")True

            Python 列表

            定义

            >>> li1 = []>>> li1[]>>> li2 = [4, 5, 6]>>> li2[4, 5, 6]>>> li3 = list((1, 2, 3))>>> li3[1, 2, 3]>>> li4 = list(range(1, 11))>>> li4[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

            生成

            >>> list(filter(lambda x : x % 2 == 1, range(1, 20)))[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]>>> [x ** 2 for x in range (1, 11) if  x % 2 == 1][1, 9, 25, 49, 81]>>> [x for x in [3, 4, 5, 6, 7] if x > 5][6, 7]>>> list(filter(lambda x: x > 5, [3, 4, 5, 6, 7]))[6, 7]

            append

            >>> li = []>>> li.append(1)>>> li[1]>>> li.append(2)>>> li[1, 2]>>> li.append(4)>>> li[1, 2, 4]>>> li.append(3)>>> li[1, 2, 4, 3]

            列表切片

            列表切片的语法:

            a_list[start:end]a_list[start:end:step]

            切片

            >>> a = ['spam', 'egg', 'bacon', 'tomato', 'ham', 'lobster']>>> a[2:5]['bacon', 'tomato', 'ham']>>> a[-5:-2]['egg', 'bacon', 'tomato']>>> a[1:4]['egg', 'bacon', 'tomato']

            省略索引

            >>> a[:4]['spam', 'egg', 'bacon', 'tomato']>>> a[0:4]['spam', 'egg', 'bacon', 'tomato']>>> a[2:]['bacon', 'tomato', 'ham', 'lobster']>>> a[2:len(a)]['bacon', 'tomato', 'ham', 'lobster']>>> a['spam', 'egg', 'bacon', 'tomato', 'ham', 'lobster']>>> a[:]['spam', 'egg', 'bacon', 'tomato', 'ham', 'lobster']

            切片方式

            ['spam', 'egg', 'bacon', 'tomato', 'ham', 'lobster']>>> a[0:6:2]['spam', 'bacon', 'ham']>>> a[1:6:2]['egg', 'tomato', 'lobster']>>> a[6:0:-2]['lobster', 'tomato', 'egg']>>> a['spam', 'egg', 'bacon', 'tomato', 'ham', 'lobster']>>> a[::-1]['lobster', 'ham', 'tomato', 'bacon', 'egg', 'spam']

            pop

            >>> li = ['bread', 'butter', 'milk']>>> li.pop()'milk'>>> li['bread', 'butter']>>> del li[0]>>> li['butter']

            使用权

            >>> li = ['a', 'b', 'c', 'd']>>> li[0]'a'>>> li[-1]'d'>>> li[4]Traceback (most recent call last):  File "<stdin>", line 1, in <module>IndexError: list index out of range

            串联

            >>> odd = [1, 3, 5]>>> odd.extend([9, 11, 13])>>> odd[1, 3, 5, 9, 11, 13]>>> odd = [1, 3, 5]>>> odd + [9, 11, 13][1, 3, 5, 9, 11, 13]

            排序和反转

            >>> li = [3, 1, 3, 2, 5]>>> li.sort()>>> li[1, 2, 3, 3, 5]>>> li.reverse()>>> li[5, 3, 3, 2, 1]

            计数

            >>> li = [3, 1, 3, 2, 5]>>> li.count(3)2

            重复

            >>> li = ["re"] * 3>>> li['re', 're', 're']

            Python 流控制

            基本的

            a = 5if a > 10:    print("a is totally bigger than 10.")elif a < 10:    print("a is smaller than 10.")else:    print("a is indeed 10.")

            一行代码

            >>> a = 330>>> b = 200>>> r = "a" if a > b else "b">>> print(r)a

            if-elif-else

            value = Trueif not value:    print("Value is False")elif value is None:    print("Value is None")else:    print("Value is True")

            Python 循环

            基本的

            primes = [2, 3, 5, 7]for prime in primes:    print(prime)

            带索引

            animals = ["dog", "cat", "mouse"]for i, value in enumerate(animals):    print(i, value)

            while

            x = 0while x < 4:    print(x)    x += 1  # Shorthand for x = x + 1

            break

            x = 0for index in range(10):    x = index * 10    if index == 5:    	break    print(x)

            continue

            for index in range(3, 8):     x = index * 10    if index == 5:    	continue    print(x)

            range 范围

            for i in range(4):    print(i) # Prints: 0 1 2 3for i in range(4, 8):    print(i) # Prints: 4 5 6 7for i in range(4, 10, 2):    print(i) # Prints: 4 6 8

            zip()

            name = ['Pete', 'John', 'Elizabeth']age = [6, 23, 44]for n, a in zip(name, age):    print('%s is %d years old' %(n, a))

            列表理解

            result = [x**2 for x in range(10) if x % 2 == 0] print(result)# [0, 4, 16, 36, 64]

            Python 函数

            基本的

            def hello_world():      print('Hello, World!')

            return

            def add(x, y):    print("x is %s, y is %s" %(x, y))    return x + yadd(5, 6)    # => 11

            位置参数

            def varargs(*args):    return argsvarargs(1, 2, 3)  # => (1, 2, 3)

            关键字参数

            def keyword_args(**kwargs):    return kwargs# => {"big": "foot", "loch": "ness"}keyword_args(big="foot", loch="ness")

            返回多个

            def swap(x, y):    return y, xx = 1y = 2x, y = swap(x, y)  # => x = 2, y = 1

            默认值

            def add(x, y=10):    return x + yadd(5)      # => 15add(5, 20)  # => 25

            匿名函数

            # => True(lambda x: x > 2)(3)# => 5(lambda x, y: x ** 2 + y ** 2)(2, 1)

            Python 模块

            导入模块

            import mathprint(math.sqrt(16))  # => 4.0

            从一个模块

            from math import ceil, floorprint(ceil(3.7))   # => 4.0print(floor(3.7))  # => 3.0

            全部导入

            from math import *

            缩短模块

            import math as m# => Truemath.sqrt(16) == m.sqrt(16)

            功能和属性

            import mathdir(math)

            Python 文件处理

            读取文件

            逐行

            with open("myfile.txt") as file:    for line in file:        print(line)

            带行号

            input = open('myfile.txt', 'r')for i,line in enumerate(input, start=1):    print("Number %s: %s" % (i, line))

            String

            写一个字符串

            contents = {"aa": 12, "bb": 21}with open("myfile1.txt", "w+") as file:    file.write(str(contents))

            读取字符串

            with open('myfile1.txt', "r+") as file:    contents = file.read()print(contents)

            目的

            写一个对象

            contents = {"aa": 12, "bb": 21}with open("myfile2.txt", "w+") as file:    file.write(json.dumps(contents))

            读取对象

            with open('myfile2.txt', "r+") as file:    contents = json.load(file)print(contents)

            删除文件

            import osos.remove("myfile.txt")

            检查和删除

            import osif os.path.exists("myfile.txt"):    os.remove("myfile.txt")else:    print("The file does not exist")

            删除文件夹

            import osos.rmdir("myfolder")

            Python 类和继承

            定义

            class MyNewClass:    '''This is a docstring.'''    pass# Class Instantiationmy = MyNewClass()

            构造函数

            class Animal:    def __init__(self, voice):    self.voice = voice cat = Animal('Meow')print(cat.voice)    # => Meow dog = Animal('Woof') print(dog.voice)    # => Woof

            方法

            class Dog:    # Method of the class    def bark(self):    print("Ham-Ham") charlie = Dog()charlie.bark()   # => "Ham-Ham"

            类变量

            class my_class:    class_variable = "A class variable!"  x = my_class()y = my_class() # => A class variable!print(x.class_variable)# => A class variable!print(y.class_variable)

            Super() 函数

            class ParentClass:    def print_test(self):        print("Parent Method") class ChildClass(ParentClass):    def print_test(self):        print("Child Method")        # Calls the parent's print_test()        super().print_test() 

            >>> child_instance = ChildClass()>>> child_instance.print_test()Child MethodParent Method

            repr() 方法

            class Employee:    def __init__(self, name):        self.name = name     def __repr__(self):        return self.name john = Employee('John')print(john)  # => John

            用户定义的异常

            class CustomError(Exception):    pass

            多态性

            class ParentClass:    def print_self(self):        print('A') class ChildClass(ParentClass):    def print_self(self):        print('B') obj_A = ParentClass()obj_B = ChildClass() obj_A.print_self() # => Aobj_B.print_self() # => B

            覆盖

            class ParentClass:    def print_self(self):        print("Parent") class ChildClass(ParentClass):    def print_self(self):        print("Child") child_instance = ChildClass()child_instance.print_self() # => Child

            继承

            class Animal:     def __init__(self, name, legs):        self.name = name        self.legs = legs        class Dog(Animal):    def sound(self):        print("Woof!") Yoki = Dog("Yoki", 4)print(Yoki.name) # => YOKIprint(Yoki.legs) # => 4Yoki.sound()     # => Woof!

            其他

            注释

            # This is a single line comments.
            """ Multiline strings can be written    using three "s, and are often used    as documentation."""
            ''' Multiline strings can be written    using three 's, and are often used    as documentation.'''

            生成器

            def double_numbers(iterable):    for i in iterable:        yield i + i

            生成器可以帮助您编写懒惰的代码。

            要列出的生成器

            values = (-x for x in [1,2,3,4,5])gen_to_list = list(values)# => [-1, -2, -3, -4, -5]print(gen_to_list)

            处理异常

            try:    # Use "raise" to raise an error    raise IndexError("This is an index error")except IndexError as e:    pass                 # Pass is just a no-op. Usually you would do recovery here.except (TypeError, NameError):    pass                 # Multiple exceptions can be handled together, if required.else:                    # Optional clause to the try/except block. Must follow all except blocks    print("All good!")   # Runs only if the code in try raises no exceptionsfinally:                 # Execute under all circumstances    print("We can clean up resources here")


            python3.10版本于2021年10月4日发布正式版,该版本带来了七大新特性。为了让大家对新版本有更好的认识,接下来的介绍会尽量添加python3.10版本和旧版本的代码进行对比。

             带*号的为比较重要的特性。

            *类型检查改进

            Python3.10版本中,联合运算符使用“|”线来代替了旧版本中的Union[]方法,使得程序更加简洁,不仅如此,Python3.10在一些内置函数中,同样可以利用“|”线的联合运算符来提升程序的性能。

            在函数中:

            from typing import Union # 使用Union需要引入对应的包

            # 旧版本

            def oldFunc(para: Union[int, float]) -> Union[int, float]: 

                return para ** 2

            # 新版本

            def newFunc(para: int | float) -> int | float:

                return para ** 2

            print(newFunc(3))

            在内置函数中使用联合运算符:

            # 旧版本

            print(isinstance("W3Cschool", (str, int)))

            # 新版本

            print(isinstance("W3Cschool", str | int))

            *上下文管理器

            python3.10 中,with 支持使用外层圆括号来使用多个上下文管理器,可以连续多行地书写。这允许将过长的上下文管理器集能够以与之前 import 语句类似的方式格式化为多行的形式。例如,以下这些示例写法现在都是有效的:

            with (CtxManager() as example):    passwith (CtxManager1(),    CtxManager2()):    passwith (CtxManager1() as example,      CtxManager2()):    passwith (CtxManager1(),      CtxManager2() as example):    passwith (CtxManager1() as example1,    CtxManager2() as example2):    pass

            *模板匹配

            Python 3.10 引入了结构化的模式匹配,通过match...case关键词来完成,可以匹配字典,类以及其他更复杂的结构。match...case的模式匹配,在使用的方式上与C++中的switch有很多的相似之处。

            下面的函数中,case函数通过匹配grade,如果grade为'A',则匹配到第一个例子,如果grade为'B',则匹配到第二个例子...如果前面的案例都不满足时,则输出最后的默认结果。

            grade = 'B'
            match grade: # 看grade变量,并与下面的case做对比(类似其他语言的switch
            case 'A': # 如果grade为'A',则执行该代码块
            print("很棒")
            case 'B': # 如果grade为'B',则执行该代码块
            print("做得好")
            case 'C': # 如果grade为'C',则执行该代码块
            print("您通过了")
            case "D":
            print("最好再试一下")
            case _: # 如果上面的所有case都未命中,则执行该代码块(类似于其他语言的default)
            print("无效的成绩")

            字典增加mapping属性

            在Python3.10中,针对于字典的三个方法,items,keys和values都增加了一个新的“mapping”属性,通过上述的程序可以发现,对三个方法调用mapping属性后都会返回原字典数据。

            mydict = {"W3Cschool": 1, "baidu": 2, "Google": 3}

            # 旧版本
            print(mydict.keys())
            print(mydict.values())
            print(mydict.items())

            # 新版本
            keys = mydict.keys()
            values = mydict.values()
            items = mydict.items()

            print(keys.mapping)
            print(values.mapping)
            print(items.mapping)

            # 可以理解为我们可以根据字典的keys,values,items反向推出这个字典

            函数 zip() 增加 strict 参数

            Python3.10中对于zip函数添加了strict参数,顾名思义,strict参数就是要严格的遵守参数长度的匹配原则,下面程序中,keys和values列表的长度并不一致。

            旧版本的zip函数会根据长度最短的参数来创建字典。新版本的zip函数中,当设定strict参数设置为True时,则要求zip的输入参数必须要长度一致,否则就会报错。

            keys = ['W3Cschool', 'Baidu', 'Google']
            values = [1,2,3,4]
            #旧版本
            try:
            print(dict(zip(keys,values)))
            except:
            print("字典创建失败")

            try:
            print(dict(zip(keys, values, strict=True)))
            # 增加strict参数后,如果两个列表长度不等,创建的时候会报错
            except:
            print("字典创建失败")#报错后使用try-except语句捕获

            二进制表示中的频率为1的数量统计

            在Python3.10版本中,可以通过调用bit_count函数来统计二进制中数字“1”的个数,当然,在旧版本中,也可以通过很简单的代码实现这个功能。

            value = 5#旧版本print(bin(value).count("1"))#新版本print(value.bit_count())

            类型别名的更改

            在旧版本中,可以直接通过不同类型的赋值操作来赋予类型新的名字,而在Python3.10版本中,则通过TypeAlias来规定了类型名字的替换。这样操作的优势在于能够让程序开发人员和Python编辑器更加清楚的知道newname是一个变量名还是一个类型的别名,提升程序开发的可靠性。

            from typing import TypeAlias # 使用TypeAlias需要导入相关的包

            #旧版本oldname = strdef oldFunc(paran:olaname)->oldname:    return param+param#新版本newname:TypeAlias = strdef newFunc(param:newname)->newname:    return param+paramprint(newFunc("W3Cschool"))

            准备弃用Distutils 内置库

            由于Distutils库的功能已经被此setuptools和package库取代了,所以本着简洁性的原则,Distutils在不久的将来(3.12版本)将会被完全的删除掉。

             Distutils包为将待构建和安装的额外的模块,打包成 Python 安装包提供支持。新模块既可以是百分百的纯 Python,也可以是用 C 写的扩展模块,或者可以是一组包含了同时用 Python 和 C 编码的 Python 包。

            大多数 Python 用户 不会 想要直接使用这个包,而是使用 Python 包官方维护的跨版本工具。特别地, setuptools 是一个对于 distutils 的增强选项,它能提供:

            • 对声明项目依赖的支持
            • 额外的用于配置哪些文件包含在源代码发布中的机制(包括与版本控制系统集成需要的插件)
            • 生成项目“进入点”的能力,进入点可用作应用插件系统的基础
            • 自动在安装时间生成 Windows 命令行可执行文件的能力,而不是需要预编译它们
            • 跨所有受支持的 Python 版本上的一致的表现


            回溯中增强的错误位置

            打印回溯时,解释器现在将指向导致错误的确切表达式,而不仅仅是行。例如:

            Traceback (most recent call last):
            File "distance.py", line 11, in <module>
              print(manhattan_distance(p1, p2))
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^
            File "distance.py", line 6, in manhattan_distance
              return abs(point_1.x - point_2.x) + abs(point_1.y - point_2.y)
                                      ^^^^^^^^^
            AttributeError: 'NoneType' object has no attribute 'x'

            以前版本的解释器只会指向使对象不明确的那一行None。在处理深度嵌套的字典对象和多个函数调用时,这些增强的错误也很有帮助,

            Traceback (most recent call last):
            File "query.py", line 37, in <module>
              magic_arithmetic('foo')
              ^^^^^^^^^^^^^^^^^^^^^^^
            File "query.py", line 18, in magic_arithmetic
              return add_counts(x) / 25
                      ^^^^^^^^^^^^^
            File "query.py", line 24, in add_counts
              return 25 + query_user(user1) + query_user(user2)
                          ^^^^^^^^^^^^^^^^^
            File "query.py", line 32, in query_user
              return 1 + query_count(db, response['a']['b']['c']['user'], retry=True)
                                          ~~~~~~~~~~~~~~~~~~^^^^^
            TypeError: 'NoneType' object is not subscriptable

            以及复杂的算术表达式:

            Traceback (most recent call last):
            File "calculation.py", line 54, in <module>
              result = (x / y / z) * (a / b / c)
                        ~~~~~~^~~
            ZeroDivisionError: division by zero

            此功能需要将列位置存储在代码对象中,这可能会导致编译 Python 文件的磁盘使用量或解释器内存使用量略有增加。为了避免存储额外信息和/或停用打印额外回溯信息, 命令行标志或-X no_debug_rangesPYTHONNODEBUGRANGES 可以使用环境变量。

            代码对象的列信息

            增强回溯功能使用的信息作为通用 API 提供,可用于将字节码指令与源代码相关联。可以使用以下方法检索此信息:

            选项和环境变量 -X no_debug_rangesPYTHONNODEBUGRANGES可用于禁用此功能。

            PEP 657了解更多详情。(由 Pablo Galindo、Batuhan Taskaya 和 Ammar Askar 在bpo-43950中贡献。)

            异常可以用字符串丰富__note__

            该__note__字段已添加到BaseException. 默认情况None 下,但可以设置为添加到异常回溯的字符串。(由 Irit Katriel 在bpo-45607中贡献。)

            其他语言变化

            其他 CPython 实现更改

            • 特殊方法complex.__complex__()和bytes.__bytes__()实现支持typing.SupportsComplextyping.SupportsBytes协议。(由 Mark Dickinson 和 Dong-hee Na 在bpo-24234中贡献。)
            • siphash13被添加为新的内部散列算法。它具有类似的安全属性,siphash24但对于长输入来说它稍快一些。str,bytes和其他一些类型现在使用它作为hash().PEP 552 基于散列的 pyc 文件现在siphash13也使用 . (由 Inada Naoki 在bpo-29410中贡献。)
            • 当不带参数的语句重新引发活动异常时raise,附加到此异常的回溯现在始终为sys.exc_info()[1].__traceback__. 这意味着对当前except子句中的回溯所做的更改会反映在重新引发的异常中。(由 Irit Katriel 在bpo-45711中贡献。)
            • 解释器状态表示的已处理异常(又名 exc_info 或 _PyErr_StackItem)现在只有该exc_value字段,exc_type并且exc_traceback 已被删除,因为它们的值可以从exc_value. (由 Irit Katriel 在bpo-45711中贡献。)
            • 为 Windows 安装程序AppendPath添加了一个新的命令行选项。它的行为类似于PrependPath但附加了 install 和 scripts 目录,而不是前面。(由 Bastian Neuburger 在bpo-44934中贡献。)

            新模块

            改进的模块

            fractions

            • 支持PEP 515Fraction -从字符串初始化(由 Sergey B Kirpichev 在bpo-44258中贡献。)
            • Fraction现在实现一个__int__方法,以便检查通过。(由 Mark Dickinson 在bpo-44547中贡献。)isinstance(some_fraction, typing.SupportsInt)

            空闲和空闲库

            • 对.pyi文件应用语法高亮。(由 Alex Waygood 和 Terry Jan Reedy 在bpo-45447中贡献。)

            inspect

            math

            • math.exp2():返回 2 的 x 次方。(由 Gideon Mitchell 在bpo-45917中贡献。)
            • 添加math.cbrt():返回 x 的立方根。(由 Ajith Ramachandran 在bpo-44357中贡献。)
            • math.pow()为了与 IEEE 754 规范保持一致,更改了两个极端情况的行为。操作 ,现在返回 。以前他们提出了. (由 Mark Dickinson 在bpo-44339中贡献。)math.pow(0.0, -math.inf)``math.pow(-0.0, -math.inf)``inf ValueError

            operator

            • 添加了一个新功能operator.call,例如 . (由 Antony Lee 在bpo-44019中贡献。)operator.call(obj, *args, **kwargs) == obj(*args, **kwargs)

            os

            • 在 Windows 上,os.urandom()现在使用BCryptGenRandom(),而不是CryptGenRandom()已弃用。(由 Dong-hee Na 在bpo-44611中提供。)

            socket

            • 添加对 NetBSD 的 CAN Socket 支持。(由 Thomas Klausner 在bpo-30512中贡献。)

            sqlite3

            sys

            • sys.exc_info()现在从(异常实例)派生typeandtraceback字段value,因此当异常在处理过程中被修改时,更改会反映在对 . 的后续调用的结果中exc_info()。(由 Irit Katriel 在bpo-45711中贡献。)
            • 添加sys.exception()返回活动异常实例(相当于sys.exc_info()[1])。(由 Irit Katriel 在bpo-46328中贡献。)

            threading

            time

            • 在 Unix 上,time.sleep()现在使用clock_nanosleep()or nanosleep()函数(如果可用),其分辨率为 1 纳秒(10 -9秒),而不是使用select()其分辨率为 1 微秒(10 -6秒)。(由 Benjamin Szőke 和 Victor Stinner 在bpo-21302中贡献。)
            • 在 Windows 8.1 和更新版本上,time.sleep()现在使用基于高分辨率计时器的可等待计时器 ,其分辨率为 100 纳秒(10 -7秒)。以前,它的分辨率为 1 毫秒(10 -3秒)。(由 Benjamin Szőke、Dong-hee Na、Eryk Sun 和 Victor Stinner 在bpo-21302bpo-45429 中贡献。)

            unicodedata

            • Unicode 数据库已更新至版本 14.0.0。( bpo-45190 )。

            fcntl

            • 在 FreeBSD 上,F_DUP2FD和F_DUP2FD_CLOEXECflags 分别被支持,前者相当于dup2使用,后者FD_CLOEXEC额外设置了 flag。

            Optimizations

            • 编译器现在使用仅包含格式代码的文字格式优化简单的 C 样式格式%s,%r并%a使其与相应的 f 字符串表达式一样快。(由 Serhiy Storchaka 在bpo-28307中贡献。)
            • 实施“零成本”例外。try当不引发异常时,语句的成本几乎可以消除。(由 Mark Shannon 在bpo-40222中贡献。)
            • 由于避免创建绑定方法实例的字节码更改,现在使用关键字的方法调用更快。以前,此优化仅适用于具有纯位置参数的方法调用。(由 Ken Jin 和 Mark Shannon 在bpo-26110中贡献,基于 PyPy 中实现的想法。)
            • 纯 ASCII 字符串现在在常数时间内通过unicodedata.normalize(). (由 Dong-hee Na 在bpo-44987中提供。)
            • math函数comb()perm()现在对于大参数来说速度提高了 10 倍或更多(对于较大的k速度更快)。(由 Serhiy Storchaka 在bpo-37295中贡献。)
            • 当所有插入的键都是 Unicode 对象时,字典不存储哈希值。这减少了字典大小。例如,sys.getsizeof(dict.fromkeys("abcdefg")) 在 64 位平台上从 352 字节变为 272 字节。(由 Inada Naoki 在bpo-46845中贡献。)

            CPython 字节码更改

            • 用单个 实现替换了所有数字BINARY_*和指令。INPLACE_*BINARY_OP
            • 将三个调用指令:CALL_FUNCTION和 CALL_FUNCTION_KW替换CALL_METHOD为 PUSH_NULLPRECALLCALL KW_NAMES。这将方法的参数转移与关键字参数的处理分离,并允许更好地专门化调用。
            • 删除COPY_DICT_WITHOUT_KEYS和GEN_START。
            • MATCH_CLASS并且MATCH_KEYS不再推送一个额外的布尔值来指示匹配是成功还是失败。相反,它们指示失败 None (否则提取值的元组会出现)。
            • 用 new 和指令替换几个堆栈操作指令(DUP_TOP、DUP_TOP_TWO、 ROT_TWO、ROT_THREE、ROT_FOUR和) 。ROT_NCOPY SWAP
            • 添加POP_JUMP_IF_NOT_NONEPOP_JUMP_IF_NONE操作码以加速条件跳转。
            • JUMP_IF_NOT_EXC_MATCH不再弹出活动异常。

            Deprecated

            Removed

            • smtpd.MailmanProxy现在已删除,因为没有外部模块就无法使用mailman. (由 Dong-hee Na 在bpo-35800中提供。)
            • 该binhex模块在 Python 3.9 中已弃用,现在已删除。在 Python 3.9 中不推荐使用的以下binascii函数现在也被删除:a2b_hqx(), b2a_hqx();rlecode_hqx(), rledecode_hqx().该binascii.crc_hqx()功能仍然可用。(由 Victor Stinner 在bpo-45085中贡献。)
            • bdist_msi在 Python 3.9 中不推荐使用的 distutils命令现在已被删除。改用bdist_wheel(车轮包)。(由 Hugo van Kemenade 在bpo-45124中贡献。)
            • 由于重大的安全问题, Python 3.9 中禁用的 的reuse_address参数 asyncio.loop.create_datagram_endpoint()现在已完全删除。这是因为 SO_REUSEADDRUDP 中套接字选项的行为。(由 Hugo van Kemenade 在bpo-45129中贡献。)
            • 自Python 3.9 起已不推荐使用和 的__getitem__()方法 。(由 Hugo van Kemenade 在bpo-45132中贡献。)xml.dom.pulldom.DOMEventStreamwsgiref.util.FileWrapperfileinput.FileInput
            • gettext 模块中删除了以下不推荐使用的函数和方法:lgettext()、ldgettext()和 。lngettext()``ldngettext()Function bind_textdomain_codeset()、 methods output_charset()和 set_output_charset()以及函数的codeset 参数translation()and install() 也被删除,因为它们仅用于l*gettext()函数。(由 Dong-hee Na 和 Serhiy Storchaka 在bpo-44235中贡献。)
            • 使基于生成器的旧协程与 async/await 代码兼容的@asyncio.coroutine 装饰器。该函数自 Python 3.8 起已被弃用,最初计划在 Python 3.10 中删除。改为使用。(由 Illia Volochii 在bpo-43216中贡献。) async def
            • asyncio.coroutines.CoroWrapper用于在调试模式下包装遗留的基于生成器的协程对象。(由 Illia Volochii 在bpo-43216中贡献。)
            • 删除了已弃用split()的_tkinter.TkappType. (由 Erlend E. Aasland 在bpo-38371中贡献。)
            • inspect模块中删除:该getargspec函数,自 Python 3.0 起已弃用;使用inspect.signature()orinspect.getfullargspec()代替。该formatargspec函数,自 Python 3.5 起已弃用;直接使用inspect.signature()函数和Signature对象。自 Python 3.5 起已弃用的未记录Signature.from_builtin和Signature.from_function 函数;改用该 Signature.from_callable()方法。(由 Hugo van Kemenade 在bpo-45320中贡献。)
            • 从 unittest 发现中删除命名空间包支持。它是在 Python 3.4 中引入的,但自 Python 3.7 以来已被破坏。(由 Inada Naoki 在bpo-23882中贡献。)
            • 从 中删除__class_getitem__方法pathlib.PurePath,因为在以前的版本中没有使用和错误添加。(由 Nikita Sobolev 在bpo-46483中贡献。)
            • 删除未记录的私有方法,以前在 Python 3.7 中float.__set_format__()称为。float.__setformat__()它的文档字符串说:“你可能不想使用这个函数。它的存在主要是为了在 Python 的测试套件中使用。” (由 Victor Stinner 在bpo-46852中贡献。)

            移植到 Python 3.11

            本节列出了之前描述的更改和其他可能需要更改代码的错误修正。

            Python API 的变化

            构建更改

            • 构建 Python 现在需要一个没有可选 C11 功能的 C11 编译器。(由 Victor Stinner 在bpo-46656中贡献。)
            • 现在可以使用 ThinLTO 选项通过--with-lto=thin. (由 Dong-hee Na 和 Brett Holman 在bpo-44340中贡献。)
            • libpython 不再与 libcrypt 链接。(由 Mike Gilbert 在bpo-45433中贡献。)
            • 构建 Python 现在需要一个<math.h>提供以下函数的 C99 头文件:copysign(), hypot(), isfinite(), isinf(), isnan(), round(). (由 Victor Stinner 在bpo-45440中贡献。)
            • 构建 Python 现在需要一个<math.h>提供NAN常量或__builtin_nan()内置函数的 C99 头文件。(由 Victor Stinner 在bpo-46640中贡献。)
            • 构建 Python 现在需要支持浮点非数字 (NaN):删除Py_NO_NAN宏。(由 Victor Stinner 在bpo-46656中贡献。)
            • 现在可以禁用对象结构的空闲列表。一个新的配置 选项--without-freelists可用于禁用除空元组单例之外的所有空闲列表。(由 Christian Heimes 在bpo-45522中贡献)
            • Modules/Setup并Modules/makesetup进行了改进和捆绑。扩展模块现在可以通过makesetup. 除了一些测试模块之外的所有模块都可以静态链接到主二进制文件或库中。(由 Brett Cannon 和 Christian Heimes 在bpo-45548bpo-45570bpo-45571bpo-43974 中贡献。)
            • configure现在可以检测大多数 stdlib 扩展模块的构建依赖项、编译器标志和链接器标志。libffi、libnsl、libsqlite3、zlib、bzip2、liblzma、libcrypt 和 uuid 标志由 pkg-config(如果可用)检测。(由 Christian Heimes 和 Erlend Egeberg Aasland 在 bpo-bpo-45847bpo-45747bpo-45763 中贡献。)
            • CPython 现在有对交叉编译到 WebAssembly 平台的实验性支持wasm32-emscripten。这项工作受到了 Pyodide 等先前工作的启发。(由 Christian Heimes 和 Ethan Smith 在bpo-40280中贡献。)
            • CPython 现在将默认使用 30 位数字来int 实现 Python。以前,默认是在带有 的平台上使用 30 位数字,否则使用 15 位数字。仍然可以通过配置脚本的选项或(对于 Windows)中的 变量显式请求使用 15 位数字 ,但将来可能会删除此选项。(由 Mark Dickinson 在 bpo-45569中贡献。)SIZEOF_VOID_P >= 8``--enable-big-digits``PYLONG_BITS_IN_DIGIT``PC/pyconfig.h

            C API

            • PyErr_SetExcInfo()不再使用typeand参数,解释器现在从异常实例(参数)traceback 派生这些值。value该函数仍然窃取所有三个参数的引用。(由 Irit Katriel 在 bpo-45711中贡献。)
            • PyErr_GetExcInfo()现在 从异常实例(字段)派生结果的type和字段。(由 Irit Katriel 在bpo-45711中贡献。)traceback``value
            • _frozen有一个新is_package字段来指示冻结的模块是否是一个包。以前,该字段中的负值size是指标。现在只有非负值用于size. (由 Kumar Aditya 在bpo-46608中贡献。)

            新功能



              在 Python3 中正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。

              Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式。

              re 模块使 Python 语言拥有全部的正则表达式功能。

              compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。

              re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数。

              本章节主要介绍 Python 中常用的正则表达式处理函数。


              re.match 函数

              re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match() 就返回 none。

              函数语法

              re.match(pattern, string, flags=0)

              函数参数说明:

              参数描述
              pattern匹配的正则表达式
              string要匹配的字符串。
              flags标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

              匹配成功 re.match 方法返回一个匹配的对象,否则返回 None。

              我们可以使用 group(num) 或 groups() 匹配对象函数来获取匹配表达式。

              匹配对象方法描述
              group(num=0)匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。
              groups()返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。

              实例 1:

              #!/usr/bin/pythonimport reprint(re.match('www', 'www.51coolma.cn').span())  # 在起始位置匹配print(re.match('cn', 'www.51coolma.cn'))         # 不在起始位置匹配

              以上实例运行输出结果为:

              (0, 3)None

              实例 2:

              #!/usr/bin/python3import reline = "Cats are smarter than dogs"matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I)if matchObj:    print ("matchObj.group() : ", matchObj.group())    print ("matchObj.group(1) : ", matchObj.group(1))    print ("matchObj.group(2) : ", matchObj.group(2))else:    print ("No match!!")

              以上实例执行结果如下:

              matchObj.group() :  Cats are smarter than dogsmatchObj.group(1) :  CatsmatchObj.group(2) :  smarter

              re.search 方法

              re.search 扫描整个字符串并返回第一个成功的匹配。

              函数语法:

              re.search(pattern, string, flags=0)

              函数参数说明:

              参数描述
              pattern匹配的正则表达式
              string要匹配的字符串。
              flags标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

              匹配成功 re.search 方法返回一个匹配的对象,否则返回 None。

              我们可以使用 group(num) 或 groups() 匹配对象函数来获取匹配表达式。

              匹配对象方法描述
              group(num=0)匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。
              groups()返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。

              实例 1:

              #!/usr/bin/python3import reprint(re.search('www', 'www.51coolma.cn').span())  # 在起始位置匹配print(re.search('cn', 'www.51coolma.cn').span())         # 不在起始位置匹配

              以上实例运行输出结果为:

              (0, 3)(14, 16)

              实例 2:

              #!/usr/bin/python3import reline = "Cats are smarter than dogs";searchObj = re.search( r'(.*) are (.*?) .*', line, re.M|re.I)if searchObj:    print ("searchObj.group() : ", searchObj.group())    print ("searchObj.group(1) : ", searchObj.group(1))    print ("searchObj.group(2) : ", searchObj.group(2))else:    print ("Nothing found!!")

              以上实例执行结果如下:

              searchObj.group() :  Cats are smarter than dogssearchObj.group(1) :  CatssearchObj.group(2) :  smarter

              re.match 与 re.search 的区别

              re.match 只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回 None;而 re.search 匹配整个字符串,直到找到一个匹配。

              实例:

              #!/usr/bin/python3import reline = "Cats are smarter than dogs";matchObj = re.match( r'dogs', line, re.M|re.I)if matchObj:    print ("match --> matchObj.group() : ", matchObj.group())else:    print ("No match!!")matchObj = re.search( r'dogs', line, re.M|re.I)if matchObj:    print ("search --> matchObj.group() : ", matchObj.group())else:    print ("No match!!")

              以上实例运行结果如下:

              No match!!search --> matchObj.group() :  dogs

              检索和替换

              Python 的 re 模块提供了 re.sub 用于替换字符串中的匹配项。

              语法:

              re.sub(pattern, repl, string, max=0)

              返回的字符串是在字符串中用 re 最左边不重复的匹配来替换。如果模式没有发现,字符将被没有改变地返回。

              可选参数 count 是模式匹配后替换的最大次数;count 必须是非负整数。缺省值是 0 表示替换所有的匹配。

              实例:

              #!/usr/bin/python3import rephone = "2004-959-559 # 这是一个电话号码"# 删除注释num = re.sub(r'#.*$', "", phone)print ("电话号码 : ", num)# 移除非数字的内容num = re.sub(r'D', "", phone)print ("电话号码 : ", num)

              以上实例执行结果如下:

              电话号码 :  2004-959-559 电话号码 :  2004959559

              正则表达式修饰符 - 可选标志

              正则表达式可以包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标志。多个标志可以通过按位 or(|) 它们来指定。如 re.L | re.M 被设置成 L 和 M 标志:

              修饰符描述
              re.I使匹配对大小写不敏感
              re.L做本地化识别(locale-aware)匹配
              re.M多行匹配,影响 ^ 和 $
              re.S使 . 匹配包括换行在内的所有字符
              re.U根据Unicode字符集解析字符。这个标志影响 w, W, , B.
              re.X该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。

              正则表达式模式

              模式字符串使用特殊的语法来表示一个正则表达式:

              字母和数字表示他们自身。一个正则表达式模式中的字母和数字匹配同样的字符串。

              多数字母和数字前加一个反斜杠时会拥有不同的含义。

              标点符号只有被转义时才匹配自身,否则它们表示特殊的含义。

              反斜杠本身需要使用反斜杠转义。

              由于正则表达式通常都包含反斜杠,所以你最好使用原始字符串来表示它们。模式元素(如 r'/t',等价于'//t')匹配相应的特殊字符。

              下表列出了正则表达式模式语法中的特殊元素。如果你使用模式的同时提供了可选的标志参数,某些模式元素的含义会改变。

              模式描述
              ^匹配字符串的开头
              $匹配字符串的末尾。
              .匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。
              [...]用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k'
              [^...]不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。
              re*匹配0个或多个的表达式。
              re+匹配1个或多个的表达式。
              re?匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式
              re{ n}匹配n个前面表达式。例如,"o{2}"不能匹配"Bob"中的"o",但是能匹配"food"中的两个o。
              re{ n,}精确匹配n个前面表达式。例如,"o{2,}"不能匹配"Bob"中的"o",但能匹配"foooood"中的所有o。"o{1,}"等价于"o+"。"o{0,}"则等价于"o*"。
              re{ n, m}匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式
              a| b匹配a或b
              (re)G匹配括号内的表达式,也表示一个组
              (?imx)正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。
              (?-imx)正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。
              (?: re)类似 (...), 但是不表示一个组
              (?imx: re)在括号中使用i, m, 或 x 可选标志
              (?-imx: re)在括号中不使用i, m, 或 x 可选标志
              (?#...)注释.
              (?= re)前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。
              (?! re)前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功
              (?> re)匹配的独立模式,省去回溯。
              w匹配字母数字
              W匹配非字母数字
              s匹配任意空白字符,等价于 [ f].
              S匹配任意非空字符
              d匹配任意数字,等价于 [0-9].
              D匹配任意非数字
              A匹配字符串开始
              匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。c
              z匹配字符串结束
              G匹配最后匹配完成的位置。
              匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
              B匹配非单词边界。'erB' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
              , , 等.匹配一个换行符。匹配一个制表符。等
              1...9匹配第n个分组的子表达式。
              10匹配第n个分组的子表达式,如果它经匹配。否则指的是八进制字符码的表达式。

              正则表达式实例

              字符匹配

              实例描述
              python匹配 "python".

              字符类

              实例描述
              [Pp]ython匹配 "Python" 或 "python"
              rub[ye]匹配 "ruby" 或 "rube"
              [aeiou]匹配中括号内的任意一个字母
              [0-9]匹配任何数字。类似于 [0123456789]
              [a-z]匹配任何小写字母
              [A-Z]匹配任何大写字母
              [a-zA-Z0-9]匹配任何字母及数字
              [^aeiou]除了aeiou字母以外的所有字符
              [^0-9]匹配除了数字外的字符

              特殊字符类

              实例描述
              .匹配除 " " 之外的任何单个字符。要匹配包括 ' ' 在内的任何字符,请使用象 '[. ]' 的模式。
              d匹配一个数字字符。等价于 [0-9]。
              D匹配一个非数字字符。等价于 [^0-9]。
              s匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ f v]。
              S匹配任何非空白字符。等价于 [^ f v]。
              w匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。
              W匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。


              本文我们为大家介绍 Python3 使用 PyMySQL 连接数据库,并实现简单的增删改查。

              什么是 PyMySQL?

              PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库,Python2 中则使用mysqldb。

              PyMySQL 遵循 Python 数据库 API v2.0 规范,并包含了 pure-Python MySQL 客户端库。


              PyMySQL 安装

              在使用 PyMySQL 之前,我们需要确保 PyMySQL 已安装。

              PyMySQL 下载地址:https://github.com/PyMySQL/PyMySQL。

              如果还未安装,我们可以使用以下命令安装最新版的 PyMySQL:

              $ pip install PyMySQL

              如果你的系统不支持 pip 命令,可以使用以下方式安装:

              1、使用 git 命令下载安装包安装(你也可以手动下载):

              $ git clone https://github.com/PyMySQL/PyMySQL$ cd PyMySQL/$ python3 setup.py install

              2、如果需要制定版本号,可以使用 curl 命令来安装:

              $ # X.X 为 PyMySQL 的版本号$ curl -L https://github.com/PyMySQL/PyMySQL/tarball/pymysql-X.X | tar xz$ cd PyMySQL*$ python3 setup.py install$ # 现在你可以删除 PyMySQL* 目录

              注意:请确保您有 root 权限来安装上述模块。

              安装的过程中可能会出现"ImportError: No module named setuptools"的错误提示,意思是你没有安装setuptools,你可以访问https://pypi.python.org/pypi/setuptools 找到各个系统的安装方法。

              Linux 系统安装实例:

              $ wget https://bootstrap.pypa.io/ez_setup.py$ python3 ez_setup.py

              数据库连接

              连接数据库前,请先确认以下事项:

              • 您已经创建了数据库 TESTDB.
              • 在 TESTDB 数据库中您已经创建了表 EMPLOYEE
              • EMPLOYEE 表字段为 FIRST_NAME, LAST_NAME, AGE, SEX 和 INCOME。
              • 连接数据库 TESTDB 使用的用户名为 "testuser" ,密码为 "test123",你可以可以自己设定或者直接使用 root 用户名及其密码,Mysql 数据库用户授权请使用 Grant 命令。
              • 在你的机子上已经安装了 Python MySQLdb 模块。
              • 如果您对 sql 语句不熟悉,可以访问我们的 SQL教程

              实例:

              以下实例链接 Mysql 的 TESTDB 数据库:

              #!/usr/bin/python3import pymysql# 打开数据库连接db = pymysql.connect("localhost","testuser","test123","TESTDB" )# 使用 cursor() 方法创建一个游标对象 cursorcursor = db.cursor()# 使用 execute()  方法执行 SQL 查询 cursor.execute("SELECT VERSION()")# 使用 fetchone() 方法获取单条数据.data = cursor.fetchone()print ("Database version : %s " % data)# 关闭数据库连接db.close()

              执行以上脚本输出结果如下:

              Database version : 5.5.20-log

              创建数据库表

              如果数据库连接存在我们可以使用 execute() 方法来为数据库创建表,如下所示创建表EMPLOYEE:

              #!/usr/bin/python3import pymysql# 打开数据库连接db = pymysql.connect("localhost","testuser","test123","TESTDB" )# 使用 cursor() 方法创建一个游标对象 cursorcursor = db.cursor()# 使用 execute() 方法执行 SQL,如果表存在则删除cursor.execute("DROP TABLE IF EXISTS EMPLOYEE")# 使用预处理语句创建表sql = """CREATE TABLE EMPLOYEE (         FIRST_NAME  CHAR(20) NOT NULL,         LAST_NAME  CHAR(20),         AGE INT,           SEX CHAR(1),         INCOME FLOAT )"""cursor.execute(sql)# 关闭数据库连接db.close()

              数据库插入操作

              以下实例使用执行 SQL INSERT 语句向表 EMPLOYEE 插入记录:

              #!/usr/bin/python3import pymysql# 打开数据库连接db = pymysql.connect("localhost","testuser","test123","TESTDB" )# 使用cursor()方法获取操作游标 cursor = db.cursor()# SQL 插入语句sql = """INSERT INTO EMPLOYEE(FIRST_NAME,         LAST_NAME, AGE, SEX, INCOME)         VALUES ('Mac', 'Mohan', 20, 'M', 2000)"""try:   # 执行sql语句   cursor.execute(sql)   # 提交到数据库执行   db.commit()except:   # 如果发生错误则回滚   db.rollback()# 关闭数据库连接db.close()

              以上例子也可以写成如下形式:

              #!/usr/bin/python3import pymysql# 打开数据库连接db = pymysql.connect("localhost","testuser","test123","TESTDB" )# 使用cursor()方法获取操作游标 cursor = db.cursor()# SQL 插入语句sql = "INSERT INTO EMPLOYEE(FIRST_NAME,        LAST_NAME, AGE, SEX, INCOME)        VALUES ('%s', '%s', '%d', '%c', '%d' )" %        ('Mac', 'Mohan', 20, 'M', 2000)try:   # 执行sql语句   cursor.execute(sql)   # 执行sql语句   db.commit()except:   # 发生错误时回滚   db.rollback()# 关闭数据库连接db.close()

              以下代码使用变量向 SQL 语句中传递参数:

              ..................................user_id = "test123"password = "password"con.execute('insert into Login values("%s", "%s")' %              (user_id, password))..................................

              数据库查询操作

              Python 查询 Mysql 使用 fetchone() 方法获取单条数据, 使用 fetchall() 方法获取多条数据。

              • fetchone(): 该方法获取下一个查询结果集。结果集是一个对象
              • fetchall(): 接收全部的返回结果行.
              • rowcount: 这是一个只读属性,并返回执行 execute() 方法后影响的行数。

              实例:

              查询 EMPLOYEE 表中 salary(工资)字段大于 1000 的所有数据:

              #!/usr/bin/python3import pymysql# 打开数据库连接db = pymysql.connect("localhost","testuser","test123","TESTDB" )# 使用cursor()方法获取操作游标 cursor = db.cursor()# SQL 查询语句sql = "SELECT * FROM EMPLOYEE        WHERE INCOME > '%d'" % (1000)try:   # 执行SQL语句   cursor.execute(sql)   # 获取所有记录列表   results = cursor.fetchall()   for row in results:      fname = row[0]      lname = row[1]      age = row[2]      sex = row[3]      income = row[4]       # 打印结果      print ("fname=%s,lname=%s,age=%d,sex=%s,income=%d" %              (fname, lname, age, sex, income ))except:   print ("Error: unable to fecth data")# 关闭数据库连接db.close()

              以上脚本执行结果如下:

              fname=Mac, lname=Mohan, age=20, sex=M, income=2000

              数据库更新操作

              更新操作用于更新数据表的的数据,以下实例将 TESTDB 表中的 SEX 字段全部修改为 'M',AGE 字段递增 1:

              #!/usr/bin/python3import pymysql# 打开数据库连接db = pymysql.connect("localhost","testuser","test123","TESTDB" )# 使用cursor()方法获取操作游标 cursor = db.cursor()# SQL 更新语句sql = "UPDATE EMPLOYEE SET AGE = AGE + 1                          WHERE SEX = '%c'" % ('M')try:   # 执行SQL语句   cursor.execute(sql)   # 提交到数据库执行   db.commit()except:   # 发生错误时回滚   db.rollback()# 关闭数据库连接db.close()

              删除操作

              删除操作用于删除数据表中的数据,以下实例演示了删除数据表 EMPLOYEE 中 AGE 大于 20 的所有数据:

              #!/usr/bin/python3import pymysql# 打开数据库连接db = pymysql.connect("localhost","testuser","test123","TESTDB" )# 使用cursor()方法获取操作游标 cursor = db.cursor()# SQL 删除语句sql = "DELETE FROM EMPLOYEE WHERE AGE > '%d'" % (20)try:   # 执行SQL语句   cursor.execute(sql)   # 提交修改   db.commit()except:   # 发生错误时回滚   db.rollback()# 关闭连接db.close()

              执行事务

              事务机制可以确保数据一致性。

              事务应该具有 4 个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为 ACID 特性。

              • 原子性(atomicity)。一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。
              • 一致性(consistency)。事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
              • 隔离性(isolation)。一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
              • 持久性(durability)。持续性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

              Python DB API 2.0 的事务提供了两个方法 commit 或 rollback。

              实例

              # SQL删除记录语句sql = "DELETE FROM EMPLOYEE WHERE AGE > '%d'" % (20)try:   # 执行SQL语句   cursor.execute(sql)   # 向数据库提交   db.commit()except:   # 发生错误时回滚   db.rollback()

              对于支持事务的数据库, 在 Python 数据库编程中,当游标建立之时,就自动开始了一个隐形的数据库事务。

              commit() 方法游标的所有更新操作,rollback()方法回滚当前游标的所有操作。每一个方法都开始了一个新的事务。


              错误处理

              DB API 中定义了一些数据库操作的错误及异常,下表列出了这些错误和异常:

              异常描述
              Warning当有严重警告时触发,例如插入数据是被截断等等。必须是 StandardError 的子类。
              Error警告以外所有其他错误类。必须是 StandardError 的子类。
              InterfaceError当有数据库接口模块本身的错误(而不是数据库的错误)发生时触发。 必须是 Error 的子类。
              DatabaseError和数据库有关的错误发生时触发。 必须是 Error 的子类。
              DataError当有数据处理时的错误发生时触发,例如:除零错误,数据超范围等等。 必须是 DatabaseError 的子类。
              OperationalError指非用户控制的,而是操作数据库时发生的错误。例如:连接意外断开、 数据库名未找到、事务处理失败、内存分配错误等等操作数据库是发生的错误。 必须是 DatabaseError 的子类。
              IntegrityError完整性相关的错误,例如外键检查失败等。必须是 DatabaseError 子类。
              InternalError数据库的内部错误,例如游标(cursor)失效了、事务同步失败等等。 必须是 DatabaseError 子类。
              ProgrammingError程序错误,例如数据表(table)没找到或已存在、SQL 语句语法错误、 参数数量错误等等。必须是 DatabaseError 的子类。
              NotSupportedError不支持错误,指使用了数据库不支持的函数或API等。例如在连接对象上 使用 .rollback() 函数,然而数据库并不支持事务或者事务已关闭。 必须是 DatabaseError 的子类。


              Python 提供了两个级别访问的网络服务。:

              • 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统 Socket 接口的全部方法。
              • 高级别的网络服务模块 SocketServer, 它提供了服务器中心类,可以简化网络服务器的开发。

              什么是 Socket?

              Socket 又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。


              socket()函数

              Python 中,我们用 socket()函数来创建套接字,语法格式如下:

              socket.socket([family[, type[, proto]]])

              参数

              • family: 套接字家族可以使 AF_UNIX 或者 AF_INET
              • type: 套接字类型可以根据是面向连接的还是非连接分为SOCK_STREAMSOCK_DGRAM
              • protocol: 一般不填默认为0.

              Socket 对象(内建)方法

              函数描述
              服务器端套接字
              s.bind()绑定地址(host,port)到套接字, 在 AF_INET 下,以元组(host,port)的形式表示地址。
              s.listen()开始 TCP 监听。backlog 指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为 1,大部分应用程序设为 5 就可以了。
              s.accept()被动接受 TCP 客户端连接,(阻塞式)等待连接的到来
              客户端套接字
              s.connect()主动初始化 TCP 服务器连接,。一般 address 的格式为元组(hostname,port),如果连接出错,返回 socket.error 错误。
              s.connect_ex()connect() 函数的扩展版本,出错时返回出错码,而不是抛出异常
              公共用途的套接字函数
              s.recv()接收 TCP 数据,数据以字符串形式返回,bufsize指定要接收的最大数据量。flag 提供有关消息的其他信息,通常可以忽略。
              s.send()发送 TCP 数据,将 string 中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于 string 的字节大小。
              s.sendall()完整发送 TCP 数据,完整发送 TCP 数据。将 string 中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回 None,失败则抛出异常。
              s.recvfrom()接收 UDP 数据,与 recv() 类似,但返回值是(data,address)。其中 data 是包含接收数据的字符串,address 是发送数据的套接字地址。
              s.sendto()发送 UDP 数据,将数据发送到套接字,address 是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。
              s.close()关闭套接字
              s.getpeername()返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。
              s.getsockname()返回套接字自己的地址。通常是一个元组(ipaddr,port)
              s.setsockopt(level,optname,value)设置给定套接字选项的值。
              s.getsockopt(level,optname[.buflen])返回套接字选项的值。
              s.settimeout(timeout)设置套接字操作的超时期,timeout 是一个浮点数,单位是秒。值为 None 表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如 connect())
              s.gettimeout()返回当前超时期的值,单位是秒,如果没有设置超时期,则返回 None。
              s.fileno()返回套接字的文件描述符。
              s.setblocking(flag)如果 flag 为 0,则将套接字设为非阻塞模式,否则将套接字设为阻塞模式(默认值)。非阻塞模式下,如果调用 recv() 没有发现任何数据,或 send() 调用无法立即发送数据,那么将引起 socket.error 异常。
              s.makefile()创建一个与该套接字相关连的文件

              简单实例

              服务端

              我们使用 socket 模块的 socket 函数来创建一个 socket 对象。socket 对象可以通过调用其他函数来设置一个 socket 服务。

              现在我们可以通过调用 bind(hostname, port) 函数来指定服务的 port(端口)

              接着,我们调用 socket 对象的 accept 方法。该方法等待客户端的连接,并返回 connection 对象,表示已连接到客户端。

              完整代码如下:

              #!/usr/bin/python3# 文件名:server.py# 导入 socket、sys 模块import socketimport sys# 创建 socket 对象serversocket = socket.socket(            socket.AF_INET, socket.SOCK_STREAM) # 获取本地主机名host = socket.gethostname()port = 9999# 绑定端口serversocket.bind((host, port))# 设置最大连接数,超过后排队serversocket.listen(5)while True:    # 建立客户端连接    clientsocket,addr = serversocket.accept()          print("连接地址: %s" % str(addr))        msg='欢迎访问W3Cschool教程!'+ "
              "    clientsocket.send(msg.encode('utf-8'))    clientsocket.close()

              客户端

              接下来我们写一个简单的客户端实例连接到以上创建的服务。端口号为 12345。

              socket.connect(hosname, port ) 方法打开一个 TCP 连接到主机为 hostname 端口为 port 的服务商。连接后我们就可以从服务端后期数据,记住,操作完成后需要关闭连接。

              完整代码如下:

              #!/usr/bin/python3# 文件名:client.py# 导入 socket、sys 模块import socketimport sys# 创建 socket 对象s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 获取本地主机名host = socket.gethostname() # 设置端口好port = 9999# 连接服务,指定主机和端口s.connect((host, port))# 接收小于 1024 字节的数据msg = s.recv(1024)s.close()print (msg.decode('utf-8'))

              现在我们打开连个终端,第一个终端执行 server.py 文件:

              $ python3 server.py

              第二个终端执行 client.py 文件:

              $ python3 client.py 欢迎访问W3Cschool教程!

              这是我们再打开第一个终端,就会看到有以下信息输出:

              连接地址: ('192.168.0.118', 33397)

              Python Internet 模块

              以下列出了 Python 网络编程的一些重要模块:

              协议功能用处端口号Python 模块
              HTTP网页访问80httplib, urllib, xmlrpclib
              NNTP阅读和张贴新闻文章,俗称为"帖子"119nntplib
              FTP文件传输20ftplib, urllib
              SMTP发送邮件25smtplib
              POP3接收邮件110poplib
              IMAP4获取邮件143imaplib
              Telnet命令行23telnetlib
              Gopher信息查找70gopherlib, urllib

              更多内容可以参阅官网的 Python Socket Library and Modules

              在Python3 中应用的SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。

              python的 smtplib 提供了一种很方便的途径发送电子邮件。它对 smtp 协议进行了简单的封装。

              Python创建 SMTP 对象语法如下:

              import smtplibsmtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] )

              参数说明:

              • host: SMTP 服务器主机。 你可以指定主机的 ip 地址或者域名如:51coolma.cn,这个是可选参数。
              • port: 如果你提供了 host 参数, 你需要指定 SMTP 服务使用的端口号,一般情况下 SMTP 端口号为 25。
              • local_hostname: 如果 SMTP 在你的本机上,你只需要指定服务器地址为 localhost 即可。

              Python SMTP 对象使用 sendmail 方法发送邮件,语法如下:

              SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options]

              参数说明:

              • from_addr: 邮件发送者地址。
              • to_addrs: 字符串列表,邮件发送地址。
              • msg: 发送消息

              这里要注意一下第三个参数,msg 是字符串,表示邮件。我们知道邮件一般由标题,发信人,收件人,邮件内容,附件等构成,发送邮件的时候,要注意 msg 的格式。这个格式就是 smtp 协议中定义的格式。

              实例

              以下是一个使用 Python 发送邮件简单的实例:

              #!/usr/bin/python3import smtplibfrom email.mime.text import MIMETextfrom email.header import Headersender = 'from@51coolma.cn'receivers = ['429240967@qq.com']  # 接收邮件,可设置为你的QQ邮箱或者其他邮箱# 三个参数:第一个为文本内容,第二个 plain 设置文本格式,第三个 utf-8 设置编码message = MIMEText('Python 邮件发送测试...', 'plain', 'utf-8')message['From'] = Header("W3Cschool教程", 'utf-8')message['To'] =  Header("测试", 'utf-8')subject = 'Python SMTP 邮件测试'message['Subject'] = Header(subject, 'utf-8')try:    smtpObj = smtplib.SMTP('localhost')    smtpObj.sendmail(sender, receivers, message.as_string())    print ("邮件发送成功")except smtplib.SMTPException:    print ("Error: 无法发送邮件")

              我们使用三个引号来设置邮件信息,标准邮件需要三个头部信息: From, To, 和 Subject ,每个信息直接使用空行分割。

              我们通过实例化 smtplib 模块的 SMTP 对象 smtpObj 来连接到 SMTP 访问,并使用 sendmail 方法来发送信息。

              执行以上程序,如果你本机安装 sendmail,就会输出:

              $ python3 test.py 邮件发送成功

              查看我们的收件箱(一般在垃圾箱),就可以查看到邮件信息:

              运行结果

              如果我们本机没有 sendmail 访问,也可以使用其他服务商的 SMTP 访问(QQ、网易、Google等)。

              #!/usr/bin/python3import smtplibfrom email.mime.text import MIMETextfrom email.header import Header# 第三方 SMTP 服务mail_host="smtp.XXX.com"  #设置服务器mail_user="XXXX"    #用户名mail_pass="XXXXXX"   #口令 sender = 'from@51coolma.cn'receivers = ['429240967@qq.com']  # 接收邮件,可设置为你的QQ邮箱或者其他邮箱message = MIMEText('Python 邮件发送测试...', 'plain', 'utf-8')message['From'] = Header("W3Cschool教程", 'utf-8')message['To'] =  Header("测试", 'utf-8')subject = 'Python SMTP 邮件测试'message['Subject'] = Header(subject, 'utf-8')try:    smtpObj = smtplib.SMTP()     smtpObj.connect(mail_host, 25)    # 25 为 SMTP 端口号    smtpObj.login(mail_user,mail_pass)    smtpObj.sendmail(sender, receivers, message.as_string())    print ("邮件发送成功")except smtplib.SMTPException:    print ("Error: 无法发送邮件")

              使用Python发送HTML格式的邮件

              Python 发送 HTML 格式的邮件与发送纯文本消息的邮件不同之处就是将 MIMEText 中 _subtype 设置为 html。具体代码如下:

              #!/usr/bin/python3import smtplibfrom email.mime.text import MIMETextfrom email.header import Headersender = 'from@51coolma.cn'receivers = ['429240967@qq.com']  # 接收邮件,可设置为你的QQ邮箱或者其他邮箱mail_msg = """<p>Python 邮件发送测试...</p><p><a href="http://www.51coolma.cn">这是一个链接</a></p>"""message = MIMEText(mail_msg, 'html', 'utf-8')message['From'] = Header("W3Cschool教程", 'utf-8')message['To'] =  Header("测试", 'utf-8')subject = 'Python SMTP 邮件测试'message['Subject'] = Header(subject, 'utf-8')try:    smtpObj = smtplib.SMTP('localhost')    smtpObj.sendmail(sender, receivers, message.as_string())    print ("邮件发送成功")except smtplib.SMTPException:    print ("Error: 无法发送邮件")

              执行以上程序,如果你本机安装 sendmail,就会输出:

              $ python3 test.py 邮件发送成功

              查看我们的收件箱(一般在垃圾箱),就可以查看到邮件信息:

              运行结果


              Python 发送带附件的邮件

              发送带附件的邮件,首先要创建 MIMEMultipart() 实例,然后构造附件,如果有多个附件,可依次构造,最后利用 smtplib.smtp 发送。

              #!/usr/bin/python3import smtplibfrom email.mime.text import MIMETextfrom email.mime.multipart import MIMEMultipartfrom email.header import Headersender = 'from@51coolma.cn'receivers = ['429240967@qq.com']  # 接收邮件,可设置为你的QQ邮箱或者其他邮箱#创建一个带附件的实例message = MIMEMultipart()message['From'] = Header("W3Cschool教程", 'utf-8')message['To'] =  Header("测试", 'utf-8')subject = 'Python SMTP 邮件测试'message['Subject'] = Header(subject, 'utf-8')#邮件正文内容message.attach(MIMEText('这是W3Cschool教程Python 邮件发送测试……', 'plain', 'utf-8'))# 构造附件1,传送当前目录下的 test.txt 文件att1 = MIMEText(open('test.txt', 'rb').read(), 'base64', 'utf-8')att1["Content-Type"] = 'application/octet-stream'# 这里的filename可以任意写,写什么名字,邮件中显示什么名字att1["Content-Disposition"] = 'attachment; filename="test.txt"'message.attach(att1)# 构造附件2,传送当前目录下的 51coolma.txt 文件att2 = MIMEText(open('51coolma.txt', 'rb').read(), 'base64', 'utf-8')att2["Content-Type"] = 'application/octet-stream'att2["Content-Disposition"] = 'attachment; filename="51coolma.txt"'message.attach(att2)try:    smtpObj = smtplib.SMTP('localhost')    smtpObj.sendmail(sender, receivers, message.as_string())    print ("邮件发送成功")except smtplib.SMTPException:    print ("Error: 无法发送邮件")
              $ python3 test.py 邮件发送成功

              查看我们的收件箱(一般在垃圾箱),就可以查看到邮件信息:



              在 HTML 文本中添加图片

              邮件的 HTML 文本中一般邮件服务商添加外链是无效的,正确添加图片的实例如下所示:

              #!/usr/bin/python3import smtplibfrom email.mime.image import MIMEImagefrom email.mime.multipart import MIMEMultipartfrom email.mime.text import MIMETextfrom email.header import Headersender = 'from@51coolma.cn'receivers = ['429240967@qq.com']  # 接收邮件,可设置为你的QQ邮箱或者其他邮箱msgRoot = MIMEMultipart('related')msgRoot['From'] = Header("W3Cschool教程", 'utf-8')msgRoot['To'] =  Header("测试", 'utf-8')subject = 'Python SMTP 邮件测试'msgRoot['Subject'] = Header(subject, 'utf-8')msgAlternative = MIMEMultipart('alternative')msgRoot.attach(msgAlternative)mail_msg = """<p>Python 邮件发送测试...</p><p><a href="http://www.51coolma.cn">W3Cschool教程链接</a></p><p>图片演示:</p><p><img src="cid:image1"></p>"""msgAlternative.attach(MIMEText(mail_msg, 'html', 'utf-8'))# 指定图片为当前目录fp = open('test.png', 'rb')msgImage = MIMEImage(fp.read())fp.close()# 定义图片 ID,在 HTML 文本中引用msgImage.add_header('Content-ID', '<image1>')msgRoot.attach(msgImage)try:    smtpObj = smtplib.SMTP('localhost')    smtpObj.sendmail(sender, receivers, msgRoot.as_string())    print ("邮件发送成功")except smtplib.SMTPException:    print ("Error: 无法发送邮件")
              $ python3 test.py 邮件发送成功

              查看我们的收件箱(如果在垃圾箱可能需要移动到收件箱才可正常显示),就可以查看到邮件信息:


              更多内容请参阅:https://docs.python.org/3/library/email-examples.html


              多线程类似于同时执行多个不同程序,多线程运行有如下优点:

              • 使用线程可以把占据长时间的程序中的任务放到后台去处理。
              • 用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度
              • 程序的运行速度可能加快
              • 在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下我们可以释放一些珍贵的资源如内存占用等等。

              线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

              每个线程都有他自己的一组 CPU 寄存器,称为线程的上下文,该上下文反映了线程上次运行该线程的 CPU 寄存器的状态。

              指令指针和堆栈指针寄存器是线程上下文中两个最重要的寄存器,线程总是在进程得到上下文中运行的,这些地址都用于标志拥有线程的进程地址空间中的内存。

              • 线程可以被抢占(中断)。
              • 在其他线程正在运行时,线程可以暂时搁置(也称为睡眠) -- 这就是线程的退让。

              线程可以分为:

              • 内核线程:由操作系统内核创建和撤销。
              • 用户线程:不需要内核支持而在用户程序中实现的线程。

              Python3 线程中常用的两个模块为:

              • _thread
              • threading(推荐使用)

              thread 模块已被废弃。用户可以使用 threading 模块代替。所以,在 Python3 中不能再使用"thread" 模块。为了兼容性,Python3 将 thread 重命名为 "_thread"。


              开始学习 Python 线程

              Python 中使用线程有两种方式:函数或者用类来包装线程对象。

              函数式:调用 _thread 模块中的 start_new_thread() 函数来产生新线程。语法如下:

              _thread.start_new_thread ( function, args[, kwargs] )

              参数说明:

              • function - 线程函数。
              • args - 传递给线程函数的参数,他必须是个 tuple 类型。
              • kwargs - 可选参数。

              实例:

              #!/usr/bin/python3import _threadimport time# 为线程定义一个函数def print_time( threadName, delay):   count = 0   while count < 5:      time.sleep(delay)      count += 1      print ("%s: %s" % ( threadName, time.ctime(time.time()) ))# 创建两个线程try:   _thread.start_new_thread( print_time, ("Thread-1", 2, ) )   _thread.start_new_thread( print_time, ("Thread-2", 4, ) )except:   print ("Error: 无法启动线程")while 1:   pass

              执行以上程序输出结果如下:

              Thread-1: Wed Apr  6 11:36:31 2016Thread-1: Wed Apr  6 11:36:33 2016Thread-2: Wed Apr  6 11:36:33 2016Thread-1: Wed Apr  6 11:36:35 2016Thread-1: Wed Apr  6 11:36:37 2016Thread-2: Wed Apr  6 11:36:37 2016Thread-1: Wed Apr  6 11:36:39 2016Thread-2: Wed Apr  6 11:36:41 2016Thread-2: Wed Apr  6 11:36:45 2016Thread-2: Wed Apr  6 11:36:49 2016

              执行以上程后可以按下 ctrl-c to 退出。


              线程模块

              Python3 通过两个标准库 _thread 和 threading 提供对线程的支持。

              _thread 提供了低级别的、原始的线程以及一个简单的锁,它相比于 threading 模块的功能还是比较有限的。

              threading 模块除了包含 _thread 模块中的所有方法外,还提供的其他方法:

              • threading.currentThread(): 返回当前的线程变量。
              • threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
              • threading.activeCount(): 返回正在运行的线程数量,与 len(threading.enumerate()) 有相同的结果。

              除了使用方法外,线程模块同样提供了 Thread 类来处理线程,Thread 类提供了以下方法:

              • run(): 用以表示线程活动的方法。
              • start():启动线程活动。

              • join([time]): 等待至线程中止。这阻塞调用线程直至线程的 join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。
              • isAlive(): 返回线程是否活动的。
              • getName(): 返回线程名。
              • setName(): 设置线程名。

              使用 threading 模块创建线程

              我们可以通过直接从 threading.Thread 继承创建一个新的子类,并实例化后调用 start() 方法启动新线程,即它调用了线程的 run() 方法:

              #!/usr/bin/python3import threadingimport timeexitFlag = 0class myThread (threading.Thread):    def __init__(self, threadID, name, counter):        threading.Thread.__init__(self)        self.threadID = threadID        self.name = name        self.counter = counter    def run(self):        print ("开始线程:" + self.name)        print_time(self.name, self.counter, 5)        print ("退出线程:" + self.name)def print_time(threadName, delay, counter):    while counter:        if exitFlag:            threadName.exit()        time.sleep(delay)        print ("%s: %s" % (threadName, time.ctime(time.time())))        counter -= 1# 创建新线程thread1 = myThread(1, "Thread-1", 1)thread2 = myThread(2, "Thread-2", 2)# 开启新线程thread1.start()thread2.start()thread1.join()thread2.join()print ("退出主线程")

              以上程序执行结果如下;

              开始线程:Thread-1开始线程:Thread-2Thread-1: Wed Apr  6 11:46:46 2016Thread-1: Wed Apr  6 11:46:47 2016Thread-2: Wed Apr  6 11:46:47 2016Thread-1: Wed Apr  6 11:46:48 2016Thread-1: Wed Apr  6 11:46:49 2016Thread-2: Wed Apr  6 11:46:49 2016Thread-1: Wed Apr  6 11:46:50 2016退出线程:Thread-1Thread-2: Wed Apr  6 11:46:51 2016Thread-2: Wed Apr  6 11:46:53 2016Thread-2: Wed Apr  6 11:46:55 2016退出线程:Thread-2退出主线程

              线程同步

              如果多个线程共同对某个数据修改,则可能出现不可预料的结果,为了保证数据的正确性,需要对多个线程进行同步。

              使用 Thread 对象的 Lock 和 Rlock 可以实现简单的线程同步,这两个对象都有 acquire 方法和 release 方法,对于那些需要每次只允许一个线程操作的数据,可以将其操作放到 acquire 和 release 方法之间。如下:

              多线程的优势在于可以同时运行多个任务(至少感觉起来是这样)。但是当线程需要共享数据时,可能存在数据不同步的问题。

              考虑这样一种情况:一个列表里所有元素都是 0,线程"set"从后向前把所有元素改成 1,而线程"print"负责从前往后读取列表并打印。

              那么,可能线程"set"开始改的时候,线程"print"便来打印列表了,输出就成了一半 0 一半 1,这就是数据的不同步。为了避免这种情况,引入了锁的概念。

              锁有两种状态——锁定和未锁定。每当一个线程比如"set"要访问共享数据时,必须先获得锁定;如果已经有别的线程比如"print"获得锁定了,那么就让线程"set"暂停,也就是同步阻塞;等到线程"print"访问完毕,释放锁以后,再让线程"set"继续。

              经过这样的处理,打印列表时要么全部输出 0,要么全部输出 1,不会再出现一半 0 一半 1 的尴尬场面。

              实例:

              #!/usr/bin/python3import threadingimport timeclass myThread (threading.Thread):    def __init__(self, threadID, name, counter):        threading.Thread.__init__(self)        self.threadID = threadID        self.name = name        self.counter = counter    def run(self):        print ("开启线程: " + self.name)        # 获取锁,用于线程同步        threadLock.acquire()        print_time(self.name, self.counter, 3)        # 释放锁,开启下一个线程        threadLock.release()def print_time(threadName, delay, counter):    while counter:        time.sleep(delay)        print ("%s: %s" % (threadName, time.ctime(time.time())))        counter -= 1threadLock = threading.Lock()threads = []# 创建新线程thread1 = myThread(1, "Thread-1", 1)thread2 = myThread(2, "Thread-2", 2)# 开启新线程thread1.start()thread2.start()# 添加线程到线程列表threads.append(thread1)threads.append(thread2)# 等待所有线程完成for t in threads:    t.join()print ("退出主线程")

              执行以上程序,输出结果为:

              开启线程: Thread-1开启线程: Thread-2Thread-1: Wed Apr  6 11:52:57 2016Thread-1: Wed Apr  6 11:52:58 2016Thread-1: Wed Apr  6 11:52:59 2016Thread-2: Wed Apr  6 11:53:01 2016Thread-2: Wed Apr  6 11:53:03 2016Thread-2: Wed Apr  6 11:53:05 2016退出主线程

              线程优先级队列( Queue)

              Python 的 Queue 模块中提供了同步的、线程安全的队列类,包括 FIFO(先入先出)队列 Queue,LIFO(后入先出)队列 LifoQueue,和优先级队列 PriorityQueue。

              这些队列都实现了锁原语,能够在多线程中直接使用,可以使用队列来实现线程间的同步。

              Queue 模块中的常用方法:

              • Queue.qsize() 返回队列的大小
              • Queue.empty() 如果队列为空,返回 True,反之 False
              • Queue.full() 如果队列满了,返回 True,反之 False
              • Queue.full 与 maxsize 大小对应
              • Queue.get([block[, timeout]]) 获取队列,timeout 等待时间
              • Queue.get_nowait() 相当 Queue.get(False)
              • Queue.put(item) 写入队列,timeout 等待时间
              • Queue.put_nowait(item) 相当 Queue.put(item, False)
              • Queue.task_done() 在完成一项工作之后,Queue.task_done() 函数向任务已经完成的队列发送一个信号
              • Queue.join() 实际上意味着等到队列为空,再执行别的操作

              实例:

              #!/usr/bin/python3import queueimport threadingimport timeexitFlag = 0class myThread (threading.Thread):    def __init__(self, threadID, name, q):        threading.Thread.__init__(self)        self.threadID = threadID        self.name = name        self.q = q    def run(self):        print ("开启线程:" + self.name)        process_data(self.name, self.q)        print ("退出线程:" + self.name)def process_data(threadName, q):    while not exitFlag:        queueLock.acquire()        if not workQueue.empty():            data = q.get()            queueLock.release()            print ("%s processing %s" % (threadName, data))        else:            queueLock.release()        time.sleep(1)threadList = ["Thread-1", "Thread-2", "Thread-3"]nameList = ["One", "Two", "Three", "Four", "Five"]queueLock = threading.Lock()workQueue = queue.Queue(10)threads = []threadID = 1# 创建新线程for tName in threadList:    thread = myThread(threadID, tName, workQueue)    thread.start()    threads.append(thread)    threadID += 1# 填充队列queueLock.acquire()for word in nameList:    workQueue.put(word)queueLock.release()# 等待队列清空while not workQueue.empty():    pass# 通知线程是时候退出exitFlag = 1# 等待所有线程完成for t in threads:    t.join()print ("退出主线程")

              以上程序执行结果:

              开启线程:Thread-1开启线程:Thread-2开启线程:Thread-3Thread-3 processing OneThread-1 processing TwoThread-2 processing ThreeThread-3 processing FourThread-1 processing Five退出线程:Thread-3退出线程:Thread-2退出线程:Thread-1退出主线程

              什么是XML?

              XML 指可扩展标记语言(eXtensible Markup Language),标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。 你可以通过本站学习 XML教程

              XML 被设计用来传输和存储数据。

              XML 是一套定义语义标记的规则,这些标记将文档分成许多部件并对这些部件加以标识。

              它也是元标记语言,即定义了用于定义其他与特定领域有关的、语义的、结构化的标记语言的句法语言。


              python对XML的解析

              常见的 XML 编程接口有 DOM 和 SAX,这两种接口处理 XML 文件的方式不同,当然使用场合也不同。

              Python 有三种方法解析 XML,SAX,DOM,以及 ElementTree:

              1.SAX (simple API for XML )

              Python 标准库包含 SAX 解析器,SAX 用事件驱动模型,通过在解析 XML 的过程中触发一个个的事件并调用用户定义的回调函数来处理 XML 文件。

              2.DOM(Document Object Model)

              将 XML 数据在内存中解析成一个树,通过对树的操作来操作 XML。

              本章节使用到的 XML 实例文件 movies.xml 内容如下:

              <collection shelf="New Arrivals"><movie title="Enemy Behind">   <type>War, Thriller</type>   <format>DVD</format>   <year>2003</year>   <rating>PG</rating>   <stars>10</stars>   <description>Talk about a US-Japan war</description></movie><movie title="Transformers">   <type>Anime, Science Fiction</type>   <format>DVD</format>   <year>1989</year>   <rating>R</rating>   <stars>8</stars>   <description>A schientific fiction</description></movie>   <movie title="Trigun">   <type>Anime, Action</type>   <format>DVD</format>   <episodes>4</episodes>   <rating>PG</rating>   <stars>10</stars>   <description>Vash the Stampede!</description></movie><movie title="Ishtar">   <type>Comedy</type>   <format>VHS</format>   <rating>PG</rating>   <stars>2</stars>   <description>Viewable boredom</description></movie></collection>

              Python 使用 SAX 解析 xml

              SAX 是一种基于事件驱动的 API。

              利用 SAX 解析 XML 文档牵涉到两个部分:解析器和事件处理器。

              解析器负责读取 XML 文档,并向事件处理器发送事件,如元素开始跟元素结束事件;

              而事件处理器则负责对事件作出相应,对传递的 XML 数据进行处理。

              • 1、对大型文件进行处理;
              • 2、只需要文件的部分内容,或者只需从文件中得到特定信息。
              • 3、想建立自己的对象模型的时候。

              在 Python 中使用 sax 方式处理 xml 要先引入 xml.sax 中的 parse 函数,还有 xml.sax.handler 中的 ContentHandler。

              ContentHandler 类方法介绍

              characters(content) 方法

              调用时机:

              从行开始,遇到标签之前,存在字符,content 的值为这些字符串。

              从一个标签,遇到下一个标签之前, 存在字符,content 的值为这些字符串。

              从一个标签,遇到行结束符之前,存在字符,content 的值为这些字符串。

              标签可以是开始标签,也可以是结束标签。

              startDocument() 方法

              文档启动的时候调用。

              endDocument() 方法

              解析器到达文档结尾时调用。

              startElement(name, attrs) 方法

              遇到XML开始标签时调用,name 是标签的名字,attrs 是标签的属性值字典。

              endElement(name) 方法

              遇到XML结束标签时调用。


              make_parser 方法

              以下方法创建一个新的解析器对象并返回。

              xml.sax.make_parser( [parser_list] )

              参数说明:

              • parser_list - 可选参数,解析器列表

              parser 方法

              以下方法创建一个 SAX 解析器并解析xml文档:

              xml.sax.parse( xmlfile, contenthandler[, errorhandler])

              参数说明:

              • xmlfile - xml文件名
              • contenthandler - 必须是一个 ContentHandler 的对象
              • errorhandler - 如果指定该参数,errorhandler 必须是一个 SAX ErrorHandler 对象

              parseString 方法

              parseString 方法创建一个 XML 解析器并解析 xml 字符串:

              xml.sax.parseString(xmlstring, contenthandler[, errorhandler])

              参数说明:

              • xmlstring - xml字符串
              • contenthandler - 必须是一个 ContentHandler 的对象
              • errorhandler - 如果指定该参数,errorhandler 必须是一个 SAX ErrorHandler对象

              Python 解析XML实例

              #!/usr/bin/python3import xml.saxclass MovieHandler( xml.sax.ContentHandler ):   def __init__(self):      self.CurrentData = ""      self.type = ""      self.format = ""      self.year = ""      self.rating = ""      self.stars = ""      self.description = ""   # 元素开始调用   def startElement(self, tag, attributes):      self.CurrentData = tag      if tag == "movie":         print ("*****Movie*****")         title = attributes["title"]         print ("Title:", title)   # 元素结束调用   def endElement(self, tag):      if self.CurrentData == "type":         print ("Type:", self.type)      elif self.CurrentData == "format":         print ("Format:", self.format)      elif self.CurrentData == "year":         print ("Year:", self.year)      elif self.CurrentData == "rating":         print ("Rating:", self.rating)      elif self.CurrentData == "stars":         print ("Stars:", self.stars)      elif self.CurrentData == "description":         print ("Description:", self.description)      self.CurrentData = ""   # 读取字符时调用   def characters(self, content):      if self.CurrentData == "type":         self.type = content      elif self.CurrentData == "format":         self.format = content      elif self.CurrentData == "year":         self.year = content      elif self.CurrentData == "rating":         self.rating = content      elif self.CurrentData == "stars":         self.stars = content      elif self.CurrentData == "description":         self.description = content  if ( __name__ == "__main__"):      # 创建一个 XMLReader   parser = xml.sax.make_parser()   # 关闭命名空间   parser.setFeature(xml.sax.handler.feature_namespaces, 0)   # 重写 ContextHandler   Handler = MovieHandler()   parser.setContentHandler( Handler )      parser.parse("movies.xml")

              以上代码执行结果如下:

              *****Movie*****Title: Enemy BehindType: War, ThrillerFormat: DVDYear: 2003Rating: PGStars: 10Description: Talk about a US-Japan war*****Movie*****Title: TransformersType: Anime, Science FictionFormat: DVDYear: 1989Rating: RStars: 8Description: A schientific fiction*****Movie*****Title: TrigunType: Anime, ActionFormat: DVDRating: PGStars: 10Description: Vash the Stampede!*****Movie*****Title: IshtarType: ComedyFormat: VHSRating: PGStars: 2Description: Viewable boredom

              完整的 SAX API 文档请查阅 Python SAX APIs


              使用xml.dom解析xml

              文件对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展置标语言的标准编程接口。

              一个 DOM 的解析器在解析一个 XML 文档时,一次性读取整个文档,把文档中所有元素保存在内存中的一个树结构里,之后你可以利用DOM 提供的不同的函数来读取或修改文档的内容和结构,也可以把修改过的内容写入xml文件。

              python中用xml.dom.minidom来解析xml文件,实例如下:

              #!/usr/bin/python3from xml.dom.minidom import parseimport xml.dom.minidom# 使用minidom解析器打开 XML 文档DOMTree = xml.dom.minidom.parse("movies.xml")collection = DOMTree.documentElementif collection.hasAttribute("shelf"):   print ("Root element : %s" % collection.getAttribute("shelf"))# 在集合中获取所有电影movies = collection.getElementsByTagName("movie")# 打印每部电影的详细信息for movie in movies:   print ("*****Movie*****")   if movie.hasAttribute("title"):      print ("Title: %s" % movie.getAttribute("title"))   type = movie.getElementsByTagName('type')[0]   print ("Type: %s" % type.childNodes[0].data)   format = movie.getElementsByTagName('format')[0]   print ("Format: %s" % format.childNodes[0].data)   rating = movie.getElementsByTagName('rating')[0]   print ("Rating: %s" % rating.childNodes[0].data)   description = movie.getElementsByTagName('description')[0]   print ("Description: %s" % description.childNodes[0].data)

              以上程序执行结果如下:

              Root element : New Arrivals*****Movie*****Title: Enemy BehindType: War, ThrillerFormat: DVDRating: PGDescription: Talk about a US-Japan war*****Movie*****Title: TransformersType: Anime, Science FictionFormat: DVDRating: RDescription: A schientific fiction*****Movie*****Title: TrigunType: Anime, ActionFormat: DVDRating: PGDescription: Vash the Stampede!*****Movie*****Title: IshtarType: ComedyFormat: VHSRating: PGDescription: Viewable boredom

              完整的 DOM API 文档请查阅 Python DOM APIs


              Python3 JSON 数据解析

              JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于 ECMAScript 的一个子集。

              Python3 中可以使用 json 模块来对 JSON 数据进行编解码,它包含了两个函数:

              • json.dumps(): 对数据进行编码。
              • json.loads(): 对数据进行解码。

              在json的编解码过程中,Python 的原始类型与 json 类型会相互转换,具体的转化对照如下:

              Python 编码为 JSON 类型转换对应表:

              PythonJSON
              dictobject
              list, tuplearray
              strstring
              int, float, int- & float-derived Enumsnumber
              Truetrue
              Falsefalse
              Nonenull

              JSON 解码为 Python 类型转换对应表:

              JSONPython
              objectdict
              arraylist
              stringstr
              number (int)int
              number (real)float
              trueTrue
              falseFalse
              nullNone

              json.dumps 与 json.loads 实例

              以下实例演示了 Python 数据结构转换为 JSON:

              #!/usr/bin/python3import json# Python 字典类型转换为 JSON 对象data = {    'no' : 1,    'name' : 'W3CSchool',    'url' : 'http://www.51coolma.cn'}json_str = json.dumps(data)print ("Python 原始数据:", repr(data))print ("JSON 对象:", json_str)

              执行以上代码输出结果为:

              Python 原始数据: {'url': 'http://www.51coolma.cn', 'no': 1, 'name': 'W3CSchool'}JSON 对象: {"url": "http://www.51coolma.cn", "no": 1, "name": "W3CSchool"}

              通过输出的结果可以看出,简单类型通过编码后跟其原始的repr()输出结果非常相似。

              接着以上实例,我们可以将一个JSON编码的字符串转换回一个Python数据结构:

              #!/usr/bin/python3import json# Python 字典类型转换为 JSON 对象data1 = {    'no' : 1,    'name' : 'W3CSchool',    'url' : 'http://www.51coolma.cn'}json_str = json.dumps(data1)print ("Python 原始数据:", repr(data1))print ("JSON 对象:", json_str)# 将 JSON 对象转换为 Python 字典data2 = json.loads(json_str)print ("data2['name']: ", data2['name'])print ("data2['url']: ", data2['url'])

              执行以上代码输出结果为:

              ython 原始数据: {'name': 'W3CSchool', 'no': 1, 'url': 'http://www.51coolma.cn'}JSON 对象: {"name": "W3CSchool", "no": 1, "url": "http://www.51coolma.cn"}data2['name']:  W3CSchooldata2['url']:  http://www.51coolma.cn

              如果你要处理的是文件而不是字符串,你可以使用 json.dump()json.load() 来编码和解码 JSON 数据。例如:

              # 写入 JSON 数据with open('data.json', 'w') as f:    json.dump(data, f)# 读取数据with open('data.json', 'r') as f:    data = json.load(f)

              更多资料请参考:https://docs.python.org/3/library/json.html

              Python3 日期和时间

              Python 程序能用很多方式处理日期和时间,转换日期格式是一个常见的功能。

              Python 提供了一个 time 和 calendar 模块可以用于格式化日期和时间。

              时间间隔是以秒为单位的浮点小数。

              每个时间戳都以自从 1970 年 1 月 1 日午夜(历元)经过了多长时间来表示。

              Python 的 time 模块下有很多函数可以转换常见日期格式。如函数 time.time() 用于获取当前时间戳, 如下实例:

              #!/usr/bin/python3import time;  # 引入time模块ticks = time.time()print ("当前时间戳为:", ticks)

              以上实例输出结果:

              当前时间戳为: 1459996086.7115328

              时间戳单位最适于做日期运算。但是 1970 年之前的日期就无法以此表示了。太遥远的日期也不行,UNIX 和 Windows 只支持到 2038 年。


              什么是时间元组?

              很多 Python 函数用一个元组装起来的9组数字处理时间:

              序号字段
              04 位数年2020
              11 到 12
              21 到 31
              3小时0 到 23
              4分钟0 到 59
              50 到 61 (60 或 61 是闰秒)
              6一周的第几日0 到 6 (0 是周一)
              7一年的第几日1 到 366 (儒略历)
              8夏令时-1, 0, 1, -1是决定是否为夏令时的旗帜

              上述也就是struct_time元组。这种结构具有如下属性:

              序号属性
              0tm_year2020
              1tm_mon1 到 12
              2tm_mday1 到 31
              3tm_hour0 到 23
              4tm_min0 到 59
              5tm_sec0 到 61 (60或61 是闰秒)
              6tm_wday0到6 (0是周一)
              7tm_yday一年中的第几天,1 到 366
              8tm_isdst是否为夏令时,值有:1(夏令时)、0(不是夏令时)、-1(未知),默认 -1


              获取当前时间

              从返回浮点数的时间辍方式向时间元组转换,只要将浮点数传递给如 localtime 之类的函数。

              #!/usr/bin/python3
              import time

              localtime
              = time.localtime(time.time())
              print
              ("本地时间为 :", localtime)

              以上实例输出结果:

              本地时间为 : time.struct_time(tm_year=2016, tm_mon=4, tm_mday=7, tm_hour=10, tm_min=28, tm_sec=49, tm_wday=3, tm_yday=98, tm_isdst=0)

              获取格式化的时间

              你可以根据需求选取各种格式,但是最简单的获取可读的时间模式的函数是 asctime():

              #!/usr/bin/python3
              import
              time

              localtime
              = time.asctime( time.localtime(time.time()) )
              print
              ("本地时间为 :", localtime)

              以上实例输出结果:

              本地时间为 : Thu Apr  7 10:29:13 2020

              格式化日期

              我们可以使用 time 模块的 strftime 方法来格式化日期,:

              time.strftime(format[, t])
              #!/usr/bin/python3
              import
              time

              # 格式化成2020-03-20 11:45:39形式

              print
              (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

              # 格式化成Sat Mar 28 22:24:24 2020形式
              print (time.strftime("%a %b %d %H:%M:%S %Y", time.localtime()))

              # 将格式字符串转换为时间戳

              a
              = "Sat Mar 28 22:24:24 2020"
              print (time.mktime(time.strptime(a,"%a %b %d %H:%M:%S %Y")))

              以上实例输出结果:

              2020-04-07 10:29:46
              Thu Apr 07 10:29:46
              2020
              1459175064.0

              Python 中时间日期格式化符号:

              • %y 两位数的年份表示(00-99)
              • %Y 四位数的年份表示(000-9999)
              • %m 月份(01-12)
              • %d 月内中的一天(0-31)
              • %H 24 小时制小时数(0-23)
              • %I 12 小时制小时数(01-12)
              • %M 分钟数(00=59)
              • %S 秒(00-59)
              • %a 本地简化星期名称
              • %A 本地完整星期名称
              • %b 本地简化的月份名称
              • %B 本地完整的月份名称
              • %c 本地相应的日期表示和时间表示
              • %j 年内的一天(001-366)
              • %p 本地 A.M. 或 P.M. 的等价符
              • %U 一年中的星期数(00-53)星期天为星期的开始
              • %w 星期(0-6),星期天为星期的开始
              • %W 一年中的星期数(00-53)星期一为星期的开始
              • %x 本地相应的日期表示
              • %X 本地相应的时间表示
              • %Z 当前时区的名称
              • %% %号本身

              获取某月日历

              Calendar 模块有很广泛的方法用来处理年历和月历,例如打印某月的月历:

              #!/usr/bin/python3

              import calendar
              cal
              = calendar.month(2020, 9)
              print ("以下输出2020年9月份的日历:")
              print (cal)

              以上实例输出结果:

              以下输出20209月份的日历:    
              September 2020
              Mo Tu We Th Fr Sa Su
              1 2 3
              4
              5 6 7 8 9 10
              11
              12 13 14 15 16 17
              18
              19 20 21 22 23 24
              25
              26 27 28 29 30 31


              Time 模块

              Time 模块包含了以下内置函数,既有时间处理相的,也有转换时间格式的:

              序号函数及描述实例
              1time.altzone
              返回格林威治西部的夏令时地区的偏移秒数。如果该地区在格林威治东部会返回负值(如西欧,包括英国)。对夏令时启用地区才能使用。

              以下实例展示了 altzone()函数的使用方法:

              >>> import time
              >>> print ("time.altzone %d " % time.altzone)
              time.altzone -28800
              2time.asctime([tupletime])
              接受时间元组并返回一个可读的形式为"Tue Dec 11 18:07:14 2008"(2008年12月11日 周二18时07分14秒)的24个字符的字符串。

              以下实例展示了 asctime()函数的使用方法:

              >>> import time
              >>> t = time.localtime()
              >>> print ("time.asctime(t): %s " % time.asctime(t))
              time.asctime(t): Thu Apr 7 10:36:20 2016
              3time.clock()
              用以浮点数计算的秒数返回当前的CPU时间。用来衡量不同程序的耗时,比time.time()更有用。
              实例
              4time.ctime([secs])
              作用相当于asctime(localtime(secs)),未给参数相当于asctime()

              以下实例展示了 ctime()函数的使用方法:

              >>> import time
              >>> print ("time.ctime() : %s" % time.ctime())
              time
              .ctime() : Thu Apr 7 10:51:58 2016
              5time.gmtime([secs])
              接收时间辍(1970纪元后经过的浮点秒数)并返回格林威治天文时间下的时间元组t。注:t.tm_isdst始终为0

              以下实例展示了 gmtime()函数的使用方法:

              >>> import time
              >>> print ("gmtime :", time.gmtime(1455508609.34375))
              gmtime
              : time.struct_time(tm_year=2016, tm_mon=2, tm_mday=15, tm_hour=3, tm_min=56, tm_sec=49, tm_wday=0, tm_yday=46, tm_isdst=0)
              6time.localtime([secs]
              接收时间辍(1970纪元后经过的浮点秒数)并返回当地时间下的时间元组t(t.tm_isdst可取0或1,取决于当地当时是不是夏令时)。

              以下实例展示了 localtime()函数的使用方法:

              >>> import time
              >>>
              print ("localtime(): ", time.localtime(1455508609.34375))
              localtime(): time.struct_time(tm_year=2016, tm_mon=2, tm_mday=15, tm_hour=11, tm_min=56, tm_sec=49, tm_wday=0, tm_yday=46, tm_isdst=0)
              7time.mktime(tupletime)
              接受时间元组并返回时间辍(1970纪元后经过的浮点秒数)。
              实例
              8time.sleep(secs)
              推迟调用线程的运行,secs指秒数。

              以下实例展示了 sleep()函数的使用方法:

              #!/usr/bin/python3
              import
              time

              print
              ("Start : %s" % time.ctime())
              time.sleep( 5 )
              print
              ("End : %s" % time.ctime())
              9time.strftime(fmt[,tupletime])
              接收以时间元组,并返回以可读字符串表示的当地时间,格式由fmt决定。

              以下实例展示了 strftime()函数的使用方法:

              >>> import time
              >>> print (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
              2016
              -04-07 11:18:05
              10time.strptime(str,fmt='%a %b %d %H:%M:%S %Y')
              根据fmt的格式把一个时间字符串解析为时间元组。

              以下实例展示了 strptime()函数的使用方法:

              >>> import time
              >>> struct_time = time.strptime("30 Nov 00", "%d %b %y")
              >>> print ("返回元组: ", struct_time)
              返回元组:
              time.struct_time(tm_year=2000, tm_mon=11, tm_mday=30, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=335, tm_isdst=-1)
              11time.time( )
              返回当前时间的时间戳(1970纪元后经过的浮点秒数)。

              以下实例展示了 time()函数的使用方法:

              >>> import time
              >>>
              print(time.time())
              1459999336.1963577
              12time.tzset()
              根据环境变量TZ重新初始化时间相关设置。
              实例

              Time 模块包含了以下 2 个非常重要的属性:

              序号属性及描述
              1time.timezone
              属性time.timezone是当地时区(未启动夏令时)距离格林威治的偏移秒数(>0,美洲;<=0大部分欧洲,亚洲,非洲)。
              2time.tzname
              属性time.tzname包含一对根据情况的不同而不同的字符串,分别是带夏令时的本地时区名称,和不带的。


              日历(Calendar)模块

              此模块的函数都是日历相关的,例如打印某月的字符月历。

              星期一是默认的每周第一天,星期天是默认的最后一天。更改设置需调用calendar.setfirstweekday() 函数。模块包含了以下内置函数:

              序号函数及描述
              1calendar.calendar(year,w=2,l=1,c=6)
              返回一个多行字符串格式的 year 年年历,3 个月一行,间隔距离为 c。 每日宽度间隔为 w 字符。每行长度为 21* W+18+2* C。l 是每星期行数。
              2calendar.firstweekday( )
              返回当前每周起始日期的设置。默认情况下,首次载入 calendar 模块时返回 0,即星期一。
              3calendar.isleap(year)
              是闰年返回 True,否则为 False。
              4calendar.leapdays(y1,y2)
              返回在 Y1,Y2 两年之间的闰年总数。
              5calendar.month(year,month,w=2,l=1)
              返回一个多行字符串格式的 year 年 month 月日历,两行标题,一周一行。每日宽度间隔为 w 字符。每行的长度为 7* w+6。l 是每星期的行数。
              6calendar.monthcalendar(year,month)
              返回一个整数的单层嵌套列表。每个子列表装载代表一个星期的整数。Year 年 month 月外的日期都设为 0;范围内的日子都由该月第几日表示,从 1 开始。
              7calendar.monthrange(year,month)
              返回两个整数。第一个是该月的星期几的日期码,第二个是该月的日期码。日从 0(星期一)到 6 (星期日);月从 1 到 12。
              8calendar.prcal(year,w=2,l=1,c=6)
              相当于 print calendar.calendar(year,w,l,c).
              9calendar.prmonth(year,month,w=2,l=1)
              相当于 print calendar.calendar(year,w,l,c)。
              10calendar.setfirstweekday(weekday)
              设置每周的起始日期码。0(星期一)到 6(星期日)。
              11calendar.timegm(tupletime)
              和 time.gmtime 相反:接受一个时间元组形式,返回该时刻的时间辍(1970 纪元后经过的浮点秒数)。
              12calendar.weekday(year,month,day)
              返回给定日期的日期码。0(星期一)到6(星期日)。月份为 1(一月) 到 12(12月)。


              其他相关模块和函数

              在 Python中,其他处理日期和时间的模块还有:


              本节介绍了 Python3 中的内置函数以及调试的两种方法。

              内置函数
              abs()dict()help()min()setattr()
              all()dir()hex()next()slice()
              any()divmod()id()object()sorted()
              ascii()enumerate()input()oct()staticmethod()
              bin()eval()int()open()str()
              bool()exec()isinstance()ord()sum()
              bytearray()filter()issubclass()pow()super()
              bytes()float()iter()print()tuple()
              callable()format()len()property()type()
              chr()frozenset()list()range()vars()
              classmethod()getattr()locals()repr()zip()
              compile()globals()map()reversed()__import__()
              complex()hasattr()max()round() 
              delattr()hash()memoryview()set() 

              Python 调试方法

              1、print

              print('here')# 可以发现某段逻辑是否执行# 打印出变量的内容

              2、assert

              assert false, 'blabla'# 如果条件不成立,则打印出 'blabla' 并抛出AssertionError异常

              3、debugger

              可以通过 pdb、IDE 等工具进行调试。

              调试的具体方法这里不展开。

              Python 中有两个内置方法在这里也很有帮助:

              •  locals: 执行 locals() 之后, 返回一个字典, 包含(current scope)当前范围下的局部变量。
              •  globals: 执行 globals() 之后, 返回一个字典, 包含(current scope)当前范围下的全局变量。


              定义:

              网络爬虫(Web Spider),又被称为网页蜘蛛,是一种按照一定的规则,自动地抓取网站信息的程序或者脚本。爬虫其实是通过编写程序,模拟浏览器上网,然后让其去互联网上抓取数据的过程。

              爬虫的价值:

              抓取互联网上的数据,为我所用,有了大量的数据,就如同有了一个数据银行一样,下一步就是如何将这些数据产品化、商业化。

              爬虫是否合法

              网络爬虫在法律中是不被禁止,但是具有违法风险,通常来说爬虫分为善意的爬虫和恶意的爬虫。爬虫带来的风险可以体现在如下两个方面:

              • 爬虫干扰了被访问网站的正常运营
              • 爬虫抓取了受法律保护的特定类的数据或信息

              那么我们如何在使用编写爬虫的过程中避免进入局子的厄运呢?

              • 时常优化自己的程序,避免干扰被访问网站的正常运行
              • 在使用、传播爬取到的数据时,审查抓取到的内容,如果发现涉及到用户隐私或者商业机密等敏感内容,需要及时停止爬取或传播

              爬虫在使用场景中的分类

              • 通用爬虫抓取系统重要组成部分,抓取的是一整张页面数据
              • 聚焦爬虫是建立在通用爬虫的基础之上,抓取页面中特定的局部内容
              • 增量式爬虫检测网站中数据更新的情况,只会爬取网站中最新更新出来的数据

              爬虫的矛与盾

              反爬机制:门户网站,可以通过制定相应的策略或者技术手段,防止爬虫程序进行网站数据的爬取。反反爬策略:爬虫程序可以通过制定相关的策略或者技术手段,破解门户网站中具备的反爬机制,从而可以获取门户网站中相关的数据。

              下面,我们来了解一下网络爬虫中一个重要的协议:robots.txt协议。robots.txt协议是一个君子协议,协议中规定了网站中哪些数据可以被爬取哪些数据不能被爬取。

              http协议和https协议

              http协议:就是服务器和客户端进行数据交互的一种形式。http协议中常用的请求头信息:

              • User-Agent:请求载体的身份标识
              • Connection:请求完毕后,是断开连接还是保持连接http协议中常用的响应头信息:
              • Content-Type:服务器响应回客户端的数据类型https协议其实就是一种安全的http协议


              在讲解爬虫内容之前,我们需要先学习一项写爬虫的必备技能:审查元素(如果已掌握,可跳过此部分内容)。


              1、审查元素

              在浏览器的地址栏输入URL地址,在网页处右键单击,找到检查。(不同浏览器的叫法不同,Chrome浏览器叫做检查,Firefox浏览器叫做查看元素,但是功能都是相同的)

              1

              我们可以看到,右侧出现了一大推代码,这些代码就叫做HTML。什么是HTML?举个容易理解的例子:我们的基因决定了我们的原始容貌,服务器返回的HTML决定了网站的原始容貌。

              为啥说是原始容貌呢?

              2

              因为人可以整容啊!扎心了,有木有?那网站也可以”整容”吗?可以!请看下图:

              3

              我能有这么多钱吗?显然不可能。我是怎么给网站”整容”的呢?就是通过修改服务器返回的HTML信息。我们每个人都是”整容大师”,可以修改页面信息。我们在页面的哪个位置点击审查元素,浏览器就会为我们定位到相应的HTML位置,进而就可以在本地更改HTML信息。

              再举个小例子:我们都知道,使用浏览器”记住密码”的功能,密码会变成一堆小黑点,是不可见的。可以让密码显示出来吗?可以,只需给页面”动个小手术”!以淘宝为例,在输入密码框处右键,点击检查。

              4

              可以看到,浏览器为我们自动定位到了相应的HTML位置。将下图中的password属性值改为text属性值(直接在右侧代码处修改):

              5

              我们让浏览器记住的密码就这样显现出来了:

              6

              说这么多,什么意思呢?浏览器就是作为客户端从服务器端获取信息,然后将信息解析,并展示给我们的。我们可以在本地修改HTML信息,为网页”整容”,但是我们修改的信息不会回传到服务器,服务器存储的HTML信息不会改变。刷新一下界面,页面还会回到原本的样子。这就跟人整容一样,我们能改变一些表面的东西,但是不能改变我们的基因。


              2、简单实例

              网络爬虫的第一步就是根据URL,获取网页的HTML信息。在Python3中,可以使用urllib.request和requests进行网页爬取。

              • urllib库是python内置的,无需我们额外安装,只要安装了Python就可以使用这个库。
              • requests库是第三方库,需要我们自己安装。

              requests库强大好用,所以本文使用requests库获取网页的HTML信息。requests库的github地址:https://github.com/requests/requests

              (1) requests安装

              在cmd中,使用如下指令安装requests:

              pip install requests
              • 1

              或者:

              easy_install requests
              • 1

              (2) 简单实例

              requests库的基础方法如下:

              7

              requests中文文档:http://docs.python-requests.org/zh_CN/latest/user/quickstart.html

              requests库的开发者为我们提供了详细的中文教程,查询起来很方便。本文不会对其所有内容进行讲解,摘取其部分使用到的内容,进行实战说明。

              首先,让我们看下requests.get()方法,它用于向服务器发起GET请求,不了解GET请求没有关系。我们可以这样理解:get的中文意思是得到、抓住,那这个requests.get()方法就是从服务器得到、抓住数据,也就是获取数据。让我们看一个例子(以 www.gitbook.cn为例)来加深理解:

              # -*- coding:UTF-8 -*-import requestsif __name__ == '__main__':    target = 'http://gitbook.cn/'    req = requests.get(url=target)    print(req.text)

              requests.get()方法必须设置的一个参数就是url,因为我们得告诉GET请求,我们的目标是谁,我们要获取谁的信息。运行程序看下结果:

              8

              左侧是我们程序获得的结果,右侧是我们在www.gitbook.cn网站审查元素获得的信息。我们可以看到,我们已经顺利获得了该网页的HTML信息。这就是一个最简单的爬虫实例,可能你会问,我只是爬取了这个网页的HTML信息,有什么用呢?客官稍安勿躁,接下来进入我们的实战正文。


              原文作者:Jack-Cui

              原文地址:https://blog.csdn.net/c406495762/article/details/78123502


              第一个 Python3 爬虫实战让我们先来试下文字的抓取,本实战将针对笔趣看小说网进行爬虫设置,从而实现小说文字的抓取下载。

              (1) 实战背景

              小说网站-笔趣看:URL:http://www.biqukan.com/

              笔趣看是一个盗版小说网站,这里有很多起点中文网的小说,该网站小说的更新速度稍滞后于起点中文网正版小说的更新速度。并且该网站只支持在线浏览,不支持小说打包下载。因此,本次实战就是从该网站爬取并保存一本名为《一念永恒》的小说,该小说是耳根正在连载中的一部玄幻小说。PS:本实例仅为交流学习,支持耳根大大,请上起点中文网订阅。

              (2) 小试牛刀

              我们先看下《一念永恒》小说的第一章内容,URL:http://www.biqukan.com/1_1094/5403177.html

              20170928143125108

              我们先用已经学到的知识获取 HTML 信息试一试,编写代码如下:

              # -*- coding:UTF-8 -*-import requestsif __name__ == '__main__':    target = 'http://www.biqukan.com/1_1094/5403177.html'    req = requests.get(url=target)    print(req.text)

              运行代码,可以看到如下结果:

              2

              可以看到,我们很轻松地获取了 HTML 信息。但是,很显然,很多信息是我们不想看到的,我们只想获得如右侧所示的正文内容,我们不关心 div、br 这些 html 标签。如何把正文内容从这些众多的 html 标签中提取出来呢?这就是本次实战的主要内容。

              (3)Beautiful Soup

              爬虫的第一步,获取整个网页的 HTML 信息,我们已经完成。接下来就是爬虫的第二步,解析 HTML 信息,提取我们感兴趣的内容。对于本小节的实战,我们感兴趣的内容就是文章的正文。提取的方法有很多,例如使用正则表达式、Xpath、Beautiful Soup 等。对于初学者而言,最容易理解,并且使用简单的方法就是使用 Beautiful Soup 提取感兴趣内容。

              Beautiful Soup 的安装方法和 requests 一样,使用如下指令安装(也是二选一):

              • pip install beautifulsoup4
              • easy_install beautifulsoup4

              一个强大的第三方库,都会有一个详细的官方文档。我们很幸运,Beautiful Soup 也是有中文的官方文档:http://beautifulsoup.readthedocs.io/zh_CN/latest/

              同理,我会根据实战需求,讲解 Beautiful Soup 库的部分使用方法,更详细的内容,请查看官方文档。

              现在,我们使用已经掌握的审查元素方法,查看一下我们的目标页面,你会看到如下内容:

              3

              不难发现,文章的所有内容都放在了一个名为 div 的“东西下面”,这个”东西”就是 html 标签。HTML 标签是 HTML 语言中最基本的单位,HTML 标签是 HTML 最重要的组成部分。不理解,没关系,我们再举个简单的例子:

              一个女人的包包里,会有很多东西,她们会根据自己的习惯将自己的东西进行分类放好。镜子和口红这些会经常用到的东西,会归放到容易拿到的外侧口袋里。那些不经常用到,需要注意安全存放的证件会放到不容易拿到的里侧口袋里。

              html 标签就像一个个“口袋”,每个“口袋”都有自己的特定功能,负责存放不同的内容。显然,上述例子中的div标签下存放了我们关心的正文内容。这个 div 标签是这样的:

              <div id="content", class="showtxt">

              细心的朋友可能已经发现,除了 div 字样外,还有 id 和 class。id 和 class 就是 div 标签的属性,content 和 showtxt 是属性值,一个属性对应一个属性值。这东西有什么用?它是用来区分不同的div标签的,因为 div 标签可以有很多,我们怎么加以区分不同的 div 标签呢?就是通过不同的属性值。

              仔细观察目标网站一番,我们会发现这样一个事实:class 属性为 showtxt 的 div 标签,独一份!这个标签里面存放的内容,是我们关心的正文部分。

              知道这个信息,我们就可以使用 Beautiful Soup 提取我们想要的内容了,编写代码如下:

              # -*- coding:UTF-8 -*-from bs4 import BeautifulSoupimport requestsif __name__ == "__main__":     target = 'http://www.biqukan.com/1_1094/5403177.html'     req = requests.get(url = target)     html = req.text     bf = BeautifulSoup(html)     texts = bf.find_all('div', class_ = 'showtxt')      print(texts)

              在解析 html 之前,我们需要创建一个 Beautiful Soup 对象。BeautifulSoup 函数里的参数就是我们已经获得的 html 信息。然后我们使用 find_all 方法,获得 html 信息中所有 class 属性为 showtxt 的 div 标签。find_all 方法的第一个参数是获取的标签名,第二个参数 class_ 是标签的属性,为什么不是 class,而带了一个下划线呢?因为 python 中 class 是关键字,为了防止冲突,这里使用class_表示标签的 class 属性,class_ 后面跟着的 showtxt 就是属性值了。看下我们要匹配的标签格式:

              <div id="content", class="showtxt">

              这样对应的看一下,是不是就懂了?可能有人会问了,为什么不是find_all(‘div’, id = ‘content’, class_ = ‘showtxt’)?这样其实也是可以的,属性是作为查询时候的约束条件,添加一个class_=’showtxt’条件,我们就已经能够准确匹配到我们想要的标签了,所以我们就不必再添加 id 这个属性了。运行代码查看我们匹配的结果:

              4

              我们可以看到,我们已经顺利匹配到我们关心的正文内容,但是还有一些我们不想要的东西。比如 div 标签名,br 标签,以及各种空格。怎么去除这些东西呢?我们继续编写代码:

              # -*- coding:UTF-8 -*-from bs4 import BeautifulSoupimport requestsif __name__ == "__main__":     target = 'http://www.biqukan.com/1_1094/5403177.html'     req = requests.get(url = target)      html = req.text     bf = BeautifulSoup(html)     texts = bf.find_all('div', class_ = 'showtxt')     print(texts[0].text.replace('xa0'*8,'
              
              '))

              find_all 匹配的返回的结果是一个列表。提取匹配结果后,使用 text 属性,提取文本内容,滤除 br 标签。随后使用 replace 方法,剔除空格,替换为回车进行分段。 在 html 中是用来表示空格的。replace(‘xa0’*8,’ ’)就是去掉下图的八个空格符号,并用回车代替:

              5

              程序运行结果如下:

              6

              可以看到,我们很自然的匹配到了所有正文内容,并进行了分段。我们已经顺利获得了一个章节的内容,要想下载正本小说,我们就要获取每个章节的链接。我们先分析下小说目录:

              7

              通过审查元素,我们发现可以发现,这些章节都存放在了 class 属性为 listmain 的 div 标签下,选取部分 html 代码如下:

              <div class="listmain"><dl><dt>《一念永恒》最新章节列表</dt><dd><a href="/1_1094/15932394.html">第1027章 第十道门</a></dd><dd><a href="/1_1094/15923072.html">第1026章 绝伦道法!</a></dd><dd><a href="/1_1094/15921862.html">第1025章 长生灯!</a></dd><dd><a href="/1_1094/15918591.html">第1024章 一目晶渊</a></dd><dd><a href="/1_1094/15906236.html">第1023章 通天道门</a></dd><dd><a href="/1_1094/15903775.html">第1022章 四大凶兽!</a></dd><dd><a href="/1_1094/15890427.html">第1021章 鳄首!</a></dd><dd><a href="/1_1094/15886627.html">第1020章 一触即发!</a></dd><dd><a href="/1_1094/15875306.html">第1019章 魁祖的气息!</a></dd><dd><a href="/1_1094/15871572.html">第1018章 绝望的魁皇城</a></dd><dd><a href="/1_1094/15859514.html">第1017章 我还是恨你!</a></dd><dd><a href="/1_1094/15856137.html">第1016章 从来没有世界之门!</a></dd><dt>《一念永恒》正文卷</dt> <dd><a href="/1_1094/5386269.html">外传1 柯父。</a></dd><dd><a href="/1_1094/5386270.html">外传2 楚玉嫣。</a></dd> <dd><a href="/1_1094/5386271.html">外传3 鹦鹉与皮冻。</a></dd><dd><a href="/1_1094/5403177.html">第一章 他叫白小纯</a></dd> <dd><a href="/1_1094/5428081.html">第二章 火灶房</a></dd><dd><a href="/1_1094/5433843.html">第三章 六句真言</a></dd> <dd><a href="/1_1094/5447905.html">第四章 炼灵</a></dd></dl></div>

              在分析之前,让我们先介绍一个概念:父节点、子节点、孙节点。<div></div>限定了<div>标签的开始和结束的位置,他们是成对出现的,有开始位置,就有结束位置。我们可以看到,在<div>标签包含<dl>标签,那这个<dl>标签就是<div>标签的子节点,<dl>标签又包含<dt>标签和<dd>标签,那么<dt>标签和<dd>标签就是<div>标签的孙节点。有点绕?那你记住这句话:谁包含谁,谁就是谁儿子!

              他们之间的关系都是相对的。比如对于<dd>标签,它的子节点是<a>标签,它的父节点是<dl>标签。这跟我们人是一样的,上有老下有小。

              看到这里可能有人会问,这有好多<dd>标签和<a>标签啊!不同的<dd>标签,它们是什么关系啊?显然,兄弟姐妹喽!我们称它们为兄弟结点。 好了,概念明确清楚,接下来,让我们分析一下问题。我们看到每个章节的名字存放在了<a>标签里面。<a>标签还有一个 href 属性。这里就不得不提一下<a>标签的定义了,<a>标签定义了一个超链接,用于从一张页面链接到另一张页面。<a> 标签最重要的属性是 href 属性,它指示链接的目标。

              我们将之前获得的第一章节的 URL 和<a> 标签对比看一下:

              http://www.biqukan.com/1_1094/5403177.html<a href="/1_1094/5403177.html">第一章 他叫白小纯</a>

              不难发现,<a> 标签中 href 属性存放的属性值/1_1094/5403177.html 是章节URLhttp://www.biqukan.com/1_1094/5403177.html的后半部分。其他章节也是如此!那这样,我们就可以根据<a>标签的href属性值获得每个章节的链接和名称了。

              总结一下:小说每章的链接放在了 class 属性为 listmain 的<div>标签下的<a>标签中。链接具体位置放在 html->body->div->dl->dd->a 的 href 属性中。先匹配 class 属性为 listmain 的<div>标签,再匹配<a>标签。编写代码如下:

              # -*- coding:UTF-8 -*-from bs4 import BeautifulSoupimport requestsif __name__ == "__main__":     target = 'http://www.biqukan.com/1_1094/'     req = requests.get(url = target)     html = req.text     div_bf = BeautifulSoup(html)     div = div_bf.find_all('div', class_ = 'listmain')     print(div[0])

              还是使用 find_all 方法,运行结果如下:

              8

              很顺利,接下来再匹配每一个<a>标签,并提取章节名和章节文章。如果我们使用 Beautiful Soup 匹配到了下面这个<a>标签,如何提取它的 href 属性和<a>标签里存放的章节名呢?

              <a href="/1_1094/5403177.html">第一章 他叫白小纯</a>

              方法很简单,对 Beautiful Soup 返回的匹配结果 a,使用 a.get(‘href’)方法就能获取 href 的属性值,使用 a.string 就能获取章节名,编写代码如下:

              # -*- coding:UTF-8 -*-from bs4 import BeautifulSoupimport requestsif __name__ == "__main__":     server = 'http://www.biqukan.com/'     target = 'http://www.biqukan.com/1_1094/'     req = requests.get(url = target)      html = req.text     div_bf = BeautifulSoup(html)     div = div_bf.find_all('div', class_ = 'listmain')     a_bf = BeautifulSoup(str(div[0]))     a = a_bf.find_all('a')     for each in a:          print(each.string, server + each.get('href'))

              因为 find_all 返回的是一个列表,里边存放了很多的<a>标签,所以使用 for 循环遍历每个<a>标签并打印出来,运行结果如下。

              9

              最上面匹配的一千多章的内容是最新更新的12章节的链接。这12章内容会和下面的重复,所以我们要滤除,除此之外,还有那3个外传,我们也不想要。这些都简单地剔除就好。

              3)整合代码

              每个章节的链接、章节名、章节内容都有了。接下来就是整合代码,将获得内容写入文本文件存储就好了。编写代码如下:

              # -*- coding:UTF-8 -*-from bs4 import BeautifulSoupimport requests, sys"""类说明:下载《笔趣看》网小说《一念永恒》Parameters:    无Returns:    无Modify:    2017-09-13"""class downloader(object):    def __init__(self):        self.server = 'http://www.biqukan.com/'        self.target = 'http://www.biqukan.com/1_1094/'        self.names = []            #存放章节名        self.urls = []            #存放章节链接        self.nums = 0            #章节数    """    函数说明:获取下载链接    Parameters:        无    Returns:        无    Modify:        2017-09-13    """    def get_download_url(self):        req = requests.get(url = self.target)        html = req.text        div_bf = BeautifulSoup(html)        div = div_bf.find_all('div', class_ = 'listmain')        a_bf = BeautifulSoup(str(div[0]))        a = a_bf.find_all('a')        self.nums = len(a[13:])                                #剔除不必要的章节,并统计章节数        for each in a[13:]:            self.names.append(each.string)            self.urls.append(self.server + each.get('href'))    """    函数说明:获取章节内容    Parameters:        target - 下载连接(string)    Returns:        texts - 章节内容(string)    Modify:        2017-09-13    """    def get_contents(self, target):        req = requests.get(url = target)        html = req.text        bf = BeautifulSoup(html)        texts = bf.find_all('div', class_ = 'showtxt')        texts = texts[0].text.replace('xa0'*8,'
              
              ')        return texts    """    函数说明:将爬取的文章内容写入文件    Parameters:        name - 章节名称(string)        path - 当前路径下,小说保存名称(string)        text - 章节内容(string)    Returns:        无    Modify:        2017-09-13    """    def writer(self, name, path, text):        write_flag = True        with open(path, 'a', encoding='utf-8') as f:            f.write(name + '
              ')            f.writelines(text)            f.write('
              
              ')if __name__ == "__main__":    dl = downloader()    dl.get_download_url()    print('《一年永恒》开始下载:')    for i in range(dl.nums):        dl.writer(dl.names[i], '一念永恒.txt', dl.get_contents(dl.urls[i]))        sys.stdout.write("  已下载:%.3f%%" %  float(i/dl.nums) + '
              ')        sys.stdout.flush()    print('《一年永恒》下载完成')

              很简单的程序,单进程跑,没有开进程池。下载速度略慢,喝杯茶休息休息吧。代码运行效果如下图所示:

              10


              原文作者:Jack-Cui

              原文地址:https://blog.csdn.net/c406495762/article/details/78123502


              在上一章中,我们已经学会了如何使用Python3爬虫抓取文字,那么在本章教程中,将通过实例来教大家如何使用Python3爬虫批量抓取图片。

               注:该网站目前已经更换了图片的请求方式,以下爬虫方法只能作为思路参考,已经无法运行成功,望周知!

              (1)实战背景

              1

              上图的网站的名字叫做Unsplash,免费高清壁纸分享网是一个坚持每天分享高清的摄影图片的站点,每天更新一张高质量的图片素材,全是生活中的景象作品,清新的生活气息图片可以作为桌面壁纸也可以应用于各种需要的环境。

              看到这么优美的图片,是不是很想下载啊。每张图片我都很喜欢,批量下载吧,不多爬,就下载50张好了。

              2)实战进阶

              我们已经知道了每个html标签都有各自的功能。<a>标签存放一下超链接,图片存放在哪个标签里呢?html规定,图片统统给我放到<img>标签中!既然这样,我们截取就Unsplash网站中的一个<img>标签,分析一下:

              <img alt="Snow-capped mountain slopes under blue sky" src="https://images.unsplash.com/photo-1428509774491-cfac96e12253?dpr=1&

              可以看到,<img>标签有很多属性,有alt、src、class、style属性,其中src属性存放的就是我们需要的图片保存地址,我们根据这个地址就可以进行图片的下载。

              那么,让我们先捋一捋这个过程:

              • 使用requeusts获取整个网页的HTML信息;
              • 使用Beautiful Soup解析HTML信息,找到所有<img>标签,提取src属性,获取图片存放地址;
              • 根据图片存放地址,下载图片。

              我们信心满满地按照这个思路爬取Unsplash试一试,编写代码如下:

              # -*- coding:UTF-8 -*-import requestsif __name__ == '__main__':     target = 'https://unsplash.com/'     req = requests.get(url=target)     print(req.text)

              按照我们的设想,我们应该能找到很多<img>标签。但是我们发现,除了一些<script>标签和一些看不懂的代码之外,我们一无所获,一个<img>标签都没有!跟我们在网站审查元素的结果完全不一样,这是为什么?

              答案就是,这个网站的所有图片都是动态加载的!网站有静态网站和动态网站之分,上一个实战爬取的网站是静态网站,而这个网站是动态网站,动态加载有一部分的目的就是为了反爬虫。

              对于什么是动态加载,你可以这样理解:我们知道化妆术学的好,贼厉害,可以改变一个人的容貌。相应的,动态加载用的好,也贼厉害,可以改变一个网站的容貌。

              动态网站使用动态加载常用的手段就是通过调用JavaScript来实现的。怎么实现JavaScript动态加载,我们不必深究,我们只要知道,动态加载的JavaScript脚本,就像化妆术需要用的化妆品,五花八门。有粉底、口红、睫毛膏等等,它们都有各自的用途。动态加载的JavaScript脚本也一样,一个动态加载的网站可能使用很多JavaScript脚本,我们只要找到负责动态加载图片的JavaScript脚本,不就找到我们需要的链接了吗?

              对于初学者,我们不必看懂JavaScript执行的内容是什么,做了哪些事情,因为我们有强大的抓包工具,它自然会帮我们分析。这个强大的抓包工具就是Fiddler:http://www.telerik.com/fiddler

              PS:也可以使用浏览器自带的Networks,但是我更推荐这个软件,因为它操作起来更高效。

              安装方法很简单,傻瓜式安装,一直下一步即可,对于经常使用电脑的人来说,应该没有任何难度。

              这个软件的使用方法也很简单,打开软件,然后用浏览器打开我们的目标网站,以Unsplash为例,抓包结果如下:

              3

              我们可以看到,上图左侧红框处是我们的GET请求的地址,就是网站的URL,右下角是服务器返回的信息,我们可以看到,这些信息也是我们上一个程序获得的信息。这个不是我们需要的链接,我们继续往下看。

              4

              我们发现上图所示的就是一个JavaScript请求,看右下侧服务器返回的信息是一个json格式的数据。这里面,就有我们需要的内容。我们局部放大看一下:

              5

              这是Fiddler右侧的信息,上面是请求的Headers信息,包括这个Javascript的请求地址:http://unsplash.com/napi/feeds/home,其他信息我们先不管,我们看看下面的内容。里面有很多图片的信息,包括图片的id,图片的大小,图片的链接,还有下一页的地址。这个脚本以json格式存储传输的数据,json格式是一种轻量级的数据交换格式,起到封装数据的作用,易于人阅读和编写,同时也易于机器解析和生成。这么多链接,可以看到图片的链接有很多,根据哪个链接下载图片呢?先别急,让我们继续分析:

              QQ截图20180517155307

              在这个网站,我们可以按这个按钮进行图片下载。我们抓包分下下这个动作,看看发送了哪些请求。

              https://unsplash.com/photos/1PrQ2mHW-Fo/download?force=truehttps://unsplash.com/photos/JX7nDtafBcU/download?force=truehttps://unsplash.com/photos/HCVbP3zqX4k/download?force=true

              通过Fiddler抓包,我们发现,点击不同图片的下载按钮,GET请求的地址都是不同的。但是它们很有规律,就是中间有一段代码是不一样的,其他地方都一样。中间那段代码是不是很熟悉?没错,它就是我们之前抓包分析得到json数据中的照片的id。我们只要解析出每个照片的id,就可以获得图片下载的请求地址,然后根据这个请求地址,我们就可以下载图片了。那么,现在的首要任务就是解析json数据了。

              json格式的数据也是分层的。可以看到next_page里存放的是下一页的请求地址,很显然Unsplash下一页的内容,也是动态加载的。在photos下面的id里,存放着图片的id,这个就是我们需要获得的图片id号。

              怎么编程提取这些json数据呢?我们也是分步完成:

              • 获取整个json数据
              • 解析json数据

              编写代码,尝试获取json数据:

              # -*- coding:UTF-8 -*-import requestsif __name__ == '__main__':     target = 'http://unsplash.com/napi/feeds/home'     req = requests.get(url=target) print(req.text)

              很遗憾,程序报错了,问题出在哪里?通过错误信息,我们可以看到SSL认证错误,SSL认证是指客户端到服务器端的认证。一个非常简单的解决这个认证错误的方法就是设置requests.get()方法的verify参数。这个参数默认设置为True,也就是执行认证。我们将其设置为False,绕过认证不就可以了?

              6

              有想法就要尝试,编写代码如下:

              # -*- coding:UTF-8 -*-import requestsif __name__ == '__main__':     target = 'http://unsplash.com/napi/feeds/home'     req = requests.get(url=target, verify=False)     print(req.text)

              认证问题解决了,又有新问题了:

              7

              可以看到,我们GET请求又失败了,这是为什么?这个网站反爬虫的手段除了动态加载,还有一个反爬虫手段,那就是验证Request Headers。接下来,让我们分析下这个Requests Headers:

              8

              我截取了Fiddler的抓包信息,可以看到Requests Headers里又很多参数,有Accept、Accept-Encoding、Accept-Language、DPR、User-Agent、Viewport-Width、accept-version、Referer、x-unsplash-client、authorization、Connection、Host。它们都是什么意思呢?

              专业的解释能说的太多,我挑重点:

              • User-Agent:这里面存放浏览器的信息。可以看到上图的参数值,它表示我是通过Windows的Chrome浏览器,访问的这个服务器。如果我们不设置这个参数,用Python程序直接发送GET请求,服务器接受到的User-Agent信息就会是一个包含python字样的User-Agent。如果后台设计者验证这个User-Agent参数是否合法,不让带Python字样的User-Agent访问,这样就起到了反爬虫的作用。这是一个最简单的,最常用的反爬虫手段。
              • Referer:这个参数也可以用于反爬虫,它表示这个请求是从哪发出的。可以看到我们通过浏览器访问网站,这个请求是从https://unsplash.com/,这个地址发出的。如果后台设计者,验证这个参数,对于不是从这个地址跳转过来的请求一律禁止访问,这样就也起到了反爬虫的作用。
              • authorization:这个参数是基于AAA模型中的身份验证信息允许访问一种资源的行为。在我们用浏览器访问的时候,服务器会为访问者分配这个用户ID。如果后台设计者,验证这个参数,对于没有用户ID的请求一律禁止访问,这样就又起到了反爬虫的作用。

              Unsplash是根据哪个参数反爬虫的呢?根据我的测试,是authorization。我们只要通过程序手动添加这个参数,然后再发送GET请求,就可以顺利访问了。怎么什么设置呢?还是requests.get()方法,我们只需要添加headers参数即可。编写代码如下:

              # -*- coding:UTF-8 -*-import requestsif __name__ == '__main__':     target = 'http://unsplash.com/napi/feeds/home'     headers = {'authorization':'your Client-ID'}     req = requests.get(url=target, headers=headers, verify=False)     print(req.text)

              headers参数值是通过字典传入的。记得将上述代码中your Client-ID换成诸位自己抓包获得的信息。代码运行结果如下:

              9

              皇天不负有心人,可以看到我们已经顺利获得json数据了,里面有next_page和照片的id。接下来就是解析json数据。根据我们之前分析可知,next_page放在了json数据的最外侧,照片的id放在了photos->id里。我们使用json.load()方法解析数据,编写代码如下:

              # -*- coding:UTF-8 -*-import requests, jsonif __name__ == '__main__':     target = 'http://unsplash.com/napi/feeds/home'     headers = {'authorization':'your Client-ID'}     req = requests.get(url=target, headers=headers, verify=False)     html = json.loads(req.text)     next_page = html['next_page']     print('下一页地址:',next_page)     for each in html['photos']:          print('图片ID:',each['id'])

              解析json数据很简单,跟字典操作一样,就是字典套字典。json.load()里面的参数是原始的json格式的数据。程序运行结果如下:

              10

              图片的ID已经获得了,再通过字符串处理一下,就生成了我们需要的图片下载请求地址。根据这个地址,我们就可以下载图片了。下载方式,使用直接写入文件的方法。

              (3)整合代码

              每次获取链接加一个1s延时,因为人在浏览页面的时候,翻页的动作不可能太快。我们要让我们的爬虫尽量友好一些。

              # -*- coding:UTF-8 -*-import requests, json, time, sysfrom contextlib import closingclass get_photos(object):    def __init__(self):        self.photos_id = []        self.download_server = 'https://unsplash.com/photos/xxx/download?force=trues'        self.target = 'http://unsplash.com/napi/feeds/home'        self.headers = {'authorization':'Client-ID c94869b36aa272dd62dfaeefed769d4115fb3189a9d1ec88ed457207747be626'}    """    函数说明:获取图片ID    Parameters:        无    Returns:        无    Modify:        2017-09-13    """       def get_ids(self):        req = requests.get(url=self.target, headers=self.headers, verify=False)        html = json.loads(req.text)        next_page = html['next_page']        for each in html['photos']:            self.photos_id.append(each['id'])        time.sleep(1)        for i in range(5):            req = requests.get(url=next_page, headers=self.headers, verify=False)            html = json.loads(req.text)            next_page = html['next_page']            for each in html['photos']:                self.photos_id.append(each['id'])            time.sleep(1)    """    函数说明:图片下载    Parameters:        无    Returns:        无    Modify:        2017-09-13    """       def download(self, photo_id, filename):        headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36'}        target = self.download_server.replace('xxx', photo_id)        with closing(requests.get(url=target, stream=True, verify = False, headers = self.headers)) as r:            with open('%d.jpg' % filename, 'ab+') as f:                for chunk in r.iter_content(chunk_size = 1024):                    if chunk:                        f.write(chunk)                        f.flush()if __name__ == '__main__':    gp = get_photos()    print('获取图片连接中:')    gp.get_ids()    print('图片下载中:')    for i in range(len(gp.photos_id)):        print('  正在下载第%d张图片' % (i+1))        gp.download(gp.photos_id[i], (i+1))

              下载速度还行,有的图片下载慢是因为图片太大。可以看到右侧也打印了一些警报信息,这是因为我们没有进行SSL验证。

              20170930130019403


              原文作者:Jack-Cui

              原文地址:https://blog.csdn.net/c406495762/article/details/78123502


              在前面的两个实例中,我们分别为大家演示使用Python3爬虫抓取文字和图片的方法,那么在本篇教程中,将继续教大家如何用Python3爬虫抓取视频。


              (1)实战背景

              爱奇艺的VIP视频只有会员能看,普通用户只能看前6分钟。那么我们怎么免费看VIP视频呢?一个简单的方法,就是通过旋风视频VIP解析网站。

              这个网站为我们提供了免费的视频解析,它的通用解析方式是:

              http://api.xfsub.com/index.php?url=[播放地址或视频id]

              比如,对于绣春刀这个电影,我们只需要在浏览器地址栏输入:

              http://api.xfsub.com/index.php?url=http://www.iqiyi.com/v_19rr7qhfg0.html#vfrm=19-9-0-1

              这样,我们就可以在线观看这些VIP视频了:

              1

              但是这个网站只提供了在线解析视频的功能,没有提供下载接口,如果想把视频下载下来,我们就可以利用网络爬虫进行抓包,将视频下载下来。

              (2)实战升级

              分析方法相同,我们使用Fiddler进行抓包:

              2

              我们可以看到,有用的请求并不多,我们逐条分析。我们先看第一个请求返回的信息。

              3

              可以看到第一个请求是GET请求,没有什么有用的信息,继续看下一条。

              4

              我们看到,第二条GET请求地址变了,并且在返回的信息中,我们看到,这个网页执行了一个POST请求。POST请求是啥呢?它跟GET请求正好相反,GET是从服务器获得数据,而POST请求是向服务器发送数据,服务器再根据POST请求的参数,返回相应的内容。这个POST请求有四个参数,分别为time、key、url、type。记住这个有用的信息,我们在抓包结果中,找一下这个请求,看看这个POST请求做了什么。

              5

              很显然,这个就是我们要找的POST请求,我们可以看到POST请求的参数以及返回的json格式的数据。其中url存放的参数如下:

              xfsub_api/url.php?key=02896e4af69fb18f70129b6046d7c718&time=1505724557&url=http%3A%2F%2Fwww.iqiyi.com%2Fv_19rr7qhfg0.html&type=&xml=1

              这个信息有转义了,但是没有关系,我们手动提取一下,变成如下形式:

              xfsub_api/url.php?key=02896e4af69fb18f70129b6046d7c718&time=1505724557&url=http://www.iqiyi.com/v_19rr7qhfg0.html&type=&xml=1

              我们已经知道了这个解析视频的服务器的域名,再把域名加上:

              http://api.xfsub.com/xfsub_apiurl.php?key=02896e4af69fb18f70129b6046d7c718&time=1505724557&url=http://www.iqiyi.com/v_19rr7qhfg0.html&type=&xml=1

              这里面存放的是什么东西?不会视频解析后的地址吧?我们有浏览器打开这个地址看一下:

              6

              我们再打开这个视频地址:

              7

              瞧,我们就这样得到了这个视频在服务器上的缓存地址。根据这个地址,我们就可以轻松下载视频了。

              PS:需要注意一点,这些URL地址,都是有一定时效性的,很快就会失效,因为里面包含时间信息。所以,各位在分析的时候,要根据自己的URL结果打开网站才能看到视频。

              接下来,我们的任务就是编程实现我们所分析的步骤,根据不同的视频播放地址获得视频存放的地址。

              现在梳理一下编程思路:

              • 用正则表达式匹配到key、time、url等信息。
              • 根据匹配的到信息发POST请求,获得一个存放视频信息的url。
              • 根据这个url获得视频存放的地址。
              • 根据最终的视频地址,下载视频。

              (3)编写代码

              编写代码的时候注意一个问题,就是我们需要使用requests.session()保持我们的会话请求。简单理解就是,在初次访问服务器的时候,服务器会给你分配一个身份证明。我们需要拿着这个身份证去继续访问,如果没有这个身份证明,服务器就不会再让你访问。这也就是这个服务器的反爬虫手段,会验证用户的身份。

              #-*- coding:UTF-8 -*-import requests,re, jsonfrom bs4 import BeautifulSoupclass video_downloader():    def __init__(self, url):        self.server = 'http://api.xfsub.com'        self.api = 'http://api.xfsub.com/xfsub_api/?url='        self.get_url_api = 'http://api.xfsub.com/xfsub_api/url.php'        self.url = url.split('#')[0]        self.target = self.api + self.url        self.s = requests.session()    """    函数说明:获取key、time、url等参数    Parameters:        无    Returns:        无    Modify:        2017-09-18    """    def get_key(self):        req = self.s.get(url=self.target)        req.encoding = 'utf-8'        self.info = json.loads(re.findall('"url.php", (.+),', req.text)[0])    #使用正则表达式匹配结果,将匹配的结果存入info变量中    """    函数说明:获取视频地址    Parameters:        无    Returns:        video_url - 视频存放地址    Modify:        2017-09-18    """    def get_url(self):        data = {'time':self.info['time'],            'key':self.info['key'],            'url':self.info['url'],            'type':''}        req = self.s.post(url=self.get_url_api,data=data)        url = self.server + json.loads(req.text)['url']        req = self.s.get(url)        bf = BeautifulSoup(req.text,'xml')                                        #因为文件是xml格式的,所以要进行xml解析。        video_url = bf.find('file').string                                        #匹配到视频地址        return video_urlif __name__ == '__main__':     url = 'http://www.iqiyi.com/v_19rr7qhfg0.html#vfrm=19-9-0-1'     vd = video_downloader(url)     vd.get_key()     print(vd.get_url())

              思路已经给出,希望喜欢爬虫的人可以在运行下代码之后,自己重头编写程序,因为只有经过自己分析和测试之后,才能真正明白这些代码的意义。上述代码运行结果如下:

              8

              我们已经顺利获得了mp4这个视频文件地址。根据视频地址,使用urllib.request.urlretrieve()即可将视频下载下来。编写代码如下:

              #-*- coding:UTF-8 -*-import requests,re, json, sysfrom bs4 import BeautifulSoupfrom urllib import requestclass video_downloader():    def __init__(self, url):        self.server = 'http://api.xfsub.com'        self.api = 'http://api.xfsub.com/xfsub_api/?url='        self.get_url_api = 'http://api.xfsub.com/xfsub_api/url.php'        self.url = url.split('#')[0]        self.target = self.api + self.url        self.s = requests.session()    """    函数说明:获取key、time、url等参数    Parameters:        无    Returns:        无    Modify:        2017-09-18    """    def get_key(self):        req = self.s.get(url=self.target)        req.encoding = 'utf-8'        self.info = json.loads(re.findall('"url.php", (.+),', req.text)[0])    #使用正则表达式匹配结果,将匹配的结果存入info变量中    """    函数说明:获取视频地址    Parameters:        无    Returns:        video_url - 视频存放地址    Modify:        2017-09-18    """    def get_url(self):        data = {'time':self.info['time'],            'key':self.info['key'],            'url':self.info['url'],            'type':''}        req = self.s.post(url=self.get_url_api,data=data)        url = self.server + json.loads(req.text)['url']        req = self.s.get(url)        bf = BeautifulSoup(req.text,'xml')                                        #因为文件是xml格式的,所以要进行xml解析。        video_url = bf.find('file').string                                        #匹配到视频地址        return video_url    """    函数说明:回调函数,打印下载进度    Parameters:        a b c - 返回信息    Returns:        无    Modify:        2017-09-18    """    def Schedule(self, a, b, c):        per = 100.0*a*b/c        if per > 100 :            per = 1        sys.stdout.write("  " + "%.2f%% 已经下载的大小:%ld 文件大小:%ld" % (per,a*b,c) + '
              ')        sys.stdout.flush()    """    函数说明:视频下载    Parameters:        url - 视频地址        filename - 视频名字    Returns:        无    Modify:        2017-09-18    """    def video_download(self, url, filename):        request.urlretrieve(url=url,filename=filename,reporthook=self.Schedule)if __name__ == '__main__':    url = 'http://www.iqiyi.com/v_19rr7qhfg0.html#vfrm=19-9-0-1'    vd = video_downloader(url)    filename = '加勒比海盗5'    print('%s下载中:' % filename)    vd.get_key()    video_url = vd.get_url()    print('  获取地址成功:%s' % video_url)    vd.video_download(video_url, filename+'.mp4')    print('
              下载完成!')

              urlretrieve()有三个参数,第一个url参数是视频存放的地址,第二个参数filename是保存的文件名,最后一个是回调函数,它方便我们查看下载进度。代码量不大,很简单,主要在于分析过程。代码运行结果如下:

              20170930130818192

               由于爬虫时效性低,同样的思路过了一个月,甚至一周可能无法使用,但是爬取思路都是如此,完全可以自行分析。

              原文作者:Jack-Cui

              原文地址:https://blog.csdn.net/c406495762/article/details/78123502


              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏

              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              赋闲在家几天,想鼓捣点简单又好玩的脚本分享给大家,于是就有了这篇文章~~~

              本文将利用Python记录微信好友/微信群中他人撤回的消息,并将这些消息通过文件传输助手发送到自己的手机上。

              让我们愉快地开始吧~~~

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/1UdTXIXy4iGes24zv9YBIZg 

              密码: j43u

              开发工具

              Python版本:3.6.4

              相关模块

              itchat模块;

              以及一些Python自带的模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              原理简介

              思路比较简单,利用itchat模块登录网页版微信,将自己微信收到的所有消息都缓存下来,当检测到有消息撤回时,将撤回消息的缓存版本通过文件传输助手发送到自己的手机上。

              因此,你必须保证脚本24小时运行才可以一直监视别人有没有撤回消息。

              具体实现过程详见相关文件中的源代码。

              使用演示

              Windows系统:

              手机端:

              视频链接

              Linux系统:

              手机端:

              视频链接

              1.微信撤回消息实现原理

              我们先来了解一下微信撤回消息的原理:

              其实微信撤回消息原理就是操作者在点击撤回的时候,客户端会自动发一条系统消息:“xxx撤回了一条消息”,然后对方app端收到消息后解析,替换原消息,改个显示的样式即可

              猪哥给大家演示一下正常消息撤回消息的内容到底有什么区别:
              正常消息:Content='你好骚啊',大家留意一下MsgId='8784390488772995470'

              撤回消息:Content是一串xml格式的内容

              我们在下面把它格式化看看

              <sysmsg type="revokemsg">
              <revokemsg>
              <session>xxx</session>
              <oldmsgid>1090336364</oldmsgid>
              <msgid>8784390488772995470</msgid>
              <replacemsg><![CDATA["猪哥" 撤回了一条消息]]></replacemsg>
              </revokemsg></sysmsg>

              分析上面撤回的Content字段我们发现<msgid>8784390488772995470</msgid>的id与我们之前发送消息的id是一致的,而<replacemsg>这个标签也验证了我们的猜想,确实是用新消息替换原消息。

              2.找到被撤回消息

              根据抓取正常消息撤回消息的内容我们发现规则:撤回消息中会包含之前被撤回的那条消息的msgid,那我们只要找到之前那条消息就可以了,而wxpy模块默认为我们缓存了最近的200条消息,所以我们只要遍历这些历史消息然后比较msgid就可以找到被撤回的那条消息啦!
               如果你微信消息太过频繁,2分钟之内消息数量超过200,则可以将max_history设置大些。

              3.转发被撤回消息

              原理也搞懂了,被撤回的消息也找到了,就差最后一步转发消息了,如果你之前玩过wxpy肯定会了吧,只要一行代码就可以将消息转发:

              msg.forward(bot.file_helper)

              4.代码

              原理和过程讲完了,代码贴出来给大家看看,注释还是比较详细,有不懂得话可以在学习群中问我。

              四、功能验证

              五、总结

              微信消息防撤回功能实现简单,但实用性很好,目前项目的唯一缺点就是易用性差,简单说就是我们还没有将项目部署服务器,每次使用都得打开电脑然后运行还得一直开着,猪哥考虑后面将项目部署在云服务器上或者打包成apk,这样就使用起来就非常方便了,而且还可以把apk发给朋友,让朋友也体验此功能!

              学会这招,再也不用好奇对方到底撤回了啥消息,快下载项目试试吧!下载项目后可直接运行不需要修改代码

              Github项目地址:https://github.com/pig6/wxrobot
              wxpy官方文档:https://wxpy.readthedocs.io/zh/latest

              更多

              代码截止2018-06-25测试无误。

              T_T这个脚本是完全合法无害的,只不过把自己收到的所有消息全部缓存下来,以防止别人撤回消息后自己看不到罢了。

              不过应该也没人会无聊到把脚本放服务器上跑来监视自己的好友有没有撤回消息吧~~~

              所以就纯当技(无)术(聊)交(取)流(乐)了?


              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏

              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              利用Python爬取豆瓣读书的一些数据,并对这些数据做一定的分析。

              标题可能改成类似“大数据时代如何科学有效地阅读”这样的题目更加引入瞩目吧,hhhhh。

              ——>

              对过程不感兴趣的同学可以直接下拉到最后看结果~~~

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/1N8mWiDtf7WeBt-lxVPL1_g

              密码: s4xb

              主要思路

              利用Python的requests模块和beautifulsoup模块来爬取豆瓣读书的数据,并对这些数据做一定的分析。

              爬取的数据包括:

              豆瓣图书各个分类中所有书籍的'书名', '作者/译者', '出版信息', '星级', '评分', '评价人数', '简介', '相应的豆瓣链接'。

              例如:


              同时,通过爬取的豆瓣链接对具体书籍的质量做一定的分析,分析包括

              制作热评词云、对热评进行简单的情感分析。

              有需要者可自行修改源代码进行更多的数据分析

              说明

              (1)因为豆瓣严格限制爬虫,且实际使用时也没有必要爬取所有分类的图书资料,给豆瓣服务器带来不必要的压力,因此我给出的源代码一次仅能爬取一个小类的图书资料,且为单进程。

              (2)在相关文件中,本人已经提供了爬取到的上百个分类的几万本图书数据,供有需要者参考。

              PS:

              建筑、漫画、日本漫画、耽美这四个小类的数据写入excel时抛出异常,因此暂时无法提供数据。

              开发工具

              Python版本:3.5.4

              相关模块

              requests模块、jieba模块、BeautifulSoup模块、openpyxl模块、matplotlib模块、wordcloud模块、snownlp模块以及一些Python自带的模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              前期准备

              以chrome浏览器为例。



              使用演示1

              演示内容:

              爬取某个小类所有相关书籍基本信息。

              截图如下:


              按照提示进行输入,输入完成后按下回车键即可。

              最后结果将保存在results文件夹中:


              结果展示1

              分析内容为

              挑选其中几类利用excel的统计功能对获得的数据进行简单的分析。

              以名著类为例:

              评分分布图:


              评分Top10:

              世界童话名著连环画

              坂田荣男围棋全集(共12册)

              世界文学名著连环画 欧美部分(全十册)

              三国演义

              细说红楼梦 1-80回

              世界文学名著连环画(亚非部分全五册)

              算术探索 

              三国演义(绘画本1-5) 

              四大名著(套装全4册)

              红楼梦

              热度(评论人数)Top10:

              围城

              不能承受的生命之轻

              红楼梦

              百年孤独

              简爱

              傲慢与偏见

              月亮和六便士

              边城

              霍乱时期的爱情

              更多内容请自行下载相关文件中提供的数据根据个人喜好进行分析选择。

              使用演示2

              演示内容为:

              对具体书籍制作豆瓣热评词云并对豆瓣热评进行简单的情感分析。

              截图如下:


              链接地址都保存到了excel表中,复制粘贴即可。

              如下图所示:


              结果展示2

              分析内容为

              爬取豆瓣读书中具体一本书的前20页短评,并制作成词云,同时对这些短评进行简单的情感分析。

              以《统计学习方法》为例:

              词云:



              情感分析:



              数值较大说明情感偏积极,否则情感偏消极。

              更多

              本人不是专业做数据分析的~~~

              所以分析的有些稚嫩~~~

              欢迎专业人士指导补充~~~


              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏

              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              利用Python为自己喜欢的音乐制作专属词云。至于词的来源嘛,当然是对应歌曲的所有评论或者热门评论啦!!!毕竟网易云音乐最得意的大概就是那些刷了我朋友圈n多遍的评论了吧~~~


              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/16GpVk4EDq9hMYZeBoYZmFQ 

              密码: dhm4


              主要思路

              利用Python爬取网易云音乐中相应歌曲的所有评论,并利用这些评论制作歌曲的专属词云。

              具体过程见相关文件中的源代码。


              开发工具

              Python版本:3.5.4

              相关模块:

              requests模块、jieba模块、scipy模块、wordcloud模块、pycrypto模块、selenium模块以及一些Python自带的模块。

              chromedriver_win32版本:2.3.4

              chrome版本:65.0.3298.4


              环境搭建

              (1)安装Python(添加到环境变量)并pip安装相关模块;

              (2)安装chrome浏览器,并将相关文件中提供的chromedriver.exe文件放在python安装文件夹中的Scripts文件夹内。

              PS:

              (1)若chromedriver.exe文件放在其他文件夹,则需将对应文件夹路径添加到环境变量中!

              (2)部分相关模块我在相关文件中提供了编译好的whl文件,使用pip+whl文件路径+whl文件名安装即可。


              使用方式

              在cmd窗口运行并根据提示输入就可以啦~~~


              使用演示

              利用歌曲热门评论制作词云:

              利用歌曲所有评论制作词云:

              更多

              (1)因为是单进程,所以当评论较多时生成图云的速度会比较慢,因此请慎重选择用所有评论制作词云(昨天晚上多线程跑到一半被封了T_T);

              (2)后续会有更多关于网易云音乐的内容,这算是初次试水吧,毕竟要从自己最喜欢的东西做起。

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏

              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              翻了翻之前关于爬虫的文章。。。

              似乎一直在欺负小网站,没什么挑战性。。。

              那么,就来“试水”一波TX吧~~~

              本着细水长流(偷懒)的原则T_T,这期文章我决定拆成两篇写。第一篇主要解决QQ空间的登录问题并尝试抓取一些信息,第二篇致力于抓取QQ空间的好友信息并做可视化分析。

              让我们愉快地开始吧~~~

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/1D3C5cSp7YhuTooPJa7znjw 

              密码: yccp

              开发工具

              Python版本:3.6.4

              相关模块:

              requests模块;

              selenium模块;

              lxml模块;

              以及一些Python自带的模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块,并前往:

              http://npm.taobao.org/mirrors/chromedriver/

              下载与自己使用的Chrome浏览器版本对应的驱动文件,下载完毕后将chromedriver.exe所在文件夹添加到环境变量中即可。

              原理简介

              本文主要解决QQ空间的登录问题。

              其主要思路为:

              利用selenium模拟登录QQ空间从而获取登录QQ空间所需的cookie值,这样就可以利用requests模块来抓取QQ空间的数据了。

              为什么这么绕?

              selenium好久不用,写起来太慢了。而且它本身速度和资源占用等问题一直为大家所诟病。

              And 省略无数条理由。

              一些细节:

              (1)第一次获取cookie之后将其保存下来,下次再登录之前先试试保存的cookie有没有用,有用直接使用就可以了,这样可以进一步节省时间。

              (2)抓包分析过程中,可以发现抓取QQ空间数据所需请求的链接都包含g_tk这个参数,这个参数实际上是使用cookie中的skey参数计算获得的,懒得打公式了,直接贴一小段代码吧:

              最后:

              不抓点数据好像不能证明这篇文章真的有用?

              好吧,那就把:

              扒下来吧~~~

              具体实现过程详见相关文件中的源代码。

              使用演示

              QQ号(username)和密码(password):

              在QQ_Spider.py文件中填写,位置如下图所示:

              运行:

              在cmd窗口运行QQ_Spider.py文件即可。

              结果:

              That's All.

              下期预告

              在本期基础上抓取好友的个人信息,并可视化分析抓取的结果。有兴趣的小伙伴可以提前试试~~~

              事实上,微调本文所提供的代码,理论上是可以抓取QQ所有用户的信息的。当然,只是理论上,以及干很多有趣的事情。

              T_T作为一个不搞事且不爱喝茶的boy,上述的理论我就不负责实现了。

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏

              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              内容回顾:

              Python爬取QQ空间信息(上)

              按照(上)中的安排,本期内容为抓取QQ空间的好友信息并做可视化分析。

              不过图省事,我只抓取了我关心和关心我的好友信息。

              那就让我们愉快地开始吧~~~

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/1_4Gmoc06wAWOsRSyMbPuvw 

              密码: fy5n

              开发工具

              Python版本:3.6.4

              相关模块:requests模块;selenium模块;lxml模块;pyecharts模块;以及一些Python自带的模块。

              环境搭建

              Python爬取QQ空间信息(上)

              pyecharts模块安装参见:

              Python简单分析微信好友。

              原理简介

              T_T

              空间都登录了,剩下的就是分析数据包,找到需要的接口来获取需要的数据并分析呗。。。

              PS:

              公众号提供的脚本只能抓取你有权限访问的数据。换句话说,就是你能看到的合法数据。

              所有脚本仅供学习交流。

              其他你们想的很美的要求,想想就行了T_T

              具体实现过程详见相关文件中的源代码。

              使用方式

              在cmd窗口运行QQ_Spider.py文件即可。

              结果展示

              借了一个玉树临风、面如冠玉、仪表不凡的小哥的QQ号做的分析QAQ。

              qq好友男女比例:

              qq好友年龄分布:

              qq好友位置分布:

              That's All.

              更多

              代码截止2018-06-03测试无误。

              事实上,本文提供的脚本可抓取的好友信息并不是仅有结果展示中的那些:

              T_T我只是懒得一个个可视化了。。。

              So,有兴趣的朋友可以自己去可视化好友的其他信息。嗯,就这样吧。

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              利用Python简单爬取美团美食板块商家数据。。。

              其实一开始我是想把美团的所有商家信息爬下来的,这样就可以美其名曰百万数据了。。。

              然而相信很多爬过美团的朋友都发现了。。。

              如果不进行一些小操作。。。

              爬不了几页代码就GG了。。。

              后来想想我要这么多数据也没什么用。。。

              唯一对我有用的。。。

              大概就是美食板块了。。。

              以后用到其他板块的时候再另外爬就好了。。。

              OK,Let's go!

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/19FPe8OFVwVa_LvuHjYnB9w 

              密码: 3pbr

              主要思路

              目的:

              根据输入的城市名,爬取该城市美团美食板块所有商家的数据。数据包括:

              店名、评分、评论数量、均价、地址,

              并将这些数据存入Excel中。

              最后尝试对爬取到的数据做一个简单的分析。

              克服反爬虫:

              爬取每页数据后,随机停止一段时间后再爬下一页;

              每页使用不同的cookie值。

              具体原理:

              没用抓包软件。。。

              Chrome打开后看了下xhr。。。

              发现直接有接口可以用。。。

              给个cookie就能返回所需的数据了。。。

              后来随便点了几个其他板块的网页。。。

              发现也差不多是这个套路。。。

              详细的实现过程见源代码。

              开发工具

              Python版本:3.5.4

              相关模块:requests模块;win_unicode_console模块;openpyxl模块;以及一些Python自带的模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              使用演示

              在cmd窗口运行MT_Cate_Spider.py文件即可。

              简单分析

              其实在码字的时候我临时加的这个部分。。。

              原因很简单。。。

              我想强调爬虫和数据分析结合的重要性。。。

              数据不多,懒得写代码分析了。。。

              利用Excel的数据分析功能简单分析一波吧~~~

              用的上海地区的数据。

              首先当然是按照评分排个序,然后做成柱状图:

              然后是评论数量排个序,做成柱状图:

              然后再做点其他有趣的图案:

              OK,That's all!

              更多

              如果有需要,我会写一个爬取美团所有商家信息的脚本,因为就如之前所说。。。

              貌似都有直接可以用的接口。。。

              所以还算比较简单。。。

              只要弄到足够多的cookie值就好了。。。

              当然这个Flag应该是要到我实在没东西写或者懒得重新踩点的时候才会去实现了吧。。。

              就这样吧~~~

              有兴趣的朋友可以试着去抓其他板块的数据。。。

              貌似挺easy的。。。

              小心别被封了就好了。。。

              代码截止2018-02-25测试无误。

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              T_T 愚人节似乎不宜出门?

              那就爬波猫眼电影看看有什么值得看的电影?

              于是T_T

              大概是没什么技术含量的~~~

              Let's Go!!!

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/1WJ8PL5nydttXjteQOWqRrg 

              密码: v78a

              开发工具

              Python版本:3.6.4

              相关模块:openpyxl模块;requests模块;win_unicode_console模块;bs4模块;以及一些Python自带的模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              主要思路

              目的:

              爬取http://maoyan.com/films中的电影信息:

              其中要爬取的内容为:

              电影名、电影评分、电影介绍页链接以及电影简介。

              思路:

              先爬取电影名、电影评分和电影介绍页链接,再根据电影介绍页链接爬取电影简介。

              这么算下来,一页30部电影,需要31个requests。

              结果只是为了爬这么点数据,效率可想而知T_T

              最后把爬到的数据存入Excel中。

              具体实现方式详见相关文件中的源代码。

              补充说明

              (1)cookies.py文件中的cookie获取方式

              按上图所示方式获得cookie值后填入cookies.py文件的相关位置中:

              第一个Cookies列表是不含登录信息的cookie;

              第二个login_Cookies列表是含登录信息的cookie。

              含登录信息的cookie获取方式和不含登录信息的cookie获取方式相同,但是需要事先在网页上登录(登录选项在网页的右上角)。

              (2)关于猫眼的反爬虫

              猫眼电影的反爬虫机制十分到位。T_T

              首先是对于非登录用户,你只能查看前100页的电影信息。其次,如果你的请求过于频繁,是会被封的:

              经过测试,得到的结论如下:

              设置随机的时间间隔并不有效防止ip被封;

              更换cookie值无法防止ip被封;

              爬取20页左右的电影数据后代码就GG了等等。

              没有仔细研究猫眼电影是如何识别爬虫的。

              但是可以感觉出其识别机制很智能。

              比如我被封之后想尝试通过更换ip解决,但是我发现更换ip地址之后可以获取的数据量竟然比前一个ip少了很多。

              因此,本人提供的正版源代码没有想过和猫眼的维护人员斗智斗勇,只是加了个随机的时间间隔。可以爬取的数据量在25页左右。选个电影而已,不想搞这么复杂。斗智斗勇的结果可能就是验证码输入越来越麻烦,给网站带来不必要的压力,影响正常用户的使用体验等等。弊大于利。

              反爬虫解决方案

              为了不让爬虫爱好者失望,还是稍微提一下吧~~~

              网上关于反爬虫机制的解决方案很多,比如使用代理池之类的等等。

              本人只是针对猫眼电影信息爬取过程中存在的反爬虫机制提出一项解决方案。

              方案很简单,它不就是想让我们输入验证码来证明我们是人嘛~~~那就证明给它看咯。

              简单测试后可以发现:

              只要把识别之后的验证码和一些其他参数以post的方式请求:

              http://maoyan.com/films?__oceanus_captcha=1

              这个链接就可以解除ip封锁~~~

              很简单。

              我在相关文件中提供了一个测试版本(test.py)。

              至于验证码获取的接口以及验证码如何自动识别,我就不一一介绍了,测试版本里也没有(源代码里获取验证码的接口只是临时接口,所以不是一个普适的版本)。。。

              感兴趣的同学可以自己研究一下~~~

              挺简单的,方案也很多T_T,但是为了避免别人滥用我就不公布最终的验证码破解版本了。

              使用演示

              在cmd窗口中运行MY_Spider.py文件即可。

              如下图所示(爬取20页数据):

              其中9分以上的电影有:

              摔跤吧!爸爸    

              战狼2    

              小萝莉的猴神大叔    

              厉害了,我的国    

              寻梦环游记    

              霸王别姬    

              速度与激情7    

              红海行动    

              神秘巨星    

              疯狂动物城    

              冰雪奇缘    

              泰坦尼克号    

              看不见的客人    

              泰坦尼克号3D    

              速度与激情8    

              奇迹男孩    

              缝纫机乐队    

              夏洛特烦恼    

              战狼    

              湄公河行动    

              蝙蝠侠:黑暗骑士    

              九品芝麻官    

              头号玩家    

              唐人街探案2    

              前任3:再见前任    

              帕丁顿熊2    

              公牛历险记    

              辛德勒的名单    

              一个人的课堂    

              智取威虎山    

              你的名字。    

              英雄本色    

              二十二    

              美国队长2    

              刀剑神域:序列之争    

              银河护卫队    

              变形金刚4:绝迹重生    

              我的少女时代    

              春光乍泄    

              闪光少女    

              熊出没·变形记    

              羞羞的铁拳    

              芳华    

              捉妖记    

              建军大业    

              侏罗纪世界    

              熊出没·奇幻空间    

              寻龙诀    

              末日崩塌    

              老炮儿    

              熊出没之熊心归来    

              比得兔    

              恋爱回旋    

              南极之恋    

              追龙    

              银河护卫队2    

              滚蛋吧!肿瘤君    

              美人鱼    

              唐人街探案    

              阿凡达    

              拆弹·专家    

              魔兽    

              钢铁侠3    

              蓝精灵:寻找神秘村    

              至爱梵高·星空之谜    

              爱在记忆消逝前    

              碟中谍5:神秘国度    

              傲娇与偏见    

              That'all~~~

              看电影去了~~~

              更多

              代码截止2018-04-01测试无误。

              若日后猫眼电影有较大更新,源代码将仅供参考。

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              利用Python“简单地”抓取并分析一下天气数据。

              T_T翻了翻公众号之前文章。。。

              很少有把重点放在数据可视化分析上。。。

              所以算是填补一下之前的空白吧~~~

              Let's Go!

              相关文件

              文件下载链接: https://pan.baidu.com/s/1dxoxhdu3sqAcNDUKFub0Xg 

              密码: jc52

              开发工具

              Python版本:3.6.4

              相关模块:PIL模块;requests模块;pyecharts模块;以及一些Python自带的模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              额外说明:

              pyecharts模块安装时请依次执行以下命令:

              pip install echarts-countries-pypkg

              pip install echarts-china-provinces-pypkg

              pip install echarts-china-cities-pypkg

              pip install pyecharts

              若安装过程中出现:

              'utf-8' codec can't decode byte 0xb6

              或者类似的编码错误提示。

              可尝试修改Python安装文件夹下如下图所示路径下的__init__.py文件的第75行代码:

              修改为下图所示内容:

              主要思路

              利用国家气象局和百度天气查询API接口来获取当前天气数据,主要包括温度、湿度、气压等。

              获取相关数据之后利用pyecharts模块和PIL模块对数据进行可视化分析。

              具体实现过程详见源代码。

              结果展示

              使用:

              在cmd窗口中运行analysis.py文件即可。

              要画什么图把对应的函数调用注释去掉就好啦:

              结果:

              (打开相关文件中的html文件查看效果更佳,到处点一点有惊喜~~~)

              (1)全国部分城市空气质量

              (2)天气预报简图

              (3)部分城市气温柱状图

              (4)部分城市气温折线图

              (5)部分城市相对气压饼图

              (6)部分城市气温分布图

              (7)北京城市湿度

              (8)南京天气信息雷达图

              有些是为了画图而画图了,所以看起来逻辑很怪T_T

              更多

              代码截止2018-04-08测试无误。

              Echarts作为百度开源的一个数据可视化 JS 库,功能还是十分强大的,有兴趣的朋友可以尝试去绘制一些其他有趣的图表。

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              进入正题,利用Python爬取房价信息并进行简单的数据分析。好久没发爬虫相关的内容了,想想还是抽空过来发一篇吧~~~

              Ok,让我们开始吧~~~

              相关文件

              网盘下载链接: https://pan.baidu.com/s/1fDYFmz9JqN1wcDu_wSvpbw 

              密码: 1f99

              开发工具

              Python版本:3.6.4

              相关模块:openpyxl模块;requests模块;bs4模块;pyecharts模块;以及一些python自带的模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              pyecharts模块安装可参考:

              Python简单分析微信好友

              原理简介

              需求:

              根据输入的城市名获取该城市的房价信息;

              对获得的数据进行简单的分析。

              目标网站:

              链家网(https://dl.lianjia.com/)

              目标数据(图中圈出的):

              实现思路

              很基础的爬虫,不需要任何分析。直接请求需要的网页地址,然后利用bs4模块解析请求返回的数据并获取所需的信息即可。

              然后再对这些信息进行简单的分析。

              其中信息保存到Excel中,分析时读取即可。

              具体实现细节详见相关文件中的源代码。

              数据爬取演示

              在cmd窗口运行Spider.py文件后根据提示输入相关的信息即可。

              视频演示如下:

              数据分析

              以北京为例:

              北京房价(元/平方):

              北京房价(万元/套起):

              emmmm,算了,不分析了吧。

              更多扎心的画图分析可参考:

              Python抓取并分析天气数据

              更多

              代码截止2018-05-06测试无误。

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              似乎好久没有更爬虫相关的内容了。。。

              而好多童鞋对爬虫相关的内容比较感兴趣。。。

              于是打算更一波。。。

              最近事情比较多,实在没有时间重新踩点。。。

              翻了下之前的文章,发现自己似乎说过以后还会继续爬网易云音乐相关的内容。。。

              既然如此,那就顺水推舟更一波吧~~~

              刚好不需要重新踩点T_T。。。

              Let's go!

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/184jEjKhFDNTZOYW4cxX1KA

              密码: 5suv

              主要思路

              目的:

              制作简单的网易云音乐下载器。

              至于这个下载器的是否可以“此处省略不可描述的内容”,你自己试试看咯~~~

              功能:

              根据提示输入歌曲名后下载该歌曲。

              下载的歌曲数量不大于9首。


              选取方式为类似上图所示的搜索结果的前9首歌曲。

              若搜索结果不足9首则全部下载。

              具体思路详见源代码。

              开发工具

              Python版本:3.5.4

              相关模块:

              requests模块、pycrypto模块以及一些Python自带的模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              PS:

              相关文件中提供了编译好的pycrypto模块whl文件。

              使用演示

              最近比较懒。。。

              还是放视频比较方便~~~

              Just Look!

              更多

              之前看到有人用PyQt做了一个高仿的网易云音乐客户端,忘了在哪看到了。。。

              有兴趣的朋友可以自己尝试制作一下。。。

              对GUI编程毫无兴趣的我就不打算做这个了。。。

              重要说明:

              代码截止2018-02-24测试无误,若日后网易云音乐官网有较大更新,源代码将仅供参考。

              如有其它疑问可后台私信我!

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              又是一年春运,很多地方的火车/高铁票依旧一票难求~~~于是,大家应该明白我推出这个小项目的缘由了吧~~~

              项目内容

              (1)利用python实现火车/高铁票查询功能;

              (2)利用python实现抢火车/高铁票功能;

              (3)对上述两项基本功能进行优化;

              (4)最后将两项功能集成到一个Demo,供所有专业/非专业人士使用。

              PS:

              本项目不提供细致入微的教学(如有疑问可后台私信咨询),仅讲解主要思路、环境搭建、使用方式以及最终代码(含详细注释)。

              本期内容

              实现项目内容中的前两项。

              开发工具

              python版本:3.5.4

              chromedriver_win32版本:2.3.4

              chrome版本:65.0.3298.4

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/19jgSjtuxslE-UUK3kg3hpQ 

              密码: rjv6

              项目内容1

              相关模块:

              requests模块、prettytable模块以及python自带的一些基本模块。(相关模块均使用pip安装即可)

              主要思路:

              构建相关的URL请求,并对返回的JSON数据进行解析处理最后显示即可。

              其中值得一提的有:

              (1)需要对特殊的URL发送请求来获得输入车站的字母代号;

              (2)车票余量查询的URL有两个,任意某时刻两个URL中仅有一个是有效的。

              环境搭建:

              安装python3.5.4(添加到环境变量)并pip安装相关第三方库即可。

              使用方式:


              使用演示:


              最终代码:

              见相关文件。

              项目内容2

              相关模块:

              splinter模块以及python自带的一些基本模块。(相关模块均使用pip安装即可)

              主要思路:

              其实无非是利用splinter库,来实现模拟登陆、查询、订票等操作。换句话说只要找到相关的控件名称即可,具体流程可以参考相关文件中的源代码,我都做了详细的注释。

              值得一提的有:

              (1)出发地和目的地不是直接输入的页面值,需要在cookie中查出;

              (2)验证码需要手动输入。

              环境搭建:

              安装python(添加到环境变量)并pip安装相关的第三方库,最后将相关文件中提供的chromedriver.exe文件放在python安装文件夹中的Scripts文件夹内。

              使用方式:

              在下图所示的代码段中填写相关信息:


              确认无误后在cmd中运行即可。

              其中cookie值查找方式如下图:


              使用演示:


              输入验证码后其余操作均将自动进行:


              抢到票之后我们需要手动打开12306官网或者官方APP在未完成订单中进行支付后购票:


              最终代码:

              见相关文件。

              下期预告

              主要完成项目内容3。

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              在“python抢火车票(上)”一文中我们完成了项目内容1和项目内容2,即利用python实现火车/高铁票查询功能以及利用python实现抢火车/高铁票功能,今天我将带大家完成项目内容3,即对项目内容1和项目内容2进行优化。

              本期任务

              完成项目内容3,即对项目内容1和项目内容2进行优化。

              开发工具

              python版本:3.5.4(64bit)

              chromedriver_win32版本:2.3.4

              chrome版本:65.0.3298.4

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/1qA1Bhd30lMa1ZyLUowg8oQ 

              密码: fxxp

              项目内容3

              相关模块:

              requests模块、prettytable模块、splinter模块以及python自带的一些基本模块。(相关模块均使用pip安装即可)

              主要改进:

              (1)出发地和目的地cookie值自动生成,无需再手工查找;

              (2)将项目内容1和项目内容2功能进行合并;

              (3)使用方式更加简便与人性化;

              (4)增加了抢票成功后语音提示功能;

              (5)避免了更多由于用户非法输入引起的程序异常;

              (6)增加了抢票成功后邮件提示功能,但由于邮件发送容易失败所以我将该部分代码注释掉了,有需要者可自行修改(最后做成Demo时我会添加邮件提示功能的)。

              具体原理请参考相关文件中的源代码,本人已进行了较为详细的注释。

              环境搭建:

              安装python(添加到环境变量)并pip安装相关的第三方库,最后将相关文件中提供的chromedriver.exe文件放在python安装文件夹中的Scripts文件夹内。

              使用方式:

              在cmd中运行后根据提示输入相关信息即可。

              使用演示:

              (1)查询功能:


              (2)抢票功能:


              抢到票之后我们需要手动打开12306官网或者官方APP在未完成订单中进行支付后购票:


              最终代码:

              见相关文件。

              下期预告

              完成项目内容4并进一步对代码进行优化。

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              在之前的“教你如何用Python实现抢火车票功能(上)、(中)”两文中我们基本完成了项目要求的功能,今天我们来完成项目的最后一部分内容即将两项功能集成到一个Demo,供所有专业/非专业人士更加方便地使用。

              本期任务

              完成项目内容4。

              开发工具

              python版本:3.5.4

              chromedriver_win32版本:2.3.4

              chrome版本:65.0.3298.4

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/16jUPfpAY90sGmqV0PbqszQ 

              密码: 6ntn

              项目内容4

              相关模块:

              requests模块、splinter模块、PIL模块以及python自带的一些基本模块。(相关模块均使用pip安装即可)

              相对之前版本的变动:

              (1)可视化界面;

              (2)车次不再使用纯数字,可直接输入需要抢票的车次名(如G163),使用更加方便;

              (3)暂时废除了邮件提示功能(太不稳定了)。

              具体原理请参考源代码!

              环境搭建:

              安装python(添加到环境变量)并pip安装相关的第三方库,最后将相关文件中提供的chromedriver.exe文件放在python安装文件夹中的Scripts文件夹内。

              使用方式:

              在cmd窗口运行即可。

              界面展示:


              最终代码:

              见相关文件。

              使用演示

              (1)查询功能


              (2)抢票功能


              需手动输入验证码:


              抢到票之后我们需要手动打开12306官网或者官方APP在未完成订单中进行支付后购票:

              使用说明

              (1)乘客名输入格式为:

              xxx(学生)或者xxx,其中()使用英文输入法;

              多名乘客时请输入xxx,xxx,xxx,其中,使用中文输入法。

              xxx代表人名!!!

              (2)日期输入格式为:

              year-month-day,例如2018-01-20。

              (3)类型输入格式为:

              字母a代表全部;

              字母g代表高铁;

              字母d代表动车;

              字母k代表快速;

              字母t代表特快;

              字母z代表直达。

              注意字母均为小写。

              (4)车次输入格式为:

              数字0代表任意车次,其他按照正确的车次名输入即可,如G163等等。

              若输入的车次不存在,则系统抢票时将抢任意车次。

              (5)其他:

              输入正确的用户名、密码和出发地与目的地即可。

              更多

              (1)这只是V1.0版本,还有很多缺陷和不足之处,为调试和修改方便,且避免程序出现其他意外的错误,暂时不提供.exe版本;

              (2)此版本至2018-01-12日为止是有效的,若日后12306官网有较大更新,则此代码将仅供参考;

              (3)尽量每年抢票季对版本进行更新升级,供抢票回家的小伙伴使用;

              (4)若发现代码有错误之处或者其他问题请后台联系我。

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              T_T并不玩这些游戏。。。

              单纯来蹭个热点。。。

              大概是因为蹭热点需要的技术含量比较低?

              就这样吧~~~

              利用Python制作命令行版的王者荣耀出装小助手。

              Let's Go!

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/1VGl4CLbPNwlFU6VC5w9r1g 

              密码: ad3a

              开发工具

              Python版本:3.6.4

              相关模块:requests模块;以及一些Python自带的模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              主要思路

              爬的是《英雄联盟盒子》这个APP。用Fiddler抓包找到需要的Get请求地址即可。。。

              不过显示的Get请求很长,在浏览器里测试一下,把不需要的参数都去掉。

              总之就是很简单的抓包。得到的三个URL:

              爬虫主要的流程是:

              (1)获得英雄ID;

              (2)获得所有的装备信息;

              (3)根据英雄ID和装备信息来获得英雄的详细信息,包括英雄简介和推荐出装。

              顺手也把所有英雄的照片爬下来了,增加点代码量。

              PS:

              因为不想手机和电脑来回截图,麻烦而且估计也没什么人看T_T。

              所以就文字叙述吧~~~

              过几天有时间我会出个APP抓包教程在公众号菜单栏中进行分享T_T,想看就看~~~

              具体实现过程详见源代码。

              使用演示

              抓取英雄照片:

              在cmd窗口运行Get_Heros_Pic.py文件即可。

              小助手:

              在cmd窗口运行Helper.py文件即可。

              视频演示:


              视频链接

              更多

              代码截止2018-03-15测试无误。

              若该盒子日后有较大更新,代码将仅供参考。

              有兴趣的朋友可以去抓点其他数据~~~

              总之这个APP还是很好抓的~~~

              虽然感觉实用价值不高T_T。。。

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              再次更新一下抖音视频批量下载脚本。

              就不一一回复了~

              参考文献

              https://github.com/loadchange/amemv-crawler

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/1ULMGqZzIlzSW1zPP7y6nTw 

              密码: j78s

              脚本仅供学习交流,禁止用于其他。

              开发工具

              Python版本:3.6.4

              相关模块:requests模块;ipaddress模块;click模块;以及一些Python自带的模块。

              Nodejs版本:10.7.0-x64

              环境搭建

              Step1:

              安装Python并添加到环境变量,pip安装需要的相关模块;

              Step2:

              安装nodejs(小白一路next就行,相关文件里提供了安装包,或者自己去官网下载)。

              原理简介

              第一个接口:

              https://api.amemv.com/aweme/v1/discover/search/?cursor=0&keyword={}&count=10&type=1&device_id={}&aid=1128&app_name=aweme&version_code=162&version_name=1.6.2

              keyword后的{}:输入的抖音号,

              device_id后的{}:随机产生的设备id。

              请求该接口可以获得以下信息:

              uid、aweme_count、unique_id。

              第二个接口:

              https://www.amemv.com/share/user/{}

              {}:请求第一个接口获得的uid。

              请求该接口可以获得以下信息:

              dytk。

              第三个接口:

              https://www.amemv.com/aweme/v1/aweme/post/?user_id={}&max_cursor=0&count={}&aid=1128&_signature={}&dytk={}

              user_id后的{}:uid(由接口一得);

              count后的{}:aweme_count(由接口一得);

              _signature后的{}:根据uid算出来的,计算方式参考了参考文献;

              dytk后的{}:dytk(由接口二得)。

              请求该接口可以获得以下信息:

              该抖音号的所有视频下载链接。

              最后:

              根据获得的视频下载链接下载抖音视频即可。

              具体的代码实现请参考相关文件中的源代码,代码量不大,就100行左右,核心代码量更少。

              使用方式

              在cmd窗口运行douyin.py文件即可。

              别忘了需要先安装Nodejs!!!

              视频演示如下:

              视频链接

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              抖音貌似最近几个月都很火。。。

              虽然我不玩T_T。。。

              但是我还是决定来蹭个热点。。。

              利用Python批量下载抖音视频。。。

              但愿能蹭到热点吧。。。

              Let's Go!

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/1Y9_7R2xVF3fWB6WC1O6kVA 

              密码: baj9

              开发工具

              Python版本:3.6.4

              相关模块:requests模块;bs4模块;以及一些Python自带的模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              主要思路

              根据输入的用户抖音号(T_T是叫抖音号吧?)获取该用户发布的所有视频并下载下来。

              所有的数据都可以用现成的API接口链接获取。

              所以代码思路基本没有什么好讲的。。。

              代码量不到100行,相信大家都能看懂。。。

              具体的实现过程详见源代码。

              使用演示

              在cmd窗口运行douyin_Spider.py文件即可。

              视频演示如下:


              点击链接查看视频

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              不久前,我们制作了网易云音乐下载器。。。

              但是网易云音乐无版权的歌曲利用那个下载器也是无法下载的。。。

              这时候就需要再搞一波事情。。。

              譬如:

              利用Python制作酷狗和QQ音乐下载器。。。

              其他的T_T我就不多说了。。。

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/1KqPYjrA7P_8llcBN0nzR2Q 

              密码: v4ju

              开发工具

              Python版本:3.6.4

              相关模块:requests模块,以及一些Python自带的模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              原理简介

              QQ音乐下载器:

              分析网页数据之后可以找到下面三个接口:

              第一个接口需要根据歌曲名构造完整链接来搜索需要下载的歌曲信息;

              第二个接口需要根据第一个接口返回的信息来构造完整链接来获取歌曲下载地址的部分信息;

              第三个接口即为歌曲下载地址,需要根据前两个接口获取的信息来构造完整链接。

              具体的实现过程见相关文件中的源代码。

              酷狗音乐下载器:

              分析网页数据之后可以获得以下两个接口:

              利用方式类似于QQ音乐下载器,但比QQ音乐下载器简单一些。第二个接口需要第一个接口返回的哈希值来构造完整链接,然后请求第二个接口就可以获取歌曲的下载链接。

              具体的实现过程见相关文件中的源代码。

              使用演示

              QQ音乐下载器:

              在cmd窗口运行QQ_Downloader.py文件即可。

              演示如下图所示:

              酷狗音乐下载器:

              在cmd窗口运行KG_Downloader.py文件即可。

              演示如下图所示:

              更多

              代码截止2018-03-19测试无误。

              若QQ音乐和酷狗音乐日后有较大更新,代码将仅供参考。(本人不予维护。)

              请合理使用,代码仅供大家学习与交流参考用途。

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              利用Python下载音悦台MV~~~

              没别的,就是为了下载一首《末班车》翻唱BY林俊杰的MV~~~

              当然这只是对我而言的~~~

              你完全可以使用这个脚本下载音悦台其他MV~~~

              Let's Go!

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/1eZAUpHwMucfan9K6hrcU2g 

              密码: fi4y

              开发工具

              Python版本:3.6.4

              相关模块:click模块;requests模块;以及一些Python自带的模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              主要思路

              MV的ID就是MV播放页链接后面的那串数字:

              根据输入的播放页面链接获取MV的ID,根据这个ID请求一个接口链接即可获取MV的下载地址,然后下载就可以了。。。

              很简单~~~

              至于为啥要用脚本下T_T,当然是因为不能直接下载所以才出此下策呀!!!

              具体思路详见相关文件中的源代码~~~

              使用演示

              在cmd窗口运行Yinyuetai.py文件,根据提示输入相关信息即可~~~

              视频演示:

              不小心把声音录进去了,点击观看时请注意场合!!!

              视频链接

              更多

              代码截止2018-04-03测试无误。

              若日后音悦台网站有较大更新,代码将仅供参考。

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              之前好像有人问怎么用python下载B站的视频,于是今天稍微研究了一下,发现还是挺简单的,于是过来分享一波。

              让我们愉快地开始吧~

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/1Wo2ExR5-LEVkCB_BsSMyPQ 

              密码: idbs

              开发工具

              Python版本:3.6.4

              相关模块:requests模块;contextlib模块;以及一些Python自带的模块。

              其他工具:ffmpeg

              环境搭建

              Python:

              安装Python并添加到环境变量,pip安装需要的相关模块;

              Ffmpeg:

              解压相关文件中提供的“ffmpeg.zip”文件,将解压后获得的文件夹内的bin文件夹路径添加到环境变量中,例如:

              原理简介

              FLV视频格式(科普一下):

              FLV(Flash Video)是Adobe公司设计开发的一种流行的流媒体格式,由于其视频文件体积轻巧、封装简单等特点,使其很适合在互联网上进行应用。此外,FLV可以使用Flash Player进行播放,而Flash Player插件已经安装在全世界绝大部分浏览器上,这使得通过网页播放FLV视频十分容易。FLV封装格式的文件后缀通常为“.flv”。

              (摘自:https://blog.csdn.net/leixiaohua1020/article/details/17934487)

              分析:

              随便点开一个B站的视频,发现在网页元素里有一个

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              利用Python简单地预测一下NBA比赛结果。。。

              这大概就叫蹭热度吧。。。

              毕竟貌似今天朋友圈都在刷NBA相关的内容。。。

              虽然我并不能看懂。。。

              但这并不妨碍我瞎预测一波。。。

              So,

              以下内容纯属瞎玩,如有雷同,算我倒霉。。。

              NBA忠实球迷请自动忽略不好结果。。。

              相关文件

              网盘下载链接: https://pan.baidu.com/s/1EwdkonbYY54AxnIgqx9yYA 

              密码: 1n93

              主要思路

              (1)数据选取

              获取数据的链接为:

              https://www.basketball-reference.com/

              获取的数据内容为:

              每支队伍平均每场比赛的表现统计;

              每支队伍的对手平均每场比赛的表现统计;

              综合统计数据;

              2016-2017年NBA常规赛以及季后赛的每场比赛的比赛数据;

              2017-2018年NBA的常规赛以及季后赛的比赛安排。

              (2)建模思路

              主要利用数据内容的前四项来评估球队的战斗力。

              利用数据内容的第五项也就是比赛安排来预测每场比赛的获胜队伍。

              利用方式为:

              数据内容的前三项以及根据数据内容的第四项计算的Elo等级分作为每支队伍的特征向量。

              Elo等级分介绍(相关文件中有):

              为方便起见,假设获胜方提高的Elo等级分与失败方降低的Elo等级分数值相等。

              另外,为了体现主场优势,主场队伍的Elo等级分在原有基础上增加100。

              (3)代码流程

              数据初始化;

              计算每支队伍的Elo等级分(初始值1600);

              基于数据内容前三项和Elo等级分建立2016-2017年常规赛和季后赛中每场比赛的数据集;

              使用sklearn中的LogisticRegression函数建立回归模型;

              利用训练好的模型对17-18年常规赛和季后赛的比赛结果进行预测;

              将预测结果保存到17-18Result.CSV文件中。

              开发工具

              Python版本:3.5.4

              相关模块:pandas模块、numpy模块、sklearn模块以及一些Python自带的模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              使用演示

              在cmd窗口运行Analysis_NBA_Data.py文件即可:

              结果:

              更多

              文章的初衷是为了让公众号推送的关于Python的小项目涉及的应用领域更加丰富多彩。从而激发部分Python初学者的学习热情,仅此而已。

              这篇文章的技术含量并不高,模型简单,数据处理方式也比较随意。。。

              可以优化的地方大概包括:

              增加训练数据(如多利用几年数据);

              优化训练模型(如sklearn中其他机器学习方法或者利用深度学习框架搭建相应的网络进行模型训练)。

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              T_T之前似乎发过类似的文章,那时候是用Keras实现的,现在用的PyTorch,而且那时候发的内容感觉有些水,于是我决定。。。

              好吧我确实只是为了写点PyTorch练手然后顺便过来水一篇美文~~~

              利用Python实现图像风格的迁移!!!

              不喜欢过程同学的依旧可以直接下拉到最后看结果~

              Let's Go!

              参考资料

              链接:

              http://pytorch.org/tutorials/advanced/neural_style_tutorial.html#

              是的,这又是来自于PyTorch官网的一个教程。

              在相关文件中我依旧提供了我翻译好的版本~~~

              以及涉及到的论文~~~

              相关文件

              网盘下载链接: https://pan.baidu.com/s/1eDOTzd0uzNzzQDRbpDEd2A 

              密码: tv5i

              开发工具

              Python版本:3.6.4

              相关模块:torch模块;PIL模块;matplotlib模块;torchvision模块;以及一些Python自带的模块。

              torch版本:0.3.0

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              补充说明:

              PyTorch暂时不支持直接pip安装。

              有两个选择:

              (1)安装anaconda3后在anaconda3的环境下安装(直接pip安装即可);

              (2)使用编译好的whl文件安装,下载链接为:

              https://pan.baidu.com/s/1dF6ayLr#list/path=%2Fpytorch

              额外说明

              T_T相关文件中提供了所需的预训练模型,若嫌弃官网的下载速度,可以下载我的。

              下载之后放到类似下图路径的文件夹中:

              原理简介

              作为一个纯正的非艺术生,抱歉我真的没法解释什么叫图像的艺术风格。反正齐白石和梵高的画肯定不是一个style的就是了。

              那么我来尝试解释一下风格迁移吧:

              风格迁移的实质是保留原画内容的基础上,用另外一种style来呈现原画。

              那么如何量化呢?

              简单而言大概是这样的:

              利用CNN逐层提取图像的特征(层越靠后提取出的特征越高级和稳定,即更能表现图片的高级语义信息),并且将某一层或某几层输出的Gram矩阵作为损失函数,来衡量两幅图像之间的内容/风格差异(T_T就是两幅图像分别经过相同的卷积神经网络,比较某一层或者某几层输出的Gram矩阵的差异)。

              Gram矩阵是啥???

              具体而言,其计算方式为:

              我们都知道,一张图片在某个卷积层的输出特征为一个形如(batch_size, channels, width, height)的四阶张量,显然batch_size为1。

              我们将类似下图的特征:

              转换为(batch_size*channels, width*height)大小的矩阵,这个矩阵和它的转置相乘就可以得到一个大小为(batch_size*channels, batch_size*channels)的矩阵,这个矩阵即为Gram矩阵。

              其实这就算是定义了图像风格和图像内容这两个概念了,接下来我们就可以实现风格迁移了。

              其流程大概是这样的:

              具体的实现细节详见源代码吧~~~

              相关文件中也有官网教程的个人翻译版以及相关的论文供感兴趣者参考。

              使用方式

              修改下图所示处的图片路径为自己的图片路径:

              在cmd窗口运行Neural_Transfer.py文件即可。

              由于资源和时间有限,下面展示的结果我都只跑了几百轮左右,图像大小为256*256。

              梵高笔下的皮卡丘

              原图像:

              生成的图像:

              梵高笔下的老北京

              原图像:

              生成的图像:

              毕加索笔下的爱因斯坦

              原图像:

              生成的图像:

              齐白石笔下的西湖

              原图像:

              生成的图像:

              更多

              利用其他库实现的图像风格迁移:

              1.基于python深度学习库DeepPy的实现:

              https://github.com/andersbll/neural_artistic_style

              2.基于python深度学习库Caffe的实现:

              https://github.com/fzliu/style-transfer

              3.基于python深度学习库TensorFlow的实现:

              https://github.com/log0/neural-style-painting

              感兴趣的朋友自己去实现一下吧~~~

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              T_T没有科研梦想的人半夜过来水篇文章~~~

              让Python学会写写歌,创创作~~~

              纯属娱乐~~~

              改编自PyTorch官网的一个教程,不过我用TF写的,然后生成英文变成了生成中文~~~

              Let's Go~~~

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/1VUEFR82CqyDj2w9SS4xnFA 

              密码: 3dmx

              开发工具

              Python版本:3.6.4

              相关模块:tensorflow-gpu模块;numpy模块;以及一些Python自带的模块。

              其中TensorFlow-GPU版本为:

              1.6.0

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              原理简介

              关于RNN的介绍,请参考我之前的文章:

              Python实现简单的机器翻译模型(点击蓝字进入)

              这里我们使用Char RNN模型进行训练。

              即Seq2Seq模型中的特殊情况输入与输出等长。

              也就是类似下图的样子(图源网络):

              具体实现过程详见相关文件中的源代码。

              使用演示

              在cmd窗口运行Char_RNN.py文件并根据提示输入相关信息即可。

              训练相关的参数请在config.py文件中调整:

              训练所用的数据路径以及生成新文本所用的预热数据请在Char_RNN.py文件中调整:

              训练演示视频:

              因为时间太长了,我只录了训练的前面一部分。

              最终训练结果如下图所示:

              结果展示

              因为时间和资源有限。

              这里只展示周杰伦的所有歌词作为样本进行训练之后测试的结果。

              当然你完全可以找其他文本作为训练语料来生成风格各异的“文章”,“歌词”等等~~~

              结果如下:

              (预热歌词为:是曾与你躲过雨的屋檐)

              好吧我并不知道它在说啥T_T

              一个失败的案例T_T

              大概是模型太low了。而且训练数据是我从网上直接下载的,也没有预处理过T_T。中间竟然突然冒出一个括号我也是颓了T_T

              更多

              随便玩玩的T_T~~~

              有兴趣的同学可以试着换更复杂的模型~~~

              然后训练的语料最好处理一下~~~

              好久没写TF了,代码可能写的有点糟糕T_T

              就这样吧~~~

              SQL Dates MySQL Date 函数

              定义和用法

              DATE_ADD() 函数向日期添加指定的时间间隔。

              语法

              DATE_ADD(date,INTERVAL expr type)

              date 参数是合法的日期表达式。expr 参数是您希望添加的时间间隔。

              type 参数可以是下列值:

              Type 值
              MICROSECOND
              SECOND
              MINUTE
              HOUR
              DAY
              WEEK
              MONTH
              QUARTER
              YEAR
              SECOND_MICROSECOND
              MINUTE_MICROSECOND
              MINUTE_SECOND
              HOUR_MICROSECOND
              HOUR_SECOND
              HOUR_MINUTE
              DAY_MICROSECOND
              DAY_SECOND
              DAY_MINUTE
              DAY_HOUR
              YEAR_MONTH


              实例

              假设我们有如下的 "Orders" 表:

              OrderId ProductName OrderDate
              1 Jarlsberg Cheese 2008-11-11 13:23:44.657

              现在,我们想要向 "OrderDate" 添加 45 天,这样就可以找到付款日期。

              我们使用下面的 SELECT 语句:

              SELECT OrderId,DATE_ADD(OrderDate,INTERVAL 45 DAY) AS OrderPayDate
              FROM Orders

              结果:

              OrderId OrderPayDate
              1 2008-12-26 13:23:44.657


              SQL Dates MySQL Date 函数


              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              利用Python简单品读/分析一下小说~~~

              T_T纯属娱乐~~~

              如有雷同,不甚荣幸~~~

              Let's Go~~~

              不想看过程的请直接下拉到最后看结果~~~

              相关文件

              网盘下载链接: https://pan.baidu.com/s/1D5dITcY27S0ji8nyJUP2fA 

              密码: c3kd

              开发工具

              Python版本:3.6.4

              相关模块:gensim模块;jieba模块;scipy模块;snownlp模块;matplotlib模块;numpy模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              额外说明:

              pip下载速度过慢:

              临时/永久换源~~~(百度上就有很多教程T_T)

              pip安装失败:

              到类似https://www.lfd.uci.edu/~gohlke/pythonlibs/这样的网站下载whl文件安装。

              主要思路

              (1)小说主要人物分析

              统计每个角色在小说中出现的次数,并假设出现的次数越多,人物在小说中的地位越高。

              (2)小说人物关系分析

              利用gensim生成一个词向量模型来分析人物关系。

              T_T这个模型是Google在2013年开源出来的,具体实现细节还没来得及看,算不上深度学习,只是浅层的神经网络~~~

              (3)小说情感分析

              主要利用了snownlp库。

              具体实现过程详见源代码。

              补充说明

              分析小说之前需要先到相关网站下载小说的文本文件并新建一个含有小说中所有人物名的文本文件。

              修改源代码(analysis.py)中的:

              if __name__ == '__main__':(98行)

              下面的小说文件路径后在cmd窗口中运行即可。

              Python品红楼

              T_T首先让我们看看这本我看了20年也只看了前3页的中国古典四大名著之首!!!

              主要人物(Top10):

              前面几个名字还是挺耳熟的???

              人物关系图:

              也不晓得靠谱不,聚类得到的图~~~

              T_T随手还得出了这样的结论(逃):

              小说整体的情感基调(消极or积极?):

              以0.5为界,左边代表消极,右边代表积极~~~

              这么极端的嘛T_T

              Python品天龙八部

              T_T只看过电视剧~~~

              主要人物(Top10):

              可能有些地方是乔峰,有些地方是萧峰的原因吧,毕竟我觉得乔峰才是主角呀!

              人物关系图:

              以及随手得出的结论:

              T_T毁三观啊~~~

              小说整体的情感基调(消极or积极?):

              Excuse me???

              更多

              不玩了T_T

              以上内容纯属不专业不科学纯娱乐的分析~~~

              有兴趣的可以去分析一下其他小说T_T

              说不定可以得到令人震惊的结论~~~

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              利用Python对照片中人脸进行颜值预测!!!

              至于结果的可靠性.......

              本人概不负责!!!

              对结果不满意或者因为结果分数过低而想不开者,请自行联系xxxPh.D.。也就是此颜值预测算法的提出者!!!本人只是部分复现了他的算法!!!

              以上和以下内容纯属玩笑,如有雷同,不甚荣幸。

              相关文件

              网盘下载链接: https://pan.baidu.com/s/1E_fc7PNaBHfMXNz3xLb12A 

              密码: 7nhm

              所需工具

              Python版本:3.5.4(64bit)

              相关模块:

              opencv_python模块、sklearn模块、numpy模块、dlib模块以及一些Python自带的模块。

              环境搭建

              (1)安装相应版本的Python并添加到环境变量中;

              (2)pip安装相关模块中提到的模块。

              例如:

              若pip安装报错,请自行到:

              http://www.lfd.uci.edu/~gohlke/pythonlibs/

              下载pip安装报错模块的whl文件,并使用:

              pip install whl文件路径+whl文件名安装。

              例如:

              (本人已在相关文件中提供了编译好的用于dlib库安装的whl文件——>因为这个库最不好装)

              参考文献链接

              【1】xxxPh.D.的博客

              http://www.learnopencv.com/computer-vision-for-predicting-facial-attractiveness/

              【2】华南理工大学某实验室

              http://www.hcii-lab.net/data/SCUT-FBP/EN/introduce.html

              主要思路

              (1)模型训练

              用了PCA算法对特征进行了压缩降维;

              然后用随机森林训练模型。

              数据源于网络,据说数据“发源地”就是华南理工大学某实验室,因此我在参考文献上才加上了这个实验室的链接。

              (2)提取人脸关键点

              主要使用了dlib库。

              使用官方提供的模型构建特征提取器。

              (3)特征生成

              完全参考了xxxPh.D.的博客。

              (4)颜值预测

              利用之前的数据和模型进行颜值预测。

              使用方式

              有特殊疾病者请慎重尝试预测自己的颜值,本人不对颜值预测的结果和带来的所有负面影响负责!!!

              言归正传。

              环境搭建完成后,解压相关文件中的Face_Value.rar文件,cmd窗口切换到解压后的*.py文件所在目录。

              例如:

              打开test_img文件夹,将需要预测颜值的照片放入并重命名为test.jpg。

              例如:

              若嫌麻烦或者有其他需求,请自行修改:

              getLandmarks.py文件中第13行。

              最后依次运行:

              train_model.py(想直接用我模型的请忽略此步)

              getLandmarks.py

              getFeatures.py

              Predict.py

              使用演示


              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              利用简单的机器学习算法实现垃圾邮件识别。

              让我们愉快地开始吧~

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/1Hsno4oREMROxWwcC_jYAOA 

              密码: qa49

              数据集源于网络,侵歉删。

              开发工具

              Python版本:3.6.4

              相关模块:scikit-learn模块;jieba模块;numpy模块;以及一些Python自带的模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              逐步实现

              (1)划分数据集

              网上用于垃圾邮件识别的数据集大多是英文邮件,所以为了表示诚意,我花了点时间找了一份中文邮件的数据集。数据集划分如下:

              训练数据集:

              7063封正常邮件(data/normal文件夹下);

              7775封垃圾邮件(data/spam文件夹下)。

              测试数据集:

              共392封邮件(data/test文件夹下)。

              (2)创建词典

              数据集里的邮件内容一般是这样的:

              首先,我们利用正则表达式过滤掉非中文字符,然后再用jieba分词库对语句进行分词,并清除一些停用词,最后再利用上述结果创建词典,词典格式为:

              {"词1": 词1词频, "词2": 词2词频...}

              这些内容的具体实现均在"utils.py"文件中体现,在主程序中(train.py)调用即可:

              最终结果保存在"results.pkl"文件内。

              大功告成了么?当然没有!!!

              现在的词典里有52113个词,显然太多了,有些词只出现了一两次,后续特征提取的时候一直空占着一个维度显然是不明智的做法。因此,我们只保留词频最高的4000个词作为最终创建的词典:

              最终结果保存在"wordsDict.pkl"文件内。

              (3)特征提取

              词典准备好之后,我们就可以把每封信的内容转换为词向量了,显然其维度为4000,每一维代表一个高频词在该封信中出现的频率,最后,我们将这些词向量合并为一个大的特征向量矩阵,其大小为:

              (7063+7775)×4000

              即前7063行为正常邮件的特征向量,其余为垃圾邮件的特征向量。

              上述内容的具体实现仍然在"utils.py"文件中体现,在主程序中调用如下:

              最终结果保存在"fvs_%d_%d.npy"文件内,其中第一个格式符代表正常邮件的数量,第二个格式符代表垃圾邮件的数量。

              (4)训练分类器

              我们使用scikit-learn机器学习库来训练分类器,模型选择朴素贝叶斯分类器和SVM(支持向量机):

              (5)性能测试

              利用测试数据集对模型进行测试:

              结果如下:

              可以发现两个模型的性能是差不多的(SVM略胜于朴素贝叶斯),但SVM更倾向于向垃圾邮件的判定。

              That's all~

              完整源代码请参见相关文件。

              更多

              没有具体介绍模型原理,因为后续可能会出一个系列,比较完整详细地介绍一下机器学习里的常用算法。所以,就先这样吧~

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              花了点时间利用Python绘制了一些有意思的图案,也算是发掘了一下Python的可视化功能吧。。。

              PS:

              部分图案参考了一些博客的一部分源代码。

              顺便证明一波我的审美T_T。。。

              没错,是时候证明一波了~~~

              Let's Go!

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/1ZOaw7JmZ2dNvw0BDCcaTcA 

              密码: grsp

              开发工具

              Python版本:3.6.4

              相关模块:numpy模块;matplotlib模块;numba模块;PIL模块;以及一些Python自带的模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              效果展示

              原理没啥好说的,直接展示吧~~~

              首先当然是一些逆天的数学分形图案啦~~~

              (1)朱利亚分形

              (2)二十面体对称的万花筒

              (3)曼德勃罗集

              (4)牛顿分形

              其次,我也用Python的turtle模块画了一些有点意思的图案。

              (1)漫天雪花


              (2)玫瑰

              方案一:

              点此观看视频

              方案二:

              点此观看视频

              (3)爱心(T_T好吧有些非主流)

              点此观看视频

              That's all...以后有机会再画其他的吧~~~

              更多

              Python的可视化库还是非常丰富的,功能也十分强大,有需要的朋友可以自己去学习一下。

              譬如:

              Matplotlib;

              Pandas;

              Bokeh;

              Pygal等等。

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              早上起来随手写的脚本。

              利用Python实时监控CPU使用率。

              感觉应该还是有用武之地的,于是过来发一波文。

              支持Linux和Windows系统。

              Let's Go~~~

              相关文件

              网盘下载链接: https://pan.baidu.com/s/1RKoYqqg74TyxKeDAEPqrhg 

              密码: xuuy

              开发工具

              测试系统:Win10和Ubuntu

              Python版本:3.5+

              相关模块:matplotlib模块;psutil模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              注意:

              Ubuntu自带的Python不包含TK模块,需要使用:

              sudo apt-get install python3-tk

              命令自行安装。

              参考文档

              psutil文档:

              https://psutil.readthedocs.io/en/latest/

              matplotlib文档:

              https://matplotlib.org/users/index.html

              具体实现过程详见相关文件中的源代码。

              最近都是比较简单的脚本,没什么原理思路T_T

              使用演示

              在cmd窗口运行monitor.py文件即可。

              运行截图:

              (1)Ubuntu

              (2)Windows10

              视频演示:

              点击观看视频

              更多

              代码截止2018-04-15测试无误。

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              不像考卷,现实生活中,有些事永远没有答案。

              简单且随意地分析一下高考的一些数据~~~

              让我们愉快地开始吧~~~

              相关文件

              相关文件

              网盘下载链接: https://pan.baidu.com/s/1zvVTTxfjmrTxjjX_M_DoEA 

              密码: 9jyd

              相关文件中包含本文所涉及到的所有源代码和数据。

              数据源于网络,不保证其完全可靠。

              开发工具

              Python版本:3.6.4

              相关模块:pyecharts模块;以及一些Python自带的模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              pyecharts模块的安装可参考:

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              额外说明:

              pyecharts模块安装时请依次执行以下命令:

              pip install echarts-countries-pypkg

              pip install echarts-china-provinces-pypkg

              pip install echarts-china-cities-pypkg

              pip install pyecharts

              若安装过程中出现:

              'utf-8' codec can't decode byte 0xb6

              或者类似的编码错误提示。

              可尝试修改Python安装文件夹下如下图所示路径下的__init__.py文件的第75行代码:

              修改为下图所示内容:

              “一本正经的分析”

              开始分析

              首先让我们来看看从恢复高考(1977年)开始高考报名、最终录取的总人数走势吧:

              T_T看来学生党确实是越来越多了。

              不过这样似乎并不能很直观地看出每年的录取比例?Ok,让我们直观地看看吧:

              看来上大学越来越“容易”之说不是空穴来风的,总录取比例高的可怕~~~

              那么各省的情况呢?

              由于各省高考最终录取人数的统计标准不一样,有些是只统计本科,有些是都统计的,为了避免统计标准不一而带来的不公平对比,我们只分析各省的高考报考人数。

              从2010年开始到今年(2018年)各省份高考考生数量的分布图如下:

              T_T河南的高考考生人数真是一枝独秀。

              那么各省的大学数量又是如何分布的呢?以公办本科大学数量作为统计标准,其分布图大概是这样的:

              Emmm。北京和江苏分别位居第一和第二名。想想也是必然T_T

              那么985&211高校的分布又如何呢?

              “那就这样吧,再爱都曲终人散了。”看到这个默默不说话了。

              以省份为x轴,年份为y轴,该年该省报考的考生人数为z轴来更直观地看看各省每年的高考考生数量变化情况吧:

              上图中省份的顺序是这样的:

              北京、四川、陕西、江西、吉林、宁夏、广西、内蒙古、甘肃、西藏、福建、上海、广东、山东、浙江、河南、安徽、江苏、河北、黑龙江、湖南、湖北、山西、云南、贵州、海南、辽宁、重庆、天津、青海、新疆,台湾因为没有数据,所以没有加入。

              T_T河南的高考考生数量真的恐怖。

              Emmm,因为可用的数据不多,再分析下去大概就是花式的做图游戏了,想想还是算了吧。至于个人观点,还是不发表为好。毕竟,大家的“哈姆雷特”都不一样。

              更多

              相关文件中包含了本文所涉及到的所有源代码、数据和结果,其中,数据来源网络,本人不保证其可靠性。

              运行源代码前需将对应的注释去除。

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              最近经常需要简单地远程控制一下电脑,比如远程查看一下电脑上模型训练的情况,模型训练完之后远程关闭电脑等等,于是就想着利用python来简单地实现一下这些功能,直接利用邮件远程控制自己电脑。

              让我们愉快地开始吧~

              相关文件

              网盘下载链接: https://pan.baidu.com/s/1yWiZPWKE44n1UxgkdFfMlQ 

              密码: 8jiq

              开发工具

              Python版本:3.6.4

              相关模块:PIL模块;email模块;以及一些Python自带的模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              原理简介

              一. 思路

              电脑每隔一段时间查看指定邮箱中是否收到了新的邮件,若未收到,则不进行任何操作,若收到了,则判断发件人的身份,若发件人为合法的控制者,则解析发件人的邮件,执行解析结果,否则忽略该邮件。

              二. 具体实现

              (1)收发邮件

              我们利用POP3协议来收取邮件,利用SMTP协议来发送邮件,python内置对着两个协议的支持,因此具体实现起来十分简单轻松。

              注1:

              此处推荐廖雪峰的Python教程,里面有关于收发邮件的详细介绍,我就不搬砖了。

              注2:

              电脑端邮箱本人使用了新浪邮箱,手机端邮箱本人使用了QQ邮箱。

              (2)查看电脑状况

              直接利用PIL模块的ImageGrab.grab()函数对电脑进行截屏,然后通过邮件把电脑截屏发送到手机上。

              如果想查看模型运行的情况,走之前把模型训练界面显示在桌面上就可以啦~

              (3)可扩展性

              除了查看电脑状况外,目前仅支持利用cmd命令控制电脑,若需要添加其他功能,可在下图所示的位置上添加:

              (4)易用性

              cmd命令太长手机上打起来不方便或者记不住怎么办?你可以在word2cmd.json中设置快捷命令语:

              (5)FAQ

              ① 电脑端发送邮件失败?

              解决方案:

              若电脑端发送的邮件被识别为垃圾邮件使得手机端无法查看电脑状况时,可用手机登陆电脑端使用的邮箱,查看被退回的邮件,这样就可以在手机上查看电脑运行状况了。

              注3:

              若为手机端邮箱拒收,可以设置一下白名单。

              ② 电脑端无法登陆邮箱?

              解决方案:

              你需要开启SMTP和POP3服务:

              密码应为客户端授权密码,而非登陆密码。当然新浪邮箱的登录密码即为客户端授权密码。

              That's All.

              完整源代码请自行参考相关文件。

              使用演示

              Step1:修改配置文件

              必须修改的配置文件为:

              config.json。

              作用:

              设置电脑端和手机端邮箱的信息。手机端邮箱的信息用于验证发信人是否为合法控制电脑者,电脑端邮箱的信息用于电脑端接收和发送邮件。

              若需要加密SMTP会话,请设置enable_ssl为true,并设置正确的端口号。

              选择修改的配置文件为:

              word2cmd.json。

              作用:

              设置快捷命令语。

              Step2:运行Server.py文件

              发送指令:

              执行指令:

              结果:

              That's All.

              更多

              代码截止2018-08-07测试无误。

              相关文件中提供了打包好的EXE文件版本,无需配置环境即可使用。

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              在跑程序,闲着也是闲着,于是做了这件似乎还算有趣的事情。拿出来分享一下。

              参考了matthewearl开源的一个项目写的。

              恶搞属性偏重。T_T有些效果还可以~

              让我们愉快地开始吧~~~

              相关文件

              百度网盘链接: https://pan.baidu.com/s/1euygpYRWprWFZDXnv39P-A 

              密码: 1xm6

              开发工具

              相关模块:python-opencv模块;dlib模块;numpy模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              dlib据说用Anaconda装比较方便。年代太久远有些忘记了,我一直用原生的Python,忘了怎么装好的,似乎也挺方便的。之前的文章分享过一些编译好的whl文件,可以直接pip安装。

              比如:

              Python美颜

              原理简介

              主要流程:

              (1)利用dlib库检测并获取人脸特征点;

              (2)通过一些简单的处理使得第二张人脸的眼睛、鼻子和嘴巴较好地“装”到第一张人脸上。

              一些细节:

              特征检测器:

              用的dlib官方提供的预训练好的模型。

              第二张图片的人脸特征需要对齐到第一张图片的人脸特征,其实现参考了:

              https://en.wikipedia.org/wiki/Procrustes_analysis#Ordinary_Procrustes_analysis

              具体实现方式详见相关文件中的源代码。

              使用演示

              修改SwapFace.py文件的图片路径为自己需要操作的图片路径:

              然后在cmd窗口运行即可。

              一些结果图:

              (1)特朗普+奥巴马

              (2)普及+安倍

              (3)乔布斯+比尔盖茨

              (4)莱布尼兹+牛顿

              (5)爱因斯坦+薛定谔

              That's All.

              更多

              有些结果还是挺逗的。。。

              中国名人的结果我没敢放T_T

              有兴趣的朋友可以自己去试试~~~

              代码截止2018-05-01测试无误。

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              偶遇了一篇文章:

              “Mapping Your Music Collection”

              https://www.christianpeccei.com/musicmap/

              感觉颇有缘分,似有命中注定之感,于是想着用一些简单的音频处理、机器学习和可视化技术,简单地分析一下自己的音乐收藏。当然我对乐理知识一无所知,所以分析将不涉及任何与乐理知识相关的内容,纯属“瞎玩”性质的分析。T_T

              那么就让我们愉快地开始吧~~~

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/16lZb3JbHeC__k_oP8RMXUg 

              密码: nxpt

              相关工具

              Python版本:3.6.4

              相关模块:numpy模块;sklearn模块;matplotlib模块;以及一些Python自带的模块。

              mpg123:

              1.25.10

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块;

              将相关文件中提供的mpg123.zip文件解压后添加到环境变量中,例如:


              开始分拆

              方便起见,所有的音乐文件均先转为.wav格式后再做分析。

              从最简单的开始吧!让我们先来看看不同歌手的声音波形图:

              周杰伦:

              感觉波形图好混乱,似乎是数据量太大引起的,于是我打算换一个策略,只画出每首歌曲前10秒的波形图来作比较,毕竟良好的开端是成功的一半?

              周杰伦:

              许嵩:

              陈奕迅:

              Interesting...

              好像还是挺有意思的,但并看不出什么端倪来的样子,同一个歌手唱的歌的波形结构之间的差异和不同歌手唱的歌的波形结构之间的差异仿佛都挺大的。虽然并没有规定说同一个歌手唱的歌的波形结构之间的差异一定很小,不同歌手唱的歌的波形结构之间的差异一定很大。

              好吧,有些混乱,还是随意点的好。那么我们来尝试性地提取一下歌曲的特征吧。我们打算提取的歌曲特征有:

              ① 歌曲波形的统计矩,包括均值、标准差、偏态和峰态,同时,我们通过平滑窗(递增平滑,长度分别为1,10,100,1000)来获取这些特征在不同时间尺度上的表现;

              ② 为了体现信号的短时变化,我们可以计算一下波形一阶差分幅度的统计矩,同样也通过平滑窗来获取这些特征(均值、标准差、偏态和峰态)在不同时间尺度上的表现;

              ③ 最后,我们计算一下波形的频域特征,这里我们只计算歌曲在不同频段(将整个频段均分为10份)的能量占比,不过直接对歌曲的波形数据作快速傅里叶变换的话其计算量过于庞大了,因此先让波形数据通过长度为5的平滑窗再对其作快速傅里叶变换。

              综上所述,我们已经获得了歌曲的42个特征值。下面我们尝试利用这些特征值对我这几天下载的43首歌曲进行k均值聚类。首先,为了便于结果的可视化,我们利用PCA对数据进行降维(42维特征到2维特征),为了方便起见,我们直接调库(sklearn)实现,结果打印如下:

              OK,接下来我们就可以对降维后的数据进行聚类了,这里我们将自己实现一下k均值聚类算法而不是简单地调库,最终的聚类结果如下图所示(k=4):

              接下来我们尝试先对歌曲的42个特征值进行归一化处理,然后再进行上面的PCA和聚类操作,同时令k=3,最终的聚类结果如下图所示:

              Emmm,好像效果更差了。

              不过我发现我喜欢了8年的歌“尾戒”竟然一枝独秀了!还是很棒的,哈哈~~~

              当然,这里有一个问题,歌曲的42个特征值是人工选取的,也许并不很好的表现出歌曲特征,且这些特征之间的相关系数是不为0的,也就是存在冗余特征。

              https://www.christianpeccei.com/musicmap/一文利用了遗传算法从42个特征值中筛选出了18个特征值作为歌曲最终的特征向量,其结果如下:

              懒得复现了,直接用他的结论重新进行聚类,结果如下(k=3):

              Emmm,好像半斤八两。

              那就这样吧,就当学点基础的音频处理、机器学习和可视化技术了。

              所有源代码和素材均在相关文件中提供了,End。

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              这又将是一个不定期更新的系列~~~

              本系列主要将使用到python的pygame模块来教大家制作一些小游戏,每期制作一个。最后都会打包成.exe文件分享给大家~~~

              So,对于只想玩小游戏的小伙伴来说,只需要下载相关文件就好啦~~~

              至于pygame的开发文档,暂时没有归入整理计划,来日方长,英文不好的同学只能先看网上中文的资料将就下了~~~

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/1gDLSHDF48xV4Z7z25UjOxw 

              密码: q4ib

              本期参考文献

              链接:

              https://www.raywenderlich.com/24252/beginning-game-programming-for-teens-with-python

              作者:

              Julian Meyer

              说明

              python版本:3.5.4

              pygame版本:1.9.3(pip安装即可)

              开始

              Step1:你好,兔子

              效果:

              Step2:添加背景

              首先载入所需的图片;其次依次通过x和y进行循环,并且根据循环里x和y的值来画上草的效果;接下来的几行就是在屏幕上画出城堡。

              效果:

              Step3:让兔子能够移动

              接下来你需要加上一些真正的游戏的元素了,比如让兔子能够随着按键移动。

              效果(可以移动兔子):

              Step4:让兔子转向

              好的,现在你的兔子在你按键的时候可以移动了,但是如果你能用鼠标让兔子朝向你选择的方向不是更酷吗?这样它就不会总是朝向一个方向了。

              效果:

              Step5:射击吧!兔子

              让兔子用箭头射向它们的敌人,这一步会有一点复杂,因为你需要跟踪所有的箭头,更新它们,旋转它们,在它们跑出屏幕的时候删除它们。

              效果:

              Step6:獾,拿上武器!

              好吧,现在有了城堡,并且你有一个英雄可以移动和射出箭头。还差什么呢?当然是攻击城堡的敌人啦~

              在这一步,你将会随机创建出一些獾冲向城堡。在游戏的进程中会有越来越多的獾冒出来。

              效果:

              Step7:獾与箭头的碰撞

              獾们冲向你的城堡,但是你的箭头对它们完全没有作用!这让兔子怎么防守它的家园呢?

              是时候来让箭头能够杀死獾让兔子能保护自己的城堡并且赢得这场游戏了~~~

              效果:

              Step8:添加健康值和时间的显示

              游戏运行起来相当不错了,有攻击者、防守者。现在,你需要的就是通过一个方法来显示兔子的得分。

              最简单的方法就是添加一个HUD来显示当前城堡的生命值。你也可以加一个计时来记录城堡存活下来的时间。

              效果:

              Step9:赢或输

              如果你玩的时间够长,即使你的生命值已经变成0了,游戏仍然是继续的!不仅如此,你仍然可以用箭头射向这些獾。这肯定不太对。你需要加上一些赢或者输的情况来让你的游戏值得玩。

              那么我们来加上胜利或者失败的条件。你可以通过终止主循环,进入胜利/失败的循环来实现它。你需要指出玩家是否胜利,并将其显示在屏幕上。

              效果:

              Step10:免费的音乐和声音效果

              这个游戏现在相当不错了,但是没有声音。有点太安静了。加上一点声音效果,能让你更好地感受这个游戏。

              效果:

              当然是会各种音效啦~~~图片大概是表达不了了emm。

              OK,大功告成,你完美地制作了一款小游戏!

              在这基础上,你可以根据你自己的创意来扩展游戏!比如,你可以试着重置里面的各种图片,加上不同的枪或者是不同的怪物!

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              T_T突然发现N久以前我还做过一个系列???

              利用Python制作小游戏???

              好吧,既然做了,就有头有尾吧~~~

              本期我们将制作一个类似八音符的小游戏。

              让我们愉快地开始吧~~~

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/1JKS3_bTToinfyGREcdqduw 

              密码: ufaw

              参考文献

              cocos2d文档:

              http://python.cocos2d.org/doc/

              开发工具

              Python版本:3.6.4

              相关模块:

              cocos2d模块;

              pyaudio模块;

              以及一些Python自带的模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              原理介绍

              相信很多人对八音符这款游戏并不陌生吧,其核心玩法是利用声音控制一个带辫子的小黑球不断前进,大概是长这样子的吧:

              今天我们就来做一个低配版本的T_T,其功能为利用声音控制皮卡丘不断前进。

              游戏主要使用了cocos2d模块和pyaudio模块,前者用于搭建游戏框架,后者用于获得麦克风的声音。

              Step1 定义皮卡丘类:

              既然游戏的主角是皮卡丘,那我们总得单独定义一个类来体现一下主角吧?

              利用cocos2d模块来定义主角类是一件非常轻松的事情。你只需要继承sprites类,然后告诉sprites类需要执行什么操作即可。

              根据八音符的游戏规则,我们赋予皮卡丘跳跃、下降和静止的能力,同时,我们规定皮卡丘在空中时无法进行跳跃。具体代码如下:

              Step2 定义block类:

              显然,主角需要有站的地方吧T_T,到处都是万丈深渊怕是一万只皮卡丘也拯救不了地球人吧T_T。

              对于地面,刚开始的时候先得有一段长点的平地缓冲一下,让玩家先试试自己的嗓音,然后再随机生成跳跃块,让玩家展示自己的歌喉。具体代码如下:

              Step3 实现游戏主循环:

              有了上面的铺垫,就可以开始实现我们的小游戏了。

              此时我们需要继承ColorLayer类来实现游戏主循环。首先,我们定义声控条类来“暗中观察”我们的嗓音,代码如下:

              然后就是实例化皮卡丘类和block类,其中,block类将被放置进容器以方便整体处理。代码如下:

              啊,千万别忘了只有输入了声音才能控制我们的皮卡丘不停地运动,代码如下:

              最后,我们需要告诉程序游戏规则,那就是根据麦克风接收到的声音的音量来控制声控条的长短以及皮卡丘的动作。这里,我们通过block块的整体后移来实现皮卡丘的前进效果。

              当然,我们也需要加入必要的碰撞检测程序,不然皮卡丘一登场就陷入沼泽一样的地面中了。并且我们规定当皮卡丘掉入“沟壑”后游戏重置。

              代码如下:

              OK,大功告成!!!

              游戏效果

              在cmd窗口运行Game2.py文件即可。

              效果如下:

              点击查看视频

              更多

              关于cocos模块的教程,推荐阅读:

              http://python.cocos2d.org/doc/

              代码截止2018-06-14测试无误。

              有兴趣的小伙伴可以在此基础上进行改进优化,例如加上音效和分值统计、开始和结束界面等等~~~

              总之可改进的空间还是比较大的~

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              本期我们将制作一个拼图小游戏。

              好吧也许有些幼稚。

              不过无论如何,让我们愉快地开始吧~~~

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/1q9VPkOYvI12LjqfQVRCF1Q 

              密码: 7wfg

              开发工具

              Python版本:3.6.4

              相关模块:

              pygame模块;

              以及一些Python自带的模块

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              原理介绍

              游戏简介:

              将图像分为m×n个矩形块,并将图像右下角的矩形块替换为空白块后,将这些矩形块随机摆放成原图像的形状。游戏目标为通过移动非空白块将随机摆放获得的图像恢复成原图像的模样,且规定移动操作仅存在于非空白块移动到空白块。

              例如下图所示:

              逐步实现:

              Step1:游戏初始界面

              既然是游戏,总得有个初始界面吧?

              OK,我们先写一个游戏初始界面:

              效果是这样子的:

              根据玩家自身水平,可以选择不同难度的拼图游戏。

              Step2:定义移动操作

              定义移动操作的目的是为了移动拼图(好像是废话T_T),具体实现起来十分简单:

              Step3:游戏主界面

              OK,有了前面的铺垫,我们可以开始实现我们的游戏主界面了。

              首先,我们需要打乱拼图,但是随机打乱很可能导致拼图无解,因此我们通过随机移动拼图来实现打乱拼图的效果,这也是我们先定义拼图的移动操作的主要原因:

              游戏主界面初始化:

              最后实现主界面的显示刷新以及事件响应等功能:

              Step4:游戏结束界面

              当玩家完成拼图后,需要显示游戏结束界面,和游戏初始界面类似,实现起来都比较简单:

              OK,大功告成!!!

              游戏效果

              在cmd窗口运行Game3.py文件即可。

              效果如下:

              点击查看视频

              更多

              代码截止2018-06-26测试无误。

              同样,有兴趣的小伙伴可以在此基础上进行优化,比如增加计时功能,积分功能等等。

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              本期我们将制作一个简单的滑雪游戏。

              废话不多说,让我们愉快地开始吧~

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/1F74v1qGVk2NEWMEv-5E25w 

              密码: 2fcv

              图片素材源于网络,侵歉删。

              开发工具

              Python版本:3.6.4

              相关模块:

              pygame模块;

              以及一些Python自带的模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              先睹为快

              原理介绍

              游戏规则:

              玩家通过“AD”键或者“←→”操控前进中的滑雪者,努力避开路上的树,尽量捡到路上的小旗。

              如果碰到树,则得分减50,如果捡到小旗子,则得分加10。

              逐步实现:

              Step1:定义精灵类

              由于游戏涉及到碰撞检测(滑雪者与树和小旗之间的碰撞),因此我们定义两个精灵类,分别用于代表滑雪者和障碍物(即树和小旗):

              其中,滑雪者在前进过程中应当拥有向左,向右偏移的能力,并且在偏移时滑雪者向前的速度应当减慢才更加合乎常理,这样才能供玩家操作。同时,滑雪者应当拥有不同的姿态来表现自己滑行时的状态:

              直线:

              左偏一点:

              左偏很多:

              右偏一点:

              右偏很多:

              另外,尽管滑雪者的左右移动通过移动滑雪者本身实现,但是滑雪者的向前移动是通过移动障碍物实现的。

              Step2:随机创建障碍物

              现在我们需要定义一个随机创建障碍物的函数,以便在游戏主循环中调用:

              Step3:游戏主循环

              首先我们初始化一些参数:

              其中障碍物创建两次的目的是便于画面衔接。

              然后我们就可以定义主循环了:

              主循环的内容包括:

              事件监听、障碍物的更新、碰撞检测以及分数的展示等内容,总之还是很容易实现的。

              Step4:其他

              开始、结束界面这些,就靠大家自己发挥了,我就写了一个简单的开始界面:

              效果:

              All Done!

              更多

              代码截止2018-07-12测试无误。

              欢迎到GitHub上Star:

              https://github.com/CharlesPikachu/Games

              VBScript RTrim 函数

              VBScript RTrim 函数返回去掉尾部空格的字符串副本。


              VBScript 参考手册 完整的 VBScript 参考手册

              RTrim 函数删除字符串右边的空格。

              提示:请参阅 LTrim 和 Trim 函数。

              语法

              RTrim(string)

              参数 描述
              string 必需。字符串表达式。

              实例

              实例

              <script type="text/vbscript">
              fname=" Jack "
              document.write("Hello" & RTrim(fname) & "and welcome.")
              </script>

              以上实例输出结果:

              Hello Jackand welcome.

              尝试一下 »

              VBScript 参考手册 完整的 VBScript 参考手册

              VBScript StrReverse 函数

              VBScript StrReverse 函数返回一字符串,其中字符的顺序与指定的字符串中的顺序相反。


              VBScript 参考手册 完整的 VBScript 参考手册

              StrReverse 函数反转一个字符串。

              语法

              StrReverse(string)

              参数 描述
              string 必需。需被反转的字符串。

              实例 1

              Dim txt
              txt="This is a beautiful day!"
              document.write(StrReverse(txt))
              Output:
              !yad lufituaeb a si sihT


              VBScript 参考手册 完整的 VBScript 参考手册
              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              利用Python简单地实现AI版的贪吃蛇。。。

              just for fun...

              没有用深度学习。。。

              算法是由一个叫Hawstein的人在好多好多年以前提出,感觉很有趣,就花了点时间复现了一下他的想法。。。

              至于效果。。。

              看脸。。。

              真的只是觉得他的想法很有趣,仅此而已,因为如果你想让蛇机械地充满整个空间,只需要让蛇一直走S就好了,但是这就变得很无趣了。。。

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/1KPAV6FKLUFj11myoVjzQ2Q 

              密码: gb7k

              主要思路

              (1)蛇每走一步,就使用BFS计算游戏界面中每个位置(蛇身除外)到达食物的最短路径长;

              (2)将蛇的安全定义为蛇是否可以跟着蛇尾运动,即蛇头和蛇尾间是否存在路径;

              (3)蛇每次行动前先利用虚拟的蛇进行探路,若虚拟的蛇吃完食物后是安全的,真蛇才行动;

              (4)若蛇和食物之间不存在路径或者吃完食物后并不安全,就跟着蛇尾走;

              (5)若蛇和食物之间、蛇和蛇尾之间均不存在路径,就随便挑一步可行的来走;

              (6)保证目标是食物时蛇走最短路径,目标是蛇尾时蛇走最长路径。

              不足之处

              由于食物是随机出现的,若虚拟的蛇跑一遍发现去吃食物是不安全的,真蛇就不会去吃食物,而是选择追着蛇尾跑,若一直如此,就陷入了死循环,蛇一直追着蛇尾跑跑跑。。。

              直到你终止游戏为止。。。

              开发工具

              Python版本:3.5.4

              相关模块:

              pygame模块以及一些Python自带的模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              运行方式

              在cmd窗口运行AI_snake.py文件即可。

              结果展示

              动图一直上传失败。。。

              所以随便截几个图吧~~~

              更多

              (1)为了保证代码简单易懂,所提供的代码冗余度较高(比如进行了不必要的重复计算),有兴趣者可对代码进行优化;

              (2)相关文件中也提供了普通版本的贪吃蛇游戏(Normal_snake.py)。

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              利用Python简单地实现AI版的贪吃蛇。。。

              just for fun...

              没有用深度学习。。。

              算法是由一个叫Hawstein的人在好多好多年以前提出,感觉很有趣,就花了点时间复现了一下他的想法。。。

              至于效果。。。

              看脸。。。

              真的只是觉得他的想法很有趣,仅此而已,因为如果你想让蛇机械地充满整个空间,只需要让蛇一直走S就好了,但是这就变得很无趣了。。。

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/1KPAV6FKLUFj11myoVjzQ2Q 

              密码: gb7k

              主要思路

              (1)蛇每走一步,就使用BFS计算游戏界面中每个位置(蛇身除外)到达食物的最短路径长;

              (2)将蛇的安全定义为蛇是否可以跟着蛇尾运动,即蛇头和蛇尾间是否存在路径;

              (3)蛇每次行动前先利用虚拟的蛇进行探路,若虚拟的蛇吃完食物后是安全的,真蛇才行动;

              (4)若蛇和食物之间不存在路径或者吃完食物后并不安全,就跟着蛇尾走;

              (5)若蛇和食物之间、蛇和蛇尾之间均不存在路径,就随便挑一步可行的来走;

              (6)保证目标是食物时蛇走最短路径,目标是蛇尾时蛇走最长路径。

              不足之处

              由于食物是随机出现的,若虚拟的蛇跑一遍发现去吃食物是不安全的,真蛇就不会去吃食物,而是选择追着蛇尾跑,若一直如此,就陷入了死循环,蛇一直追着蛇尾跑跑跑。。。

              直到你终止游戏为止。。。

              开发工具

              Python版本:3.5.4

              相关模块:

              pygame模块以及一些Python自带的模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              运行方式

              在cmd窗口运行AI_snake.py文件即可。

              结果展示

              动图一直上传失败。。。

              所以随便截几个图吧~~~

              更多

              (1)为了保证代码简单易懂,所提供的代码冗余度较高(比如进行了不必要的重复计算),有兴趣者可对代码进行优化;

              (2)相关文件中也提供了普通版本的贪吃蛇游戏(Normal_snake.py)。

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              闲来无事写了个比较愚蠢的AI五子棋。

              T_T当然你好好和它下,它还是比较机智的。

              让我们愉快地开始吧~~~

              相关文件

              网盘下载链接: https://pan.baidu.com/s/1DV09ZdyNMoZF2KoKQ4GH_A 

              密码: ujrh

              开发工具

              Python版本:3.6.4

              相关模块:

              graphics模块。

              环境搭建

              安装Python并添加到环境变量即可。

              注:

              graphics模块在相关文件中已经提供,就是一个py文件,直接放在当前路径或者放到python安装文件夹下的site-packages文件夹内均可。

              原理简介

              对于五子棋这样的博弈类AI,很自然的想法就是让计算机把当前所有可能的情况都尝试一遍,找到最优的落子点。这里有两个问题:

              (1)如何把所有可能的情况都尝试一遍;

              (2)如何定量判断某落子点的优劣。

              对于第一个问题,其实就是所谓的博弈树搜索,对于第二个问题,其实就是所谓的选择评估函数。评估函数的选取直接决定了AI算法的优劣,其形式也千变万化。可以说,每个评估函数就是一个选手,对不同的棋型每个选手自然有不同的看法和应对措施,当然他们的棋力也就因此各不相同了。

              但博弈树搜索就比较固定了,其核心思想无非是让计算机考虑当前局势下之后N步所有可能的情况,其中奇数步(因为现在轮到AI下)要让AI方的得分最大,偶数步要让AI方的得分最小(因为对手也就是人类,也可以选择最优策略)。

              当然这样的搜索其计算量是极大的,这时候就需要剪枝来减少计算量。例如下图:

              其中A代表AI方,P代表人类方。AI方搜索最大值,人类方搜索最小值。因此Layer3的A1向下搜索的最终结果为4,Layer3的A2向下搜索,先搜索Layer4的P3,获得的分值为6,考虑到Layer2的P1向下搜索时取Layer3的A1和A2中的较小值,而Layer3的A2搜索完Layer4的P3时,其值就已经必大于Layer3的A1了,就没有搜索下去的必要了,因此Layer3到Layer4的路径3就可以剪掉了。

              上述搜索策略其实质就是:

              minimax算法+alpha-beta剪枝算法。

              了解了上述原理之后,就可以自己写代码实现了。当然实际实现过程中,我做了一些简化,但万变不离其宗,其核心思想都是一样的。

              具体实现过程详见相关文件中的源代码。

              使用演示

              在cmd窗口运行GobangAI.py文件即可。

              下面的视频是我和AI的一局对弈,我执黑先行,所以赢的比较轻松T_T。毕竟五子棋先手者优势巨大,或者说在某些情况/规则下是必胜的。至于原因,在相关文件中提供了两篇论文,感兴趣的可以看看。

              点击查看视频

              更多

              之后有时间的话会研究一下基于深度学习的AI五子棋算法,目前这个版本还是比较low的,当然你好好和它下的话,它还是可以走出一些精妙的步子的。

              T_T没有仔细测试,如果有什么bug可以留言反馈给我,我会进行修复。

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              好久以前看到有人做过。。

              今天心血来潮。。

              就想自己试试。。

              仅此而已。。

              用的PyQt版本是5.10.。。

              网上关于PyQt5.10的中文教程=None。。

              所以最后做出来的效果一般(毕竟短时间内啃不动官方那全英文的教程)。。

              So,

              don't get your hopes up...


              源码地址:

              https://github.com/RogerLZH/Browser.git

              主要思路

              主要实现的功能:

              (1)可以正常显示网页;

              (2)设置导航栏,用以实现浏览器的前进、后退、停止加载和刷新功能;

              (3)设置地址栏,可以实时更新当前网页的URL,同时支持输入地址回车访问功能;

              (4)设置标签页,可通过双击导航栏打开新的标签页,从而支持同时访问多个页面。

              底层传输协议等功能的实现方式:

              借助PyQt5的QtWebEngine模块。

              具体实现过程见源代码(有较为详细的注释)。

              不足之处

              初步测试无Bug,但有时会有卡顿。。。

              感兴趣者可自行优化。。。

              欢迎后台交流(T_T如果不嫌弃我是刚入坑半天的小白的话)。。。

              欢迎在后台提出修改意见。。。

              若有必要,我可以再水一篇类似“Python制作简易浏览器(后续优化)”的文章hhhhh。。。

              开发工具

              Python版本:3.5.4

              相关模块:

              PyQt5模块(5.10版本)以及一些Python自带的模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              使用演示

              在cmd窗口运行Create_Browser.py文件即可。

              如下图所示:

              更多

              PyQt5快速入门文档已分享在此公众号底部菜单栏中,供有需要者参考。

              文档主要参考了CSDN上的一些博文整理的且亲测PyQt5.10版本可用。

              日后有时间将整理PyQt5.10版本完整使用文档。


              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              利用Python实现手写笔记的压缩与增强。

              至于起因大概是:

              这个内容很有趣。。。

              ——>

              说了等于没说。T_T

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/1oagM2fbKUJXSiZ93S_Mszg 

              密码: 47ws

              参考文献

              链接:

              https://mzucker.github.io/2016/09/20/noteshrink.html

              作者:

              Matt Zucker

              主要思路

              Step1:确定背景色

              假定纸张颜色是扫描图像中最常出现的那一种颜色。

              同时将8比特每通道消减至6比特每通道来增加背景色获取的可靠性。

              Step2:分离前景色

              将色彩从RGB空间映射到HSV空间来实现分离前景色的功能。

              规则默认为:

              (1)明亮度V比背景色大0.3以上;

              (2)饱和度S比背景色大0.2以上。

              满足其中一条即为前景色。

              Step3:选择呈现色

              相当于使用簇分析法解决一个色彩量化问题。

              将原始24位每像素的图像转换成一个具有小数量代表色的图像。

              主要使用K均值算法实现。

              其他说明:

              (1)默认情况下,程序会通过重新设置颜色的最大最小强度值为0到255,来增加最后调色板各色的艳丽度和对比度;

              (2)程序默认情况下自动地根据输入文件名排序,关键字为数字。

              开发工具

              Python版本:3.5.4

              相关模块:Scipy模块、numpy模块、PIL模块以及一些Python自带的模块。

              环境搭建:安装Python并添加到环境变量,pip安装需要的相关模块即可。

              使用演示

              全部功能选项:

              基本功能使用:

              py -3.5 Note_Processor.py + 待处理的笔记图片名

              例如下图:

              结果展示

              笔记1:

              结果图:

              笔记2:

              结果图:

              更多

              若对结果不满意,请自行在命令行窗口设置相应的参数,即不要使用默认值;

              例如:



              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              不要被上面的照片所迷惑。。。

              Python做上面的照片?

              不存在的。。。

              只是最近看到好多jQuery+H5的表白代码。。。

              想着用Python应该也可以?

              Just have a try~~~

              提前声明

              T_T请不要信任我在这方面的审美水平;

              T_T代码仅供参考,使用前请自行精心优化,否则被拒概率或许将高达99.99%。

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/1dc6-tFgBpAgnQUbci87l9Q 

              密码: yyrw

              开发工具

              Python版本:3.5.4

              相关模块:jieba模块、scipy模块、wordcloud模块、pygame模块、matplotlib模块以及一些Python自带的模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              尝试一:画表白树

              具体原理见源代码吧~~~

              其实就是一个递归而已~~~

              使用方式:

              在cmd窗口运行Unburden.py文件即可:

              效果:

              视频链接

              尝试二:词云

              原理也很简单就不多说了~~~

              (T_T详见源代码)

              使用方式:

              在cmd窗口运行Confession.py文件即可:

              效果图:

              (1)英文情诗

              (2)周董的歌

              更多

              确实没有什么精力去优化这些东西。。。

              So,

              如果你真的用到的话。。。

              用之前一定要自己再精致地优化一波呀!!!

              T_T

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              做这个的起因大概是:

              电脑里的Xshell不知道为啥突然显示“评估期已过”之类的提示。。。

              记得之前认证学校邮箱后是可以免费使用的。。。

              苍天绕过谁。。。

              想起上次认证学校邮箱过了N个小时才收到那封认证的邮件。。。

              我决定。。。

              自己动手,丰衣足食。。。

              反正好多天没更公众号了。。。正好水一波。。。

              Just have a try!

              相关文件

              百度网盘下载链接: https://pan.baidu.com/s/1-GK9-zdbvanTEXphSN2SmQ

              密码: djdj

              开发工具

              Python版本:3.5.4

              相关模块:paramiko模块以及一些Python自带的模块。

              操作系统:Windows系列。

              环境搭建:安装Python并添加到环境变量,pip安装需要的相关模块即可。

              主要思路

              目的:

              制作命令行版的SSH登录工具。

              需要实现的功能:

              (1)添加/删除连接服务器需要的IP、端口、密码;

              (2)自动输入密码登录远程服务器。

              具体思路详见源代码。

              PS:

              本着用了Python那就尽量不制造轮子的原则,SSH登录主要借助了paramiko模块。

              使用演示

              放个flash视频吧。。。

              懒得截图了。。。

              视频链接

              更多

              此代码仅适用于Windows系统。

              有兴趣者可自行修改源代码制作Mac/Linux版本。

              使用过程中若有任何优化意见:

              欢迎后台交流!

              以后若有时间将进一步优化和扩展该脚本。

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              利用Python简单实现图片隐写术。。。

              或者说是水印技术。。。

              说实话,真的只是简单实现。。。

              没什么技术含量。。。

              可以说是入门级的隐写术/水印技术。。。

              Let's Go?

              相关文件

              百度网盘链接: https://pan.baidu.com/s/1DNVk11rMcFk9u-B7GE4Jow 

              密码: 9ffy

              开发工具

              Python版本:3.5.4

              相关模块:cv2模块;pillow模块;numpy模块;以及一些Python自带的模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              原理简介

              相关文件中的源代码主要实现了两种水印技术:

              (1)空域数字水印

              实现的是基于LSB的水印技术。。。

              (2)频域数字水印

              实现的是基于FFT的水印技术。。。

              T_T确实没啥技术含量吧?

              图片需为PNG或BMP格式。。。

              若频域数字水印效果不佳,请修改alpha因子大小。

              具体实现过程详见源代码。。。

              使用演示

              可直接运行或作为模块导入。

              功能:

              直接运行方式:

              在cmd窗口运行Watermark.py即可。

              演示一:基于FFT

              载体图片:

              水印图片:

              嵌入效果:

              解水印:

              演示二:基于LSB

              载体图片:

              水印文字:

              公众号:Charles的皮卡丘

              嵌入效果:

              解水印:

              更多

              上述内容只是入门级的隐写术/水印技术。。。

              这是一项非常有趣的技术。。。

              以后有机会会复现一些进阶版的水印算法。。。

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              导语

              Hi,好久不见~~~

              两周没写东西了,从简单的开始,慢慢提高文章水准吧,下一个月开始时间就会比较充裕了~~~

              利用Python实现简单的车牌检测算法~~~

              让我们愉快地开始吧~~~

              相关文件

              网盘下载链接: https://pan.baidu.com/s/1iJmXCheJoWqpjEZdL5D3AA 

              密码: wjcd

              开发工具

              Python版本:3.6.4

              相关模块:cv2模块;numpy模块。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              原理简介

              注意这不是车牌号识别,是车牌检测。

              因为车牌形状比较单一,所以我参考了一些简单的传统算法实现的,没有使用深度学习。效果比较一般。不适用于复杂环境下的车牌检测。

              直接调的OpenCV的函数接口,没有从0开始实现,所以总体技术含量较低。

              其流程为:

              Step1:

              对图片进行一些预处理,包括灰度化、高斯平滑、中值滤波、Sobel算子边缘检测等等。

              Step2:

              利用OpenCV对预处理后的图像进行轮廓查找,然后根据一些参数判断该轮廓是否为车牌轮廓。

              具体实现过程详见相关文件中的源代码。

              使用演示

              在cmd窗口运行detect.py文件即可。

              使用前请先指定需要检测的图片路径:

              效果如下:

              原图1:

              检测结果1:

              原图2:

              检测结果:

              原图3:

              检测结果3:

              That's all~

              更多

              车牌检测和车牌识别其实算是很成熟的技术了。

              所以我做的仅代表菜鸟级水平。

              随便看了一会试着写的代码。

              之后会逐渐提高水准的T_T,好久不发文不太习惯了hhhh。

              那就这样吧~~~

              本文转载至知乎ID:Charles(白露未晞)知乎个人专栏
              下载W3Cschool手机App,0基础随时随地学编程>>戳此了解

              视频预览


              点击链接查看视频

              导语

              利用简单的Python和VBA程序在Excel中生成小姐姐。

              感觉很有趣,让我们愉快地开始吧~~~

              相关文件

              关注微信公众号“Charles的皮卡丘”回复‘小姐姐’获取。

              开发工具

              Python版本:3.6.4

              相关模块:PIL模块;openpyxl模块;以及一些Python自带的模块。

              Excel版本:Excel2016。

              环境搭建

              安装Python并添加到环境变量,pip安装需要的相关模块即可。

              实现过程

              Step1:

              利用Python将小姐姐照片上各像素的RGB信息(随机)输出到Excel文件的Sheet2中。

              注意照片不宜过大,否则不利于后续操作。

              实现方式:

              在cmd窗口运行"Gen_Excel.py"文件(或者直接双击运行"Gen_Excel.exe"文件),并根据提示输入小姐姐照片的路径即可:

              Step2:

              读取Sheet2中的像素值信息并填充到Sheet1中。

              实现方式:

              打开Step1中生成的Excel文件(默认文件名为"test.xlsx"),按下"Alt+F11"打开VB编辑器后新建一个模块:

              将相关文件中提供的"VBA.txt"文件里的第一段代码复制进模块:

              同时,为了使Excel文件打开后自动生成小姐姐的图片,设置一下Workbook_open事件,即将"VBA.txt"文件里的第二段代码复制到"ThisWorkbook"中:

              最后,将该".xlsx"格式的excel文件(默认为"test.xlsx")另存为".xlsm"格式的excel文件以保证宏正常运行:

              Step3:

              打开".xlsm"格式的excel文件,可以发现最终的结果是这样子的:

              而原图是这样子的:

              因此我们需要调整一下图片所在单元格的列宽、行高和页面缩放级别使其长宽比与原图一致(网上淘的图,所以质量差了点):

              最后隐藏一下Sheet2以免露馅:

              OK,大功告成!!!

              关闭".xlsm"格式的excel文件后重新打开即可获得文章开头视频中的效果~

              更多

              更多

              相关文件里有打包好的exe文件,所以环境搭建一步是可以略去的~~~

              图片可以是任意的小姐姐、小哥哥以及一些萌萌的小动物等等~~~

              VBScript CDate 函数

              VBScript CDate 函数返回表达式,此表达式已被转换为 Date 子类型的 Variant


              VBScript 参考手册 完整的 VBScript 参考手册

              CDate 函数把有效的日期和时间表达式转换为日期(Date)类型,并返回结果。p>

              提示:请使用 IsDate 函数来判断 date 是否可被转换为日期或时间。

              注意:IsDate 函数使用本地设置来检测字符串是否可被转换为日期(在所有的语言中,"January"不是一个月份)。

              语法

              CDate(date)

              参数

              参数 描述
              date 必需。任何有效的日期表达式(比如 Date() 或者 Now())。


              实例

              实例 1

              如何把字符串转换为日期:

              <script type="text/vbscript">

              d=CDate("April 22, 2010")

              </script>

              尝试一下 »

              实例 2

              如何把带分隔符的数字转换为日期:

              <script type="text/vbscript">

              d=CDate(#4/22/10#)

              </script>

              尝试一下 »

              实例 3

              如何使用 CDATE 把字符串转换为一个时间对象:

              <script type="text/vbscript">

              d=CDate("3:18:40 AM")

              </script>

              尝试一下 »


              VBScript 参考手册 完整的 VBScript 参考手册

              相关文章

              VBScript IsDate 函数

              云存储提供高可用、高稳定、强安全的云端存储服务,支持任意数量和形式的非结构化数据存储,如视频和图片,并在控制台进行可视化管理。云存储包含以下功能:

              • 存储管理:支持文件夹,方便文件归类。支持文件的上传、删除、移动、下载、搜索等,并可以查看文件的详情信息
              • 权限设置:可以灵活设置哪些用户是否可以读写该文件夹中的文件,以保证业务的数据安全
              • 上传管理:在这里可以查看文件上传历史、进度及状态
              • 文件搜索:支持文件前缀名称及子目录文件的搜索
              • 组件支持:支持在 image、audio 等组件中传入云文件 ID

              接下来,我们看看云文件管理提供了哪些 API、及如何在控制台中管理云文件:

              • 存储 API
              • 控制台中管理文件

              API 指引

              上传文件

              在小程序端可调用 wx.cloud.uploadFile 方法进行上传:

              wx.cloud.uploadFile({  cloudPath: 'example.png', // 上传至云端的路径  filePath: '', // 小程序临时文件路径  success: res => {    // 返回文件 ID    console.log(res.fileID)  },  fail: console.error})

              上传成功后会获得文件唯一标识符,即文件 ID,后续操作都基于文件 ID 而不是 URL。

              下载文件

              可以根据文件 ID 下载文件,用户仅可下载其有访问权限的文件:

              wx.cloud.downloadFile({  fileID: '', // 文件 ID  success: res => {    // 返回临时文件路径    console.log(res.tempFilePath)  },  fail: console.error})

              删除文件

              可以通过 wx.cloud.deleteFile 删除文件:

              wx.cloud.deleteFile({  fileList: ['a7xzcb'],  success: res => {    // handle success    console.log(res.fileList)  },  fail: console.error})

              更详细的 API 可参考小程序端及后端存储 API 文件。

              组件支持

              支持在 image、audio 等组件中传入云文件 ID,具体支持列表见文档

              换取临时链接

              可以根据文件 ID 换取临时文件网络链接,文件链接有有效期为两个小时:

              wx.cloud.getTempFileURL({  fileList: ['cloud://xxx.png'],  success: res => {    // fileList 是一个有如下结构的对象数组    // [{    //    fileID: 'cloud://xxx.png', // 文件 ID    //    tempFileURL: '', // 临时文件网络链接    //    maxAge: 120 * 60 * 1000, // 有效期    // }]    console.log(res.fileList)  },  fail: console.error})

              API 文档

              可以在此参考详细的小程序端存储 API 文档和服务端 API 文档


              管理文件

              在控制台中,选择存储管理标签页,可以在此看到云存储空间中所有的文件,还可以查看文件的详细信息、控制存储空间的读写权限。



              文件名命名限制

              • 不能为空
              • 不能以/开头
              • 不能出现连续/
              • 编码长度最大为850个字节
              • 推荐使用大小写英文字母、数字,即[a-z,A-Z,0-9]和符号 -,!,_,.,* 及其组合
              • 不支持 ASCII 控制字符中的字符上(↑),字符下(↓),字符右(→),字符左(←),分别对应 CAN(24),EM(25),SUB(26),ESC(27)
              • 如果用户上传的文件或文件夹的名字带有中文,在访问和请求这个文件或文件夹时,中文部分将按照 URL Encode 规则转化为百分号编码。
              • 不建议使用的特殊字符: ` ^ " { } [ ] ~ % # > < 及 ASCII 128-255 十进制
              • 可能需特殊处理后再使用的特殊字符: , : ; = & $ @ + ?(空格)及ASCII 字符范围:00-1F 十六进制(0-31 十进制)以及7F(127 十进制)

              组件支持

              小程序组件支持传入云文件 ID,支持列表如下:

              组件属性
              imagesrc
              videosrc、poster
              cover-imagesrc
              接口参数
              getBackgroundAudioManagersrc
              createInnerAudioContextsrc
              previewImageurls、current


              None
              None
              None

              Python的备忘单是用于Python 3的编程语言中的单页参考表。

              开始

              介绍

              Hello World

              >>> print("Hello, World!")Hello, World!

              Python 中著名的“Hello World”程序

              变量

              x = 4        # x is of type intx = "Sally"  # x is now of type strprint(x)

              Python 没有用于声明变量的命令。

              数据类型

              str文本
              int, float,complex数字
              list, tuple,range序列
              dict映射
              set, frozenset集合
              bool布尔值
              bytes, bytearray,memoryview二进制

              请参阅:数据类型

              切片字符串

              >>> b = "Hello, World!">>> print(b[2:5])llo

              请参阅:字符串

              列表

              mylist = []mylist.append(1)mylist.append(2)for x in mylist:    print(x) # prints out 1,2

              请参阅:列表

              if-else

              a = 200if a > 0:    print("a is greater than 0")else:    print("a is not greater than 0")

              请参阅:流量控制

              循环

              for x in range(6):    if x == 3: break    print(x)else:    print("Finally finished!")

              请参阅:循环

              函数

              >>> def my_function():...     print("Hello from a function")...>>> my_function()Hello from a function

              请参阅:函数

              文件处理

              with open("myfile.txt", "r", encoding='utf8') as file:    for x in file:        print(x)

              请参阅:文件处理

              算术运算符

              result = 10 + 30  # =>  40result = 40 - 10  # =>  30result = 50 * 5   # =>  250result = 16 / 4   # =>  4result = 25 % 2   # =>  1result = 5 ** 3   # =>  125

              加等于

              counter = 0counter += 10           # => 10counter = 0counter = counter + 10  # => 10message = "Part 1."# => Part 1.Part 2.message += "Part 2."   

              Python 数据类型

              字符串

              s = "Hello World"s = 'Hello World'a = """Multiline StringsLorem ipsum dolor sit amet,consectetur adipiscing elit """

              请参阅:字符串

              数字

              x = 1    # inty = 2.8  # floatz = 1j   # complex>>> print(type(x))<class 'int'>

              布尔值

              a = True b = Falsebool(0)     # => Falsebool(1)     # => True

              列表

              list1 = ["apple", "banana", "cherry"]list2 = [True, False, False]list3 = [1, 5, 7, 9, 3]list4 = list((1, 5, 7, 9, 3))

              请参阅:列表

              元组

              a = (1, 2, 3)a = tuple((1, 2, 3))

              类似于 List 但不可变

              集合

              set1 = {"a", "b", "c"}   set2 = set(("a", "b", "c"))

              一组独特的项目/对象

              字典

              >>> empty_dict = {}>>> a = {"one": 1, "two": 2, "three": 3}>>> a["one"]1>>> a.keys()dict_keys(['one', 'two', 'three'])>>> a.values()dict_values([1, 2, 3])>>> a.update({"four": 4})>>> a.keys()dict_keys(['one', 'two', 'three', 'four'])>>> a['four']4

              键:值对,类JSON对象

              赋值

              整数

              x = int(1)   # x will be 1y = int(2.8) # y will be 2z = int("3") # z will be 3

              浮动

              x = float(1)     # x will be 1.0y = float(2.8)   # y will be 2.8z = float("3")   # z will be 3.0w = float("4.2") # w will be 4.2

              字符串

              x = str("s1") # x will be 's1'y = str(2)    # y will be '2'z = str(3.0)  # z will be '3.0'

              Python 字符串

              类似数组

              >>> a = "Hello, World">>> print(a[1])e>>> print(a[len(a)-1])d

              获取位置 1 处的字符

              循环

              >>> for x in "abc":...     print(x)abc

              循环遍历单词“banana”中的字母

              切片字符串

               ┌───┬───┬───┬───┬───┬───┬───┐ | m | y | b | a | c | o | n | └───┴───┴───┴───┴───┴───┴───┘ 0   1   2   3   4   5   6   7-7  -6  -5  -4  -3  -2  -1

              >>> s = 'mybacon'>>> s[2:5]'bac'>>> s[0:2]'my'
              >>> s = 'mybacon'>>> s[:2]'my'>>> s[2:]'bacon'>>> s[:2] + s[2:]'mybacon'>>> s[:]'mybacon'
              >>> s = 'mybacon'>>> s[-5:-1]'baco'>>> s[2:6]'baco'

              切片方式

              >>> s = '12345' * 5>>> s'1234512345123451234512345'>>> s[::5]'11111'>>> s[4::5]'55555'>>> s[::-5]'55555'>>> s[::-1]'5432154321543215432154321'

              字符串长度

              >>> a = "Hello, World!">>> print(len(a))13

              len() 函数返回字符串的长度

              多次复制

              >>> s = '===+'>>> n = 8>>> s * n'===+===+===+===+===+===+===+===+'

              检查字符串

              >>> s = 'spam'>>> s in 'I saw spamalot!'True>>> s not in 'I saw The Holy Grail!'True

              连接

              >>> s = 'spam'>>> t = 'egg'>>> s + t'spamegg'>>> 'spam' 'egg''spamegg'

              格式化

              name = "John"print("Hello, %s!" % name)
              name = "John"age = 23print("%s is %d years old." % (name, age))

              format() 方法

              txt1 = "My name is {fname}, I'm {age}".format(fname = "John", age = 36)txt2 = "My name is {0}, I'm {1}".format("John",36)txt3 = "My name is {}, I'm {}".format("John",36)

              input

              >>> name = input("Enter your name: ")Enter your name: Tom>>> name'Tom'

              从控制台获取输入数据

              join

              >>> "#".join(["John", "Peter", "Vicky"])'John#Peter#Vicky'

              endswith

              >>> "Hello, world!".endswith("!")True

              Python 列表

              定义

              >>> li1 = []>>> li1[]>>> li2 = [4, 5, 6]>>> li2[4, 5, 6]>>> li3 = list((1, 2, 3))>>> li3[1, 2, 3]>>> li4 = list(range(1, 11))>>> li4[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

              生成

              >>> list(filter(lambda x : x % 2 == 1, range(1, 20)))[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]>>> [x ** 2 for x in range (1, 11) if  x % 2 == 1][1, 9, 25, 49, 81]>>> [x for x in [3, 4, 5, 6, 7] if x > 5][6, 7]>>> list(filter(lambda x: x > 5, [3, 4, 5, 6, 7]))[6, 7]

              append

              >>> li = []>>> li.append(1)>>> li[1]>>> li.append(2)>>> li[1, 2]>>> li.append(4)>>> li[1, 2, 4]>>> li.append(3)>>> li[1, 2, 4, 3]

              列表切片

              列表切片的语法:

              a_list[start:end]a_list[start:end:step]

              切片

              >>> a = ['spam', 'egg', 'bacon', 'tomato', 'ham', 'lobster']>>> a[2:5]['bacon', 'tomato', 'ham']>>> a[-5:-2]['egg', 'bacon', 'tomato']>>> a[1:4]['egg', 'bacon', 'tomato']

              省略索引

              >>> a[:4]['spam', 'egg', 'bacon', 'tomato']>>> a[0:4]['spam', 'egg', 'bacon', 'tomato']>>> a[2:]['bacon', 'tomato', 'ham', 'lobster']>>> a[2:len(a)]['bacon', 'tomato', 'ham', 'lobster']>>> a['spam', 'egg', 'bacon', 'tomato', 'ham', 'lobster']>>> a[:]['spam', 'egg', 'bacon', 'tomato', 'ham', 'lobster']

              切片方式

              ['spam', 'egg', 'bacon', 'tomato', 'ham', 'lobster']>>> a[0:6:2]['spam', 'bacon', 'ham']>>> a[1:6:2]['egg', 'tomato', 'lobster']>>> a[6:0:-2]['lobster', 'tomato', 'egg']>>> a['spam', 'egg', 'bacon', 'tomato', 'ham', 'lobster']>>> a[::-1]['lobster', 'ham', 'tomato', 'bacon', 'egg', 'spam']

              pop

              >>> li = ['bread', 'butter', 'milk']>>> li.pop()'milk'>>> li['bread', 'butter']>>> del li[0]>>> li['butter']

              使用权

              >>> li = ['a', 'b', 'c', 'd']>>> li[0]'a'>>> li[-1]'d'>>> li[4]Traceback (most recent call last):  File "<stdin>", line 1, in <module>IndexError: list index out of range

              串联

              >>> odd = [1, 3, 5]>>> odd.extend([9, 11, 13])>>> odd[1, 3, 5, 9, 11, 13]>>> odd = [1, 3, 5]>>> odd + [9, 11, 13][1, 3, 5, 9, 11, 13]

              排序和反转

              >>> li = [3, 1, 3, 2, 5]>>> li.sort()>>> li[1, 2, 3, 3, 5]>>> li.reverse()>>> li[5, 3, 3, 2, 1]

              计数

              >>> li = [3, 1, 3, 2, 5]>>> li.count(3)2

              重复

              >>> li = ["re"] * 3>>> li['re', 're', 're']

              Python 流控制

              基本的

              a = 5if a > 10:    print("a is totally bigger than 10.")elif a < 10:    print("a is smaller than 10.")else:    print("a is indeed 10.")

              一行代码

              >>> a = 330>>> b = 200>>> r = "a" if a > b else "b">>> print(r)a

              if-elif-else

              value = Trueif not value:    print("Value is False")elif value is None:    print("Value is None")else:    print("Value is True")

              Python 循环

              基本的

              primes = [2, 3, 5, 7]for prime in primes:    print(prime)

              带索引

              animals = ["dog", "cat", "mouse"]for i, value in enumerate(animals):    print(i, value)

              while

              x = 0while x < 4:    print(x)    x += 1  # Shorthand for x = x + 1

              break

              x = 0for index in range(10):    x = index * 10    if index == 5:    	break    print(x)

              continue

              for index in range(3, 8):     x = index * 10    if index == 5:    	continue    print(x)

              range 范围

              for i in range(4):    print(i) # Prints: 0 1 2 3for i in range(4, 8):    print(i) # Prints: 4 5 6 7for i in range(4, 10, 2):    print(i) # Prints: 4 6 8

              zip()

              name = ['Pete', 'John', 'Elizabeth']age = [6, 23, 44]for n, a in zip(name, age):    print('%s is %d years old' %(n, a))

              列表理解

              result = [x**2 for x in range(10) if x % 2 == 0] print(result)# [0, 4, 16, 36, 64]

              Python 函数

              基本的

              def hello_world():      print('Hello, World!')

              return

              def add(x, y):    print("x is %s, y is %s" %(x, y))    return x + yadd(5, 6)    # => 11

              位置参数

              def varargs(*args):    return argsvarargs(1, 2, 3)  # => (1, 2, 3)

              关键字参数

              def keyword_args(**kwargs):    return kwargs# => {"big": "foot", "loch": "ness"}keyword_args(big="foot", loch="ness")

              返回多个

              def swap(x, y):    return y, xx = 1y = 2x, y = swap(x, y)  # => x = 2, y = 1

              默认值

              def add(x, y=10):    return x + yadd(5)      # => 15add(5, 20)  # => 25

              匿名函数

              # => True(lambda x: x > 2)(3)# => 5(lambda x, y: x ** 2 + y ** 2)(2, 1)

              Python 模块

              导入模块

              import mathprint(math.sqrt(16))  # => 4.0

              从一个模块

              from math import ceil, floorprint(ceil(3.7))   # => 4.0print(floor(3.7))  # => 3.0

              全部导入

              from math import *

              缩短模块

              import math as m# => Truemath.sqrt(16) == m.sqrt(16)

              功能和属性

              import mathdir(math)

              Python 文件处理

              读取文件

              逐行

              with open("myfile.txt") as file:    for line in file:        print(line)

              带行号

              input = open('myfile.txt', 'r')for i,line in enumerate(input, start=1):    print("Number %s: %s" % (i, line))

              String

              写一个字符串

              contents = {"aa": 12, "bb": 21}with open("myfile1.txt", "w+") as file:    file.write(str(contents))

              读取字符串

              with open('myfile1.txt', "r+") as file:    contents = file.read()print(contents)

              目的

              写一个对象

              contents = {"aa": 12, "bb": 21}with open("myfile2.txt", "w+") as file:    file.write(json.dumps(contents))

              读取对象

              with open('myfile2.txt', "r+") as file:    contents = json.load(file)print(contents)

              删除文件

              import osos.remove("myfile.txt")

              检查和删除

              import osif os.path.exists("myfile.txt"):    os.remove("myfile.txt")else:    print("The file does not exist")

              删除文件夹

              import osos.rmdir("myfolder")

              Python 类和继承

              定义

              class MyNewClass:    '''This is a docstring.'''    pass# Class Instantiationmy = MyNewClass()

              构造函数

              class Animal:    def __init__(self, voice):    self.voice = voice cat = Animal('Meow')print(cat.voice)    # => Meow dog = Animal('Woof') print(dog.voice)    # => Woof

              方法

              class Dog:    # Method of the class    def bark(self):    print("Ham-Ham") charlie = Dog()charlie.bark()   # => "Ham-Ham"

              类变量

              class my_class:    class_variable = "A class variable!"  x = my_class()y = my_class() # => A class variable!print(x.class_variable)# => A class variable!print(y.class_variable)

              Super() 函数

              class ParentClass:    def print_test(self):        print("Parent Method") class ChildClass(ParentClass):    def print_test(self):        print("Child Method")        # Calls the parent's print_test()        super().print_test() 

              >>> child_instance = ChildClass()>>> child_instance.print_test()Child MethodParent Method

              repr() 方法

              class Employee:    def __init__(self, name):        self.name = name     def __repr__(self):        return self.name john = Employee('John')print(john)  # => John

              用户定义的异常

              class CustomError(Exception):    pass

              多态性

              class ParentClass:    def print_self(self):        print('A') class ChildClass(ParentClass):    def print_self(self):        print('B') obj_A = ParentClass()obj_B = ChildClass() obj_A.print_self() # => Aobj_B.print_self() # => B

              覆盖

              class ParentClass:    def print_self(self):        print("Parent") class ChildClass(ParentClass):    def print_self(self):        print("Child") child_instance = ChildClass()child_instance.print_self() # => Child

              继承

              class Animal:     def __init__(self, name, legs):        self.name = name        self.legs = legs        class Dog(Animal):    def sound(self):        print("Woof!") Yoki = Dog("Yoki", 4)print(Yoki.name) # => YOKIprint(Yoki.legs) # => 4Yoki.sound()     # => Woof!

              其他

              注释

              # This is a single line comments.
              """ Multiline strings can be written    using three "s, and are often used    as documentation."""
              ''' Multiline strings can be written    using three 's, and are often used    as documentation.'''

              生成器

              def double_numbers(iterable):    for i in iterable:        yield i + i

              生成器可以帮助您编写懒惰的代码。

              要列出的生成器

              values = (-x for x in [1,2,3,4,5])gen_to_list = list(values)# => [-1, -2, -3, -4, -5]print(gen_to_list)

              处理异常

              try:    # Use "raise" to raise an error    raise IndexError("This is an index error")except IndexError as e:    pass                 # Pass is just a no-op. Usually you would do recovery here.except (TypeError, NameError):    pass                 # Multiple exceptions can be handled together, if required.else:                    # Optional clause to the try/except block. Must follow all except blocks    print("All good!")   # Runs only if the code in try raises no exceptionsfinally:                 # Execute under all circumstances    print("We can clean up resources here")


              字符串(string,简写为str)是 Python 中最常用的数据类型之一。我们可以使用引号( ' 或 " )来创建字符串。

              创建字符串很简单,只要为变量分配一个值即可。例如:

              var1 = 'Hello World!' var2 = "W3Cschool"

              Python 访问字符串中的值

              Python 不支持单字符类型,单字符在 Python 中也是作为一个字符串使用。

              Python 访问子字符串,可以使用方括号 ​[]​来截取字符串(这种方式也被称为切片),字符串的截取的语法格式如下:

              变量[头下标:尾下标]

              python截取的特点是取头下标的值到尾下标的值(尾下标的值不取)

              索引值以 0 为开始值,-1 为从末尾的开始位置。

              从后面索引   -9 -8 -7 -6 -5-4-3-2-1 
              从前面索引 012345678 
                W  3Cschool
              从前面截取 :  12345678: 
               从后面截取 :
              -8-7-6-5-4-3-2-1: 

              以下代码都是取字符C:

              str="W3cschool"print(str[2:3]) #使用截取方式,用正序进行截取print(str[2:-6])#使用截取方式,正序和倒序混合使用print(str[-7:-6])#使用截取方式,使用倒序进行截取print(str[-7])#使用负索引获取单个字符Cprint(str[2])#使用正索引获取单个字符C

              切片的更多案例:

              str="W3cschool"#取W3Cprint(str[:3]) print(str[:-6])#取schprint(str[3:6])print(str[-6:-3])#只有头下标/尾下标的情况print(str[:3])#只有尾下标的情况,默认头下标为0(正序的0,也就是字符串开始的地方)#也就是从字符串开头截取到3的位置(也就是W3C)print(str[3:])#只有头下标的情况,默认尾下标为0(逆序的0,也就是字符串结束的地方)#也就是从3的位置截取到字符串结尾(也就是school)#更多应用str2 ="https://www.51coolma.cn/"#截取协议名称print(str2[:5]) #也就是截取前五位#截取域名print(str2[8:-1]) #也就是截取第八位到倒数第一位

              Python转义字符

              有一些字符因为在python中已经被定义为一些操作(比如单引号和双引号被用来引用字符串),而这些符号我们可能在字符串中需要使用到。为了能够使用这些特殊字符,可以用反斜杠  转义字符(同样地,反斜杠也可以用来转义反斜杠)。如下表:

              转义字符描述实例
              (在行尾时)续行符
              >>> print("line1 ... line2 ... line3")line1 line2 line3>>> 
              反斜杠符号
              >>> print("")
              '单引号
              >>> print(''')'
              "双引号
              >>> print(""")"
              a响铃
              >>> print("a")
              执行后电脑有响声。
              退格(Backspace)
              >>> print("Hello  World!")Hello World!
              00
              >>> print("00")>>> 
              换行
              >>> print("
              ")>>>
              v纵向制表符
              >>> print("Hello v World!")Hello        World!>>>
              横向制表符
              >>> print("Hello 	 World!")Hello      World!>>>
              回车,将   后面的内容移到字符串开头,并逐一替换开头部分的字符,直至将   后面的内容完全替换完成。
              >>> print("Hello
              World!")World!>>> print('google runoob taobao
              123456')123456 runoob taobao
              f换页
              >>> print("Hello f World!")Hello        World!>>> 
              yyy八进制数,y 代表 0~7 的字符,例如:12 代表换行。
              >>> print("1101451541541574012715716215414441")Hello World!
              xyy十六进制数,以 x 开头,y 代表的字符,例如:x0a 代表换行
              >>> print("x48x65x6cx6cx6fx20x57x6fx72x6cx64x21")Hello World!
              other其它的字符以普通格式输出 

              Python字符串运算符

              下表实例变量 a 值为字符串 "Hello",b 变量值为 "W3Cschool":

              操作符描述实例
              +字符串连接a + b 输出结果: HelloW3Cschool
              >>> a ="hello">>> b = "W3Cschool">>> a+b'helloW3Cschool'
              *重复输出字符串a*2 输出结果:HelloHello
              >>> a ="hello">>> b = "W3Cschool">>> a*2'hellohello'
              []通过索引获取字符串中字符a[1] 输出结果 e
              >>> a ="hello">>> b = "W3Cschool">>> a[1]'e'
              [ : ]截取字符串中的一部分(切片),遵循左闭右开原则,str[0:2] 是不包含第 3 个字符的(详见上上节内容)。a[1:4] 输出结果 ell
              >>> a ="hello">>> b = "W3Cschool">>> a[1:4]'ell'
              in成员运算符 - 如果字符串中包含给定的字符返回 True'H' in a 输出结果 ​True
              >>> a ="hello">>> b = "W3Cschool">>> 'h' in aTrue
              not in成员运算符 - 如果字符串中不包含给定的字符返回 True'M' not in a 输出结果 ​True
              >>> a ="hello">>> b = "W3Cschool">>> 'M' not in aTrue
              r/R原始字符串 - 原始字符串:所有的字符串都是直接按照字面的意思来使用,没有转义特殊或不能打印的字符。 原始字符串除在字符串的第一个引号前加上字母 r(不区分大小写)以外,与普通字符串有着几乎完全相同的语法。

              >>> str="W3Cschool "

              >>> str2=r"W3Cschool "

              >>> print(str)

              W3Cschool

              >>> print(str2)

              W3Cschool

              %格式字符串请看下一节内容。

              Python 字符串格式化

              Python 支持格式化字符串的输出 。尽管这样可能会用到非常复杂的表达式,但最基本的用法是将一个值插入到一个有字符串格式符 ​%s​ 的字符串中。

              在 Python 中,字符串的格式化使用与 C/C++中的printf函数有着一样的语法。

              例如

              #!/usr/bin/python3 name = "小明"age = 10print ("我叫 %s 今年 %d 岁!" % (name, age))

              以上实例输出结果:

              我叫 小明 今年 10 岁!

              python字符串格式化符号:

                  符   号描述
                    ​%c 格式化字符及其ASCII码
                   ​ %s 格式化字符串
                ​   %d 格式化整型
                    ​%u 格式化无符号整型
                   ​ %o 格式化无符号八进制数
                    ​%x 格式化无符号十六进制数
                    ​%X 格式化无符号十六进制数(大写)
                   ​ %f 格式化浮点数字,可指定小数点后的精度
                   ​ %e 用科学计数法格式化浮点数
                    ​%E 作用同​%e​,用科学计数法格式化浮点数
                    ​%g ​%f​和​%e​的简写
                    ​%G ​%f ​和​ %E​ 的简写
                    ​%p 用十六进制数格式化变量的地址

              格式化操作符辅助指令:

              符号功能
              *定义宽度或者小数点精度
              -用做左对齐
              +在正数前面显示加号( + )
              <sp>在正数前面显示空格
              #在八进制数前面显示零('0'),在十六进制前面显示'0x'或者'0X'(取决于用的是'x'还是'X')
              0显示的数字前面填充'0'而不是默认的空格
              %'%%'输出一个单一的'%'
              (var)映射变量(字典参数)
              m.n.m 是显示的最小总宽度,n 是小数点后的位数(如果可用的话)

              Python2.6 开始,新增了一种格式化字符串的函数 str.format(),它增强了字符串格式化的功能。

              Python三引号

              python三引号允许一个字符串跨多行,字符串中可以包含换行符、制表符以及其他特殊字符。实例如下

              #!/usr/bin/python3 para_str = """这是一个多行字符串的实例多行字符串可以使用制表符TAB ( 	 )。也可以使用换行符 [ 
               ]。"""print (para_str)

              以上实例执行结果为:

              这是一个多行字符串的实例多行字符串可以使用制表符TAB (    )。也可以使用换行符 [  ]。

              三引号让程序员从引号和特殊字符串的泥潭里面解脱出来,自始至终保持一小块字符串的格式是所谓的WYSIWYG(所见即所得)格式的。

              一个典型的用例是,当你需要一块HTML或者SQL时,这时用字符串组合,特殊字符串转义将会非常的繁琐。

              errHTML = '''<HTML><HEAD><TITLE>Friends CGI Demo</TITLE></HEAD><BODY><H3>ERROR</H3><B>%s</B><P><FORM><INPUT TYPE=button VALUE=BackONCLICK="window.history.back()"></FORM></BODY></HTML>'''cursor.execute('''CREATE TABLE users (  login VARCHAR(8), uid INTEGER,prid INTEGER)''')

              还记得我们在注释相关章节中介绍的多行注释嘛?三引号的另一种用途就是用来做为多行注释使用。

              f-string

              f-string 是 python3.6 之后版本添加的,称之为字面量格式化字符串,是新的格式化字符串的语法。

              之前我们习惯用百分号 (%):

              name = 'W3Cschool'print('Hello %s' % name)

              运行结果:

              Hello W3Cschool

              f-string 格式化字符串以 f 开头,后面跟着字符串,字符串中的表达式用大括号 {} 包起来,它会将变量或表达式计算后的值替换进去,实例如下:

              name = 'W3Cschool'print(f'Hello {name}')  # 替换变量print(f'{1+2}')         # 使用表达式w = {'name': 'W3Cschool', 'url': 'www.51coolma.cn'}print(f'{w["name"]}: {w["url"]}')

              运行结果:

              Hello W3Cschool3W3Cschool: www.51coolma.cn

              用了这种方式明显更简单了,不用再去判断使用 %s,还是 %d。

              在 Python 3.8 的版本中可以使用 = 符号来拼接运算表达式与结果:

              x = 1print(f'{x+1}')   # Python 3.6x = 1print(f'{x+1=}')   # Python 3.8

              运行结果(由于在线idepython版本不支持3.8,所以不提供在线运行案例):

              2x+1=2

              Unicode 字符串

              在Python2中,普通字符串是以8位ASCII码进行存储的,而Unicode字符串则存储为16位unicode字符串,这样能够表示更多的字符集。使用的语法是在字符串前面加上前缀 u。

              在Python3中,所有的字符串都是Unicode字符串。

              Python 的字符串内建函数

              Python 的字符串常用内建函数如下:

              序号方法及描述
              1

              capitalize()
              将字符串的第一个字符转换为大写

              2

              center(width, fillchar)

              返回一个指定的宽度 width 居中的字符串,fillchar 为填充的字符,默认为空格。
              3

              count(str, beg= 0,end=len(string))

              返回 str 在 string 里面出现的次数,如果指定 beg 或者 end,则返回指定范围内 str 出现的次数
              4

              bytes.decode(encoding="utf-8", errors="strict")

              Python3 中没有 decode 方法,但我们可以使用 bytes 对象的 decode() 方法来解码给定的 bytes 对象,这个 bytes 对象可以由 str.encode() 来编码返回。
              5

              encode(encoding='UTF-8',errors='strict')

              以 encoding 指定的编码格式编码字符串,如果出错默认报​ValueError​异常,除非 errors 指定的是'ignore'或者'replace'
              6

              endswith(suffix, beg=0, end=len(string))
              检查字符串是否以指定的字符串结束,如果指定了beg 或 end 则检查指定的范围内是否以指定的字符串结束,如果是,返回 True,否则返回 False.

              7

              expandtabs(tabsize=8)

              把字符串 string 中的 tab 符号转为空格,tab 符号默认的空格数是 8 。
              8

              find(str, beg=0, end=len(string))

              检测 str 是否包含在字符串中,如果指定范围 beg 和 end ,则检查是否包含在指定范围内,如果包含,返回开始的索引值,否则返回-1
              9

              index(str, beg=0, end=len(string))

              跟find()方法一样,只不过如果str不在字符串中会报一个异常。
              10

              isalnum()

              如果字符串至少有一个字符并且所有字符都是字母或数字则返回 True,否则返回 False
              11

              isalpha()

              如果字符串至少有一个字符并且所有字符都是字母或中文字则返回 True, 否则返回 False
              12

              isdigit()

              如果字符串只包含数字则返回 True 否则返回 False..
              13

              islower()

              如果字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是小写,则返回 True,否则返回 False
              14

              isnumeric()

              如果字符串中只包含数字字符,则返回 True,否则返回 False
              15

              isspace()

              如果字符串中只包含空白,则返回 True,否则返回 False.
              16

              istitle()

              如果字符串是标题化的(见 title())则返回 True,否则返回 False
              17

              isupper()

              如果字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是大写,则返回 True,否则返回 False
              18

              join(seq)

              以指定字符串作为分隔符,将 seq 中所有的元素(的字符串表示)合并为一个新的字符串
              19

              len(string)

              返回字符串长度
              20

              ljust(width[, fillchar])

              返回一个原字符串左对齐,并使用 fillchar 填充至长度 width 的新字符串,fillchar 默认为空格。
              21

              lower()

              转换字符串中所有大写字符为小写.
              22

              lstrip()

              截掉字符串左边的空格或指定字符。
              23

              maketrans()

              创建字符映射的转换表,对于接受两个参数的最简单的调用方式,第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串表示转换的目标。
              24

              max(str)

              返回字符串 str 中最大的字母。
              25

              min(str)

              返回字符串 str 中最小的字母。
              26

              replace(old, new [, max])

              把 将字符串中的 old 替换成 new,如果 max 指定,则替换不超过 max 次。
              27

              rfind(str, beg=0,end=len(string))

              类似于 find()函数,不过是从右边开始查找.
              28

              rindex( str, beg=0, end=len(string))

              类似于 index(),不过是从右边开始.
              29

              rjust(width,[, fillchar])

              返回一个原字符串右对齐,并使用fillchar(默认空格)填充至长度 width 的新字符串
              30

              rstrip()

              删除字符串末尾的空格或指定字符。
              31

              split(str="", num=string.count(str))

              以 str 为分隔符截取字符串,如果 num 有指定值,则仅截取 num+1 个子字符串
              32

              splitlines([keepends])

              按照行(' ', ' ', ')分隔,返回一个包含各行作为元素的列表,如果参数 keepends 为 False,不包含换行符,如果为 True,则保留换行符。
              33

              startswith(substr, beg=0,end=len(string))

              检查字符串是否是以指定子字符串 substr 开头,是则返回 True,否则返回 False。如果beg 和 end 指定值,则在指定范围内检查。
              34

              strip([chars])

              在字符串上执行 lstrip()和 rstrip()
              35

              swapcase()

              将字符串中大写转换为小写,小写转换为大写
              36

              title()

              返回"标题化"的字符串,就是说所有单词都是以大写开始,其余字母均为小写(见 istitle())
              37

              translate(table, deletechars="")

              根据 str 给出的表(包含 256 个字符)转换 string 的字符, 要过滤掉的字符放到 deletechars 参数中
              38

              upper()

              转换字符串中的小写字母为大写
              39

              zfill (width)

              返回长度为 width 的字符串,原字符串右对齐,前面填充0
              40

              isdecimal()

              检查字符串是否只包含十进制字符,如果是返回 true,否则返回 false。




              字符串(string,简写为str)是 Python 中最常用的数据类型之一。我们可以使用引号( ' 或 " )来创建字符串。

              创建字符串很简单,只要为变量分配一个值即可。例如:

              var1 = 'Hello World!' var2 = "W3Cschool"

              Python 访问字符串中的值

              Python 不支持单字符类型,单字符在 Python 中也是作为一个字符串使用。

              Python 访问子字符串,可以使用方括号 ​[]​来截取字符串(这种方式也被称为切片),字符串的截取的语法格式如下:

              变量[头下标:尾下标]

              python截取的特点是取头下标的值到尾下标的值(尾下标的值不取)

              索引值以 0 为开始值,-1 为从末尾的开始位置。

              从后面索引   -9 -8 -7 -6 -5-4-3-2-1 
              从前面索引 012345678 
                W  3Cschool
              从前面截取 :  12345678: 
               从后面截取 :
              -8-7-6-5-4-3-2-1: 

              以下代码都是取字符C:

              str="W3cschool"print(str[2:3]) #使用截取方式,用正序进行截取print(str[2:-6])#使用截取方式,正序和倒序混合使用print(str[-7:-6])#使用截取方式,使用倒序进行截取print(str[-7])#使用负索引获取单个字符Cprint(str[2])#使用正索引获取单个字符C

              切片的更多案例:

              str="W3cschool"#取W3Cprint(str[:3]) print(str[:-6])#取schprint(str[3:6])print(str[-6:-3])#只有头下标/尾下标的情况print(str[:3])#只有尾下标的情况,默认头下标为0(正序的0,也就是字符串开始的地方)#也就是从字符串开头截取到3的位置(也就是W3C)print(str[3:])#只有头下标的情况,默认尾下标为0(逆序的0,也就是字符串结束的地方)#也就是从3的位置截取到字符串结尾(也就是school)#更多应用str2 ="https://www.51coolma.cn/"#截取协议名称print(str2[:5]) #也就是截取前五位#截取域名print(str2[8:-1]) #也就是截取第八位到倒数第一位

              Python转义字符

              有一些字符因为在python中已经被定义为一些操作(比如单引号和双引号被用来引用字符串),而这些符号我们可能在字符串中需要使用到。为了能够使用这些特殊字符,可以用反斜杠  转义字符(同样地,反斜杠也可以用来转义反斜杠)。如下表:

              转义字符描述实例
              (在行尾时)续行符
              >>> print("line1 ... line2 ... line3")line1 line2 line3>>> 
              反斜杠符号
              >>> print("")
              '单引号
              >>> print(''')'
              "双引号
              >>> print(""")"
              a响铃
              >>> print("a")
              执行后电脑有响声。
              退格(Backspace)
              >>> print("Hello  World!")Hello World!
              00
              >>> print("00")>>> 
              换行
              >>> print("
              ")>>>
              v纵向制表符
              >>> print("Hello v World!")Hello        World!>>>
              横向制表符
              >>> print("Hello 	 World!")Hello      World!>>>
              回车,将   后面的内容移到字符串开头,并逐一替换开头部分的字符,直至将   后面的内容完全替换完成。
              >>> print("Hello
              World!")World!>>> print('google runoob taobao
              123456')123456 runoob taobao
              f换页
              >>> print("Hello f World!")Hello        World!>>> 
              yyy八进制数,y 代表 0~7 的字符,例如:12 代表换行。
              >>> print("1101451541541574012715716215414441")Hello World!
              xyy十六进制数,以 x 开头,y 代表的字符,例如:x0a 代表换行
              >>> print("x48x65x6cx6cx6fx20x57x6fx72x6cx64x21")Hello World!
              other其它的字符以普通格式输出 

              Python字符串运算符

              下表实例变量 a 值为字符串 "Hello",b 变量值为 "W3Cschool":

              操作符描述实例
              +字符串连接a + b 输出结果: HelloW3Cschool
              >>> a ="hello">>> b = "W3Cschool">>> a+b'helloW3Cschool'
              *重复输出字符串a*2 输出结果:HelloHello
              >>> a ="hello">>> b = "W3Cschool">>> a*2'hellohello'
              []通过索引获取字符串中字符a[1] 输出结果 e
              >>> a ="hello">>> b = "W3Cschool">>> a[1]'e'
              [ : ]截取字符串中的一部分(切片),遵循左闭右开原则,str[0:2] 是不包含第 3 个字符的(详见上上节内容)。a[1:4] 输出结果 ell
              >>> a ="hello">>> b = "W3Cschool">>> a[1:4]'ell'
              in成员运算符 - 如果字符串中包含给定的字符返回 True'H' in a 输出结果 ​True
              >>> a ="hello">>> b = "W3Cschool">>> 'h' in aTrue
              not in成员运算符 - 如果字符串中不包含给定的字符返回 True'M' not in a 输出结果 ​True
              >>> a ="hello">>> b = "W3Cschool">>> 'M' not in aTrue
              r/R原始字符串 - 原始字符串:所有的字符串都是直接按照字面的意思来使用,没有转义特殊或不能打印的字符。 原始字符串除在字符串的第一个引号前加上字母 r(不区分大小写)以外,与普通字符串有着几乎完全相同的语法。

              >>> str="W3Cschool "

              >>> str2=r"W3Cschool "

              >>> print(str)

              W3Cschool

              >>> print(str2)

              W3Cschool

              %格式字符串请看下一节内容。

              Python 字符串格式化

              Python 支持格式化字符串的输出 。尽管这样可能会用到非常复杂的表达式,但最基本的用法是将一个值插入到一个有字符串格式符 ​%s​ 的字符串中。

              在 Python 中,字符串的格式化使用与 C/C++中的printf函数有着一样的语法。

              例如

              #!/usr/bin/python3 name = "小明"age = 10print ("我叫 %s 今年 %d 岁!" % (name, age))

              以上实例输出结果:

              我叫 小明 今年 10 岁!

              python字符串格式化符号:

                  符   号描述
                    ​%c 格式化字符及其ASCII码
                   ​ %s 格式化字符串
                ​   %d 格式化整型
                    ​%u 格式化无符号整型
                   ​ %o 格式化无符号八进制数
                    ​%x 格式化无符号十六进制数
                    ​%X 格式化无符号十六进制数(大写)
                   ​ %f 格式化浮点数字,可指定小数点后的精度
                   ​ %e 用科学计数法格式化浮点数
                    ​%E 作用同​%e​,用科学计数法格式化浮点数
                    ​%g ​%f​和​%e​的简写
                    ​%G ​%f ​和​ %E​ 的简写
                    ​%p 用十六进制数格式化变量的地址

              格式化操作符辅助指令:

              符号功能
              *定义宽度或者小数点精度
              -用做左对齐
              +在正数前面显示加号( + )
              <sp>在正数前面显示空格
              #在八进制数前面显示零('0'),在十六进制前面显示'0x'或者'0X'(取决于用的是'x'还是'X')
              0显示的数字前面填充'0'而不是默认的空格
              %'%%'输出一个单一的'%'
              (var)映射变量(字典参数)
              m.n.m 是显示的最小总宽度,n 是小数点后的位数(如果可用的话)

              Python2.6 开始,新增了一种格式化字符串的函数 str.format(),它增强了字符串格式化的功能。

              Python三引号

              python三引号允许一个字符串跨多行,字符串中可以包含换行符、制表符以及其他特殊字符。实例如下

              #!/usr/bin/python3 para_str = """这是一个多行字符串的实例多行字符串可以使用制表符TAB ( 	 )。也可以使用换行符 [ 
               ]。"""print (para_str)

              以上实例执行结果为:

              这是一个多行字符串的实例多行字符串可以使用制表符TAB (    )。也可以使用换行符 [  ]。

              三引号让程序员从引号和特殊字符串的泥潭里面解脱出来,自始至终保持一小块字符串的格式是所谓的WYSIWYG(所见即所得)格式的。

              一个典型的用例是,当你需要一块HTML或者SQL时,这时用字符串组合,特殊字符串转义将会非常的繁琐。

              errHTML = '''<HTML><HEAD><TITLE>Friends CGI Demo</TITLE></HEAD><BODY><H3>ERROR</H3><B>%s</B><P><FORM><INPUT TYPE=button VALUE=BackONCLICK="window.history.back()"></FORM></BODY></HTML>'''cursor.execute('''CREATE TABLE users (  login VARCHAR(8), uid INTEGER,prid INTEGER)''')

              还记得我们在注释相关章节中介绍的多行注释嘛?三引号的另一种用途就是用来做为多行注释使用。

              f-string

              f-string 是 python3.6 之后版本添加的,称之为字面量格式化字符串,是新的格式化字符串的语法。

              之前我们习惯用百分号 (%):

              name = 'W3Cschool'print('Hello %s' % name)

              运行结果:

              Hello W3Cschool

              f-string 格式化字符串以 f 开头,后面跟着字符串,字符串中的表达式用大括号 {} 包起来,它会将变量或表达式计算后的值替换进去,实例如下:

              name = 'W3Cschool'print(f'Hello {name}')  # 替换变量print(f'{1+2}')         # 使用表达式w = {'name': 'W3Cschool', 'url': 'www.51coolma.cn'}print(f'{w["name"]}: {w["url"]}')

              运行结果:

              Hello W3Cschool3W3Cschool: www.51coolma.cn

              用了这种方式明显更简单了,不用再去判断使用 %s,还是 %d。

              在 Python 3.8 的版本中可以使用 = 符号来拼接运算表达式与结果:

              x = 1print(f'{x+1}')   # Python 3.6x = 1print(f'{x+1=}')   # Python 3.8

              运行结果(由于在线idepython版本不支持3.8,所以不提供在线运行案例):

              2x+1=2

              Unicode 字符串

              在Python2中,普通字符串是以8位ASCII码进行存储的,而Unicode字符串则存储为16位unicode字符串,这样能够表示更多的字符集。使用的语法是在字符串前面加上前缀 u。

              在Python3中,所有的字符串都是Unicode字符串。

              Python 的字符串内建函数

              Python 的字符串常用内建函数如下:

              序号方法及描述
              1

              capitalize()
              将字符串的第一个字符转换为大写

              2

              center(width, fillchar)

              返回一个指定的宽度 width 居中的字符串,fillchar 为填充的字符,默认为空格。
              3

              count(str, beg= 0,end=len(string))

              返回 str 在 string 里面出现的次数,如果指定 beg 或者 end,则返回指定范围内 str 出现的次数
              4

              bytes.decode(encoding="utf-8", errors="strict")

              Python3 中没有 decode 方法,但我们可以使用 bytes 对象的 decode() 方法来解码给定的 bytes 对象,这个 bytes 对象可以由 str.encode() 来编码返回。
              5

              encode(encoding='UTF-8',errors='strict')

              以 encoding 指定的编码格式编码字符串,如果出错默认报​ValueError​异常,除非 errors 指定的是'ignore'或者'replace'
              6

              endswith(suffix, beg=0, end=len(string))
              检查字符串是否以指定的字符串结束,如果指定了beg 或 end 则检查指定的范围内是否以指定的字符串结束,如果是,返回 True,否则返回 False.

              7

              expandtabs(tabsize=8)

              把字符串 string 中的 tab 符号转为空格,tab 符号默认的空格数是 8 。
              8

              find(str, beg=0, end=len(string))

              检测 str 是否包含在字符串中,如果指定范围 beg 和 end ,则检查是否包含在指定范围内,如果包含,返回开始的索引值,否则返回-1
              9

              index(str, beg=0, end=len(string))

              跟find()方法一样,只不过如果str不在字符串中会报一个异常。
              10

              isalnum()

              如果字符串至少有一个字符并且所有字符都是字母或数字则返回 True,否则返回 False
              11

              isalpha()

              如果字符串至少有一个字符并且所有字符都是字母或中文字则返回 True, 否则返回 False
              12

              isdigit()

              如果字符串只包含数字则返回 True 否则返回 False..
              13

              islower()

              如果字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是小写,则返回 True,否则返回 False
              14

              isnumeric()

              如果字符串中只包含数字字符,则返回 True,否则返回 False
              15

              isspace()

              如果字符串中只包含空白,则返回 True,否则返回 False.
              16

              istitle()

              如果字符串是标题化的(见 title())则返回 True,否则返回 False
              17

              isupper()

              如果字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是大写,则返回 True,否则返回 False
              18

              join(seq)

              以指定字符串作为分隔符,将 seq 中所有的元素(的字符串表示)合并为一个新的字符串
              19

              len(string)

              返回字符串长度
              20

              ljust(width[, fillchar])

              返回一个原字符串左对齐,并使用 fillchar 填充至长度 width 的新字符串,fillchar 默认为空格。
              21

              lower()

              转换字符串中所有大写字符为小写.
              22

              lstrip()

              截掉字符串左边的空格或指定字符。
              23

              maketrans()

              创建字符映射的转换表,对于接受两个参数的最简单的调用方式,第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串表示转换的目标。
              24

              max(str)

              返回字符串 str 中最大的字母。
              25

              min(str)

              返回字符串 str 中最小的字母。
              26

              replace(old, new [, max])

              把 将字符串中的 old 替换成 new,如果 max 指定,则替换不超过 max 次。
              27

              rfind(str, beg=0,end=len(string))

              类似于 find()函数,不过是从右边开始查找.
              28

              rindex( str, beg=0, end=len(string))

              类似于 index(),不过是从右边开始.
              29

              rjust(width,[, fillchar])

              返回一个原字符串右对齐,并使用fillchar(默认空格)填充至长度 width 的新字符串
              30

              rstrip()

              删除字符串末尾的空格或指定字符。
              31

              split(str="", num=string.count(str))

              以 str 为分隔符截取字符串,如果 num 有指定值,则仅截取 num+1 个子字符串
              32

              splitlines([keepends])

              按照行(' ', ' ', ')分隔,返回一个包含各行作为元素的列表,如果参数 keepends 为 False,不包含换行符,如果为 True,则保留换行符。
              33

              startswith(substr, beg=0,end=len(string))

              检查字符串是否是以指定子字符串 substr 开头,是则返回 True,否则返回 False。如果beg 和 end 指定值,则在指定范围内检查。
              34

              strip([chars])

              在字符串上执行 lstrip()和 rstrip()
              35

              swapcase()

              将字符串中大写转换为小写,小写转换为大写
              36

              title()

              返回"标题化"的字符串,就是说所有单词都是以大写开始,其余字母均为小写(见 istitle())
              37

              translate(table, deletechars="")

              根据 str 给出的表(包含 256 个字符)转换 string 的字符, 要过滤掉的字符放到 deletechars 参数中
              38

              upper()

              转换字符串中的小写字母为大写
              39

              zfill (width)

              返回长度为 width 的字符串,原字符串右对齐,前面填充0
              40

              isdecimal()

              检查字符串是否只包含十进制字符,如果是返回 true,否则返回 false。




              什么是 CGI

              CGI 目前由 NCSA 维护,NCSA 定义 CGI 如下:

              CGI(Common Gateway Interface),通用网关接口,它是一段程序,运行在服务器上如:HTTP服务器,提供同客户端 HTML 页面的接口。


              网页浏览

              为了更好的了解 CGI 是如何工作的,我们可以从在网页上点击一个链接或 URL 的流程:

              • 1、使用你的浏览器访问 URL 并连接到 HTTP web 服务器。
              • 2、Web 服务器接收到请求信息后会解析 URL,并查找访问的文件在服务器上是否存在,如果存在返回文件的内容,否则返回错误信息。
              • 3、浏览器从服务器上接收信息,并显示接收的文件或者错误信息。

              CGI 程序可以是 Python 脚本,PERL 脚本,SHELL 脚本,C 或者 C++ 程序等。


              CGI 架构图

              cgiarch


              Web 服务器支持及配置

              在你进行 CGI 编程前,确保您的 Web 服务器支持 CGI 及已经配置了 CGI 的处理程序。

              Apache 支持 CGI 配置(这里使用PHPstudy集成的Apache):

              打开Apache的配置文件​httpd-conf​,在文件中找到如下内容:

              首先找到ScriptAlias(图片内容为已经修改过的值,默认值应该有所不同而且是被注释掉的)


              修改为项目地址​ ScriptAlias /cgi-bin/ "F:/phpstudy/phpstudy_pro/WWW/webpy"​ (之前的项目都放在​F:/phpstudy/phpstudy_pro/WWW/​下,这个文件夹是PHPstudy的apache默认项目文件夹,将路径改为这样可以方便localhost访问)。

              然后找到Directory,将其修改为

              <Directory "F:/phpstudy/phpstudy_pro/WWW/webpy">

                  AllowOverride None

                  Options +ExecCGI

                  Order allow,deny

                  Allow from all

               </Directory>

              注意:这里的路径和上面设置的路径是一样的。

              接着找到AddHandler


              添加​.py​。使apache识别.py文件为cgi程序(图中已添加)。

              接下来我们就可以在webpy文件夹下写pythonCGI程序了。


              第一个CGI程序

              我们使用 Python 创建第一个 CGI 程序,文件名为 hello.py,文件位于 /var/www/cgi-bin目录中,内容如下:

              #!/usr/bin/python3

              # 请注意第一行代码,在linux中需要在py文件中正确指定python解释器的路径才能运行# 在Windows中使用Python CGI文件也需要正确指定python解释器的路径才能运行

              #coding=utf-8

              print("Content-type:text/html") # 指定返回的类型,没有这行代码会报错

              print()              # 空行,告诉服务器结束头部

              # 以下是要返回的HTML正文print ('<html>')

              print ('<head>')

              print ('<title>Hello Word - 我的第一个 CGI 程序!</title>')

              print ('</head>')

              print ('<body>')

              print ('<h2>Hello Word! 我的第一CGI程序</h2>')

              print ('</body>')

              print ('</html>')

              文件保存后修改 hello.py,修改文件权限为 755(linux和macos需要在webpy文件夹下使用下面的命令来修改文件读写权限,在Windows环境下需要修改文件的读写权限):

              chmod 755 hello.py 

              以上程序在浏览器访问显示结果如下:


              这个的 hello.py 脚本是一个简单的 Python 脚本,脚本第一行的输出内容"Content-type:text/html"发送到浏览器并告知浏览器显示的内容类型为"text/html"。

              用 print 输出一个空行用于告诉服务器结束头部信息。

              注:如果此处出现乱码,可以在打印html的时候打印​​,在下文部分代码中有所体现(注意,这里不使用UTF-8的原因是小编在这里使用utf-8出现乱码,这是因为小编的系统是Windows系统,系统默认字符集是GBK,所以会出现乱码)。

              另外:请注意第一行代码,在linux中需要在py文件中正确指定python解释器的路径才能运行 。在Windows中使用Python CGI文件也需要正确指定python解释器的路径才能运行


              HTTP头部

              hello.py 文件内容中的" Content-type:text/html"即为 HTTP 头部的一部分,它会发送给浏览器告诉浏览器文件的内容类型。

              HTTP 头部的格式如下:

              HTTP 字段名: 字段内容

              例如:

              Content-type: text/html

              以下表格介绍了 CGI 程序中 HTTP 头部经常使用的信息:

              描述
              Content-type:请求的与实体对应的 MIME 信息。例如: Content-type:text/html
              Expires: Date响应过期的日期和时间
              Location: URL用来重定向接收方到非请求URL的位置来完成请求或标识新的资源
              Last-modified: Date请求资源的最后修改时间
              Content-length: N请求的内容长度
              Set-Cookie: String设置 Http Cookie

              CGI 环境变量

              所有的 CGI 程序都接收以下的环境变量,这些变量在 CGI 程序中发挥了重要的作用:

              变量名描述
              CONTENT_TYPE这个环境变量的值指示所传递来的信息的 MIME 类型。目前,环境变量 CONTENT_TYPE 一般都是:application/x-www-form-urlencoded,他表示数据来自于 HTML 表单。
              CONTENT_LENGTH如果服务器与 CGI 程序信息的传递方式是 POST,这个环境变量即使从标准输入 STDIN 中可以读到的有效数据的字节数。这个环境变量在读取所输入的数据时必须使用。
              HTTP_COOKIE客户机内的 COOKIE 内容。
              HTTP_USER_AGENT提供包含了版本数或其他专有数据的客户浏览器信息。
              PATH_INFO这个环境变量的值表示紧接在 CGI 程序名之后的其他路径信息。它常常作为 CGI 程序的参数出现。
              QUERY_STRING如果服务器与 CGI 程序信息的传递方式是 GET,这个环境变量的值即使所传递的信息。这个信息经跟在 CGI 程序名的后面,两者中间用一个问号'?'分隔。
              REMOTE_ADDR这个环境变量的值是发送请求的客户机的IP地址,例如上面的192.168.1.67。这个值总是存在的。而且它是 Web 客户机需要提供给Web服务器的唯一标识,可以在 CGI 程序中用它来区分不同的 Web 客户机。
              REMOTE_HOST这个环境变量的值包含发送 CGI 请求的客户机的主机名。如果不支持你想查询,则无需定义此环境变量。
              REQUEST_METHOD提供脚本被调用的方法。对于使用 HTTP/1.0 协议的脚本,仅 GET 和 POST 有意义。
              SCRIPT_FILENAMECGI 脚本的完整路径
              SCRIPT_NAMECGI 脚本的的名称
              SERVER_NAME这是你的 WEB 服务器的主机名、别名或IP地址。
              SERVER_SOFTWARE这个环境变量的值包含了调用 CGI 程序的 HTTP 服务器的名称和版本号。例如,上面的值为 Apache/2.2.14(Unix)

              以下是一个简单的 CGI 脚本输出 CGI 的环境变量:

              #!/usr/bin/python3#coding=utf-8import osprint ("Content-type: text/html")print ()print ("<b>环境变量</b><br>")print ("<ul>")for key in os.environ.keys():    print ("<li><span style='color:green'>%30s </span> : %s </li>" % (key,os.environ[key]))print ("</ul>")

              将以上点保存为 test.py ,并修改文件权限为 755,执行结果如下:



              GET 和 POST 方法

              浏览器客户端通过两种方法向服务器传递信息,这两种方法就是 GET 方法和 POST 方法。

              使用 GET 方法传输数据

              GET 方法发送编码后的用户信息到服务端,数据信息包含在请求页面的 URL 上,以"?"号分割, 如下所示:

              http://localhost/webpy/test.py?key1=value1&key2=value2

              有关 GET 请求的其他一些注释:

              • GET 请求可被缓存
              • GET 请求保留在浏览器历史记录中
              • GET 请求可被收藏为书签
              • GET 请求不应在处理敏感数据时使用
              • GET 请求有长度限制
              • GET 请求只应当用于取回数据

              简单的 url 实例:GET 方法

              以下是一个简单的 URL,使用 GET 方法向 test_get.py 程序发送两个参数:

              http://localhost/webpy/test_get.py?name=W3Cschool教程&url=http://www.51coolma.cn

              以下为 test_get.py 文件的代码:

              #!/usr/bin/python3#coding=utf-8# CGI处理模块import cgi, cgitb # 创建 FieldStorage 的实例化form = cgi.FieldStorage() # 获取数据site_name = form.getvalue('name')site_url  = form.getvalue('url')print ("Content-type:text/html")print ()print ("<html>")print ("<head>")print ("<title>W3Cschool教程 CGI 测试实例</title>")print ("</head>")print ("<body>")print ("<h2>%s官网:%s</h2>" % (site_name, site_url))print ("</body>")print ("</html>")

              文件保存后修改 hello_get.py,修改文件权限为 755:

              chmod 755 hello_get.py 

              浏览器请求输出结果:


              简单的表单实例:GET 方法

              以下是一个通过 HTML 的表单使用 GET 方法向服务器发送两个数据,提交的服务器脚本同样是 test_get.py 文件,hello_get.html 代码如下:

              <!DOCTYPE html><html><head><meta charset="utf-8"><title>W3Cschool教程(51coolma.cn)</title></head><body><form action="/webpy/test_get.py" method="get">站点名称: <input type="text" name="name">  <br />站点 URL: <input type="text" name="url" /><input type="submit" value="提交" /></form></body></html>

              默认情况下 webpy 目录只能存放脚本文件,我们将 hello_get.html 存储在 WWW 目录下,修改文件权限为 755:

              chmod 755 hello_get.html

              Gif 演示如下所示:



              使用 POST 方法传递数据

              使用 POST 方法向服务器传递数据是更安全可靠的,像一些敏感信息如用户密码等需要使用 POST 传输数据。

              以下同样是 test_get.py ,它也可以处理浏览器提交的 POST 表单数据:

              #!/usr/bin/python3#coding=utf-8# CGI处理模块import cgi, cgitb # 创建 FieldStorage 的实例化form = cgi.FieldStorage() # 获取数据site_name = form.getvalue('name')site_url  = form.getvalue('url')print ("Content-type:text/html")print ()print ("<html>")print ("<head>")print ("<meta charset="utf-8">")print ("<title>W3Cschool教程 CGI 测试实例</title>")print ("</head>")print ("<body>")print ("<h2>%s官网:%s</h2>" % (site_name, site_url))print ("</body>")print ("</html>")

              以下为表单通过 POST 方法(method="post")向服务器脚本 test_get.py 提交数据:

              <!DOCTYPE html><html><head><meta charset="utf-8"><title>W3Cschool教程(51coolma.cn)</title></head><body><form action="/webpy/hello_get.py" method="post">站点名称: <input type="text" name="name">  <br />站点 URL: <input type="text" name="url" /><input type="submit" value="提交" /></form></body></html></form>

              Gif 演示如下所示:


              通过 CGI 程序传递 checkbox 数据

              checkbox 用于提交一个或者多个选项数据,HTML 代码如下:

              <!DOCTYPE html><html><head><meta charset="utf-8"><title>W3Cschool教程(51coolma.cn)</title></head><body><form action="/webpy/checkbox.py" method="POST" target="_blank"><input type="checkbox" name="youj" value="on" /> W3Cschool教程<input type="checkbox" name="google" value="on" /> Google<input type="submit" value="选择站点" /></form></body></html>

              以下为 checkbox.py 文件的代码:

              #!/usr/bin/python3#coding=utf-8# 引入 CGI 处理模块 import cgi, cgitb # 创建 FieldStorage的实例 form = cgi.FieldStorage() # 接收字段数据if form.getvalue('google'):    google_flag = "是"else:    google_flag = "否"if form.getvalue('youj'):    youj_flag = "是"else:    youj_flag = "否"print ("Content-type:text/html")print ()print ("<html>")print ("<head>")print ("<title>W3Cschool教程 CGI 测试实例</title>")print ("</head>")print ("<body>")print ("<h2> W3Cschool教程是否选择了 : %s</h2>" % youj_flag)print ("<h2> Google 是否选择了 : %s</h2>" % google_flag)print ("</body>")print ("</html>")

              修改 checkbox.py 权限:

              chmod 755 checkbox.py

              浏览器访问 Gif 演示图:


              通过 CGI 程序传递 Radio 数据

              Radio 只向服务器传递一个数据,HTML 代码如下:

              <!DOCTYPE html><html><head><meta charset="utf-8"><title>W3Cschool教程(51coolma.cn)</title></head><body><form action="/webpy/radiobutton.py" method="post" target="_blank"><input type="radio" name="site" value="W3Cschool教程" /> W3Cschool教程<input type="radio" name="site" value="google" /> Google<input type="submit" value="提交" /></form></body></html>

              radiobutton.py 脚本代码如下:

              #!/usr/bin/python3#coding=utf-8# 引入 CGI 处理模块 import cgi, cgitb # 创建 FieldStorage的实例 form = cgi.FieldStorage() # 接收字段数据if form.getvalue('site'):    site = form.getvalue('site')else:    site = "提交数据为空"print ("Content-type:text/html")print ()print ("<html>")print ("<head>")print ("<title>W3Cschool教程 CGI 测试实例</title>")print ("</head>")print ("<body>")print ("<h2> 选中的网站是 %s</h2>" % site)print ("</body>")print ("</html>")

              修改 radiobutton.py 权限:

              chmod 755 radiobutton.py

              浏览器访问 Gif 演示图:


              通过 CGI 程序传递 Textarea 数据

              Textarea 向服务器传递多行数据,HTML 代码如下:

              <!DOCTYPE html><html><head><meta charset="utf-8"><title>W3Cschool教程(51coolma.cn)</title></head><body><form action="/webpy/textarea.py" method="post" target="_blank"><textarea name="textcontent" cols="40" rows="4">在这里输入内容...</textarea><input type="submit" value="提交" /></form></body></html>

              textarea.py 脚本代码如下:

              #!/usr/bin/python3#coding=utf-8# 引入 CGI 处理模块 import cgi, cgitb # 创建 FieldStorage的实例 form = cgi.FieldStorage() # 接收字段数据if form.getvalue('textcontent'):    text_content = form.getvalue('textcontent')else:    text_content = "没有内容"print ("Content-type:text/html")print ()print ("<html>")print ("<head>")print ("<title>W3Cschool教程 CGI 测试实例</title>")print ("</head>")print ("<body>")print ("<h2> 输入的内容是:%s</h2>" % text_content)print ("</body>")print ("</html>")

              修改 textarea.py 权限:

              chmod 755 textarea.py

              浏览器访问 Gif 演示图:


              通过 CGI 程序传递下拉数据。

              HTML 下拉框代码如下:

              <!DOCTYPE html><html><head><meta charset="utf-8"><title>W3Cschool教程(51coolma.cn)</title></head><body><form action="/webpy/dropdown.py" method="post" target="_blank"><select name="dropdown"><option value="W3Cschool教程" selected>W3Cschool教程</option>
              <option value="google">Google</option></select><input type="submit" value="提交"/></form></body></html>

              dropdown.py 脚本代码如下所示:

              #!/usr/bin/python3
              #coding=utf-8# 引入 CGI 处理模块 import cgi, cgitb # 创建 FieldStorage的实例 form = cgi.FieldStorage() # 接收字段数据if form.getvalue('dropdown'): dropdown_value = form.getvalue('dropdown')else: dropdown_value = "没有内容"print ("Content-type:text/html")print ()print ("<html>")print ("<head>")print ("<meta charset="utf-8">")print ("<title>W3Cschool教程 CGI 测试实例</title>")print ("</head>")print ("<body>")print ("<h2> 选中的选项是:%s</h2>" % dropdown_value)print ("</body>")print ("</html>")

              修改 dropdown.py 权限:

              chmod 755 dropdown.py

              浏览器访问 Gif 演示图:



              CGI 中使用 Cookie

              在 http 协议一个很大的缺点就是不对用户身份的进行判断,这样给编程人员带来很大的不便,而 cookie 功能的出现弥补了这个不足。

              cookie 就是在客户访问脚本的同时,通过客户的浏览器,在客户硬盘上写入纪录数据 ,当下次客户访问脚本时取回数据信息,从而达到身份判别的功能,cookie 常用在身份校验中。

              cookie 的语法

              http cookie 的发送是通过 http 头部来实现的,他早于文件的传递,头部set-cookie 的语法如下:

              Set-cookie:name=name;expires=date;path=path;domain=domain;secure 
              • name=name: 需要设置cookie的值(name不能使用";"和","号),有多个name值时用 ";" 分隔,例如:name1=name1;name2=name2;name3=name3
              • expires=date: cookie的有效期限,格式: expires="Wdy,DD-Mon-YYYY HH:MM:SS"
              • path=path: 设置 cookie 支持的路径,如果path是一个路径,则 cookie 对这个目录下的所有文件及子目录生效,例如: path="/webpy/",如果path是一个文件,则cookie指对这个文件生效,例如:path="/webpy/cookie.py"。
              • domain=domain: 对 cookie 生效的域名,例如:domain="www.51coolma.cn"
              • secure: 如果给出此标志,表示cookie只能通过SSL协议的https服务器来传递。
              • cookie的接收是通过设置环境变量 HTTP_COOKIE 来实现的,CGI 程序可以通过检索该变量获取 cookie 信息。

              Cookie 设置

              Cookie 的设置非常简单,cookie 会在 http 头部单独发送。以下实例在 cookie 中设置了name 和 expires:

              #!/usr/bin/python3

              #coding=utf-8

              print ('Content-Type: text/html')

              print ('Set-Cookie: name="W3Cschool";expires=Thu 02 Dec 2021 18:30:00 GMT')//注意,这个cookie在这个时间前有效,之后使用cookie会过期

              print ()

              print ("""

              <html>

                <head>

                  <meta charset="gbk">

                  <title>W3Cschool教程(51coolma.cn)</title>

                </head>

                  <body>

                      <h1>Cookie set OK!</h1>

                  </body>

              </html>

              """)

              将以上代码保存到 cookie_set.py,并修改 cookie_set.py 权限:

              chmod 755 cookie_set.py

              以上实例使用了 Set-Cookie 头信息来设置 Cookie 信息,可选项中设置了 Cookie 的其他属性,如过期时间 Expires,域名 Domain,路径 Path。这些信息设置在 "Content-type:text/html"之前。

              注意:cookie不能存放中文,本文采用英文例子,如果要使用中文可以使用后端编码(可以采用utf-8等编码,python和JavaScript都有提供响应的编解码的功能),传到前端后再将其解码即可。


              检索Cookie信息

              Cookie 信息检索页非常简单,Cookie 信息存储在 CGI 的环境变量 HTTP_COOKIE 中,存储格式如下:

              key1=value1;key2=value2;key3=value3....

              以下是一个简单的 CGI 检索 cookie 信息的程序:

              #!/usr/bin/python3

              #coding=utf-8

              # 导入模块

              import os

              import http.cookies

              print ("Content-type: text/html")

              print ()

              print ("""

              <html>

              <head>

              <meta charset="gbk">

              <title>W3Cschool教程(51coolma.cn)</title>

              </head>

              <body>

              <h1>读取cookie信息</h1>

              """)

              if 'HTTP_COOKIE' in os.environ:

                  cookie_string=os.environ.get('HTTP_COOKIE')

                  c=http.cookies.SimpleCookie()

                  c.load(cookie_string)

                  try:

                      data=c['name'].value

                      print ("cookie data: "+data+"<br>")

                  except KeyError:

                      print ("cookie 没有设置或者已过去<br>")

              print ("""

              </body>

              </html>

              """)

              将以上代码保存到 cookie_get.py,并修改 cookie_get.py 权限:

              chmod 755 cookie_get.py

              以上 cookie 设置的Gif 如下所示:




              文件上传实例

              HTML 设置上传文件的表单需要设置 enctype 属性为 multipart/form-data,代码如下所示:

              <!DOCTYPE html><html><head><meta charset="utf-8"><title>W3Cschool教程(51coolma.cn)</title></head><body> <form enctype="multipart/form-data"                      action="/webpy/save_file.py" method="post">   <p>选中文件: <input type="file" name="filename" /></p>   <p><input type="submit" value="上传" /></p>   </form></body></html>

              save_file.py 脚本文件代码如下:

              #!/usr/bin/python3

              #coding=utf-8

              import cgi, os

              import cgitb

              cgitb.enable()

              form = cgi.FieldStorage()

              # 获取文件名

              fileitem = form['filename']

              # 检测文件是否上传

              if fileitem.filename:

                 # 设置文件路径 

                 fn = os.path.basename(fileitem.filename)

                 open(os.getcwd()+'/tmp/' + fn, 'wb').write(fileitem.file.read())

                 message = '文件 "' + fn + '" 上传成功'

                 

              else:

                 message = '文件没有上传'

              print ("Content-type: text/html")

              print () 

              print ("""

              <html>

              <head>

              <meta charset="gbk">

              <title>W3Cschool教程(51coolma.cn)</title>

              </head>

              <body>

                 <p>%s</p>

              </body>

              </html>

              """ % (message,))

              将以上代码保存到 save_file.py,并修改 save_file.py 权限:

              chmod 755 save_file.py

              以上文件上传代码 Gif 如下所示:



              如果你使用的系统是 Unix/Linux,你必须替换文件分隔符,在 window 下只需要使用open() 语句即可:

              fn = os.path.basename(fileitem.filename.replace("", "/" ))

              另外,请注意在webpy下创建一个tmp文件夹,不然上传的时候会报错



              文件下载对话框

              我们先在当前目录下创建 foo.txt 文件,用于程序的下载。

              文件下载通过设置 HTTP 头信息来实现,功能代码如下:

              #!/usr/bin/python3# HTTP 头部print ("Content-Disposition: attachment; filename="foo.txt"")print ()# 打开文件fo = open("foo.txt", "rb")str = fo.read();print (str)# 关闭文件fo.close()


              什么是 CGI

              CGI 目前由 NCSA 维护,NCSA 定义 CGI 如下:

              CGI(Common Gateway Interface),通用网关接口,它是一段程序,运行在服务器上如:HTTP服务器,提供同客户端 HTML 页面的接口。


              网页浏览

              为了更好的了解 CGI 是如何工作的,我们可以从在网页上点击一个链接或 URL 的流程:

              • 1、使用你的浏览器访问 URL 并连接到 HTTP web 服务器。
              • 2、Web 服务器接收到请求信息后会解析 URL,并查找访问的文件在服务器上是否存在,如果存在返回文件的内容,否则返回错误信息。
              • 3、浏览器从服务器上接收信息,并显示接收的文件或者错误信息。

              CGI 程序可以是 Python 脚本,PERL 脚本,SHELL 脚本,C 或者 C++ 程序等。


              CGI 架构图

              cgiarch


              Web 服务器支持及配置

              在你进行 CGI 编程前,确保您的 Web 服务器支持 CGI 及已经配置了 CGI 的处理程序。

              Apache 支持 CGI 配置(这里使用PHPstudy集成的Apache):

              打开Apache的配置文件​httpd-conf​,在文件中找到如下内容:

              首先找到ScriptAlias(图片内容为已经修改过的值,默认值应该有所不同而且是被注释掉的)


              修改为项目地址​ ScriptAlias /cgi-bin/ "F:/phpstudy/phpstudy_pro/WWW/webpy"​ (之前的项目都放在​F:/phpstudy/phpstudy_pro/WWW/​下,这个文件夹是PHPstudy的apache默认项目文件夹,将路径改为这样可以方便localhost访问)。

              然后找到Directory,将其修改为

              <Directory "F:/phpstudy/phpstudy_pro/WWW/webpy">

                  AllowOverride None

                  Options +ExecCGI

                  Order allow,deny

                  Allow from all

               </Directory>

              注意:这里的路径和上面设置的路径是一样的。

              接着找到AddHandler


              添加​.py​。使apache识别.py文件为cgi程序(图中已添加)。

              接下来我们就可以在webpy文件夹下写pythonCGI程序了。


              第一个CGI程序

              我们使用 Python 创建第一个 CGI 程序,文件名为 hello.py,文件位于 /var/www/cgi-bin目录中,内容如下:

              #!/usr/bin/python3

              # 请注意第一行代码,在linux中需要在py文件中正确指定python解释器的路径才能运行# 在Windows中使用Python CGI文件也需要正确指定python解释器的路径才能运行

              #coding=utf-8

              print("Content-type:text/html") # 指定返回的类型,没有这行代码会报错

              print()              # 空行,告诉服务器结束头部

              # 以下是要返回的HTML正文print ('<html>')

              print ('<head>')

              print ('<title>Hello Word - 我的第一个 CGI 程序!</title>')

              print ('</head>')

              print ('<body>')

              print ('<h2>Hello Word! 我的第一CGI程序</h2>')

              print ('</body>')

              print ('</html>')

              文件保存后修改 hello.py,修改文件权限为 755(linux和macos需要在webpy文件夹下使用下面的命令来修改文件读写权限,在Windows环境下需要修改文件的读写权限):

              chmod 755 hello.py 

              以上程序在浏览器访问显示结果如下:


              这个的 hello.py 脚本是一个简单的 Python 脚本,脚本第一行的输出内容"Content-type:text/html"发送到浏览器并告知浏览器显示的内容类型为"text/html"。

              用 print 输出一个空行用于告诉服务器结束头部信息。

              注:如果此处出现乱码,可以在打印html的时候打印​​,在下文部分代码中有所体现(注意,这里不使用UTF-8的原因是小编在这里使用utf-8出现乱码,这是因为小编的系统是Windows系统,系统默认字符集是GBK,所以会出现乱码)。

              另外:请注意第一行代码,在linux中需要在py文件中正确指定python解释器的路径才能运行 。在Windows中使用Python CGI文件也需要正确指定python解释器的路径才能运行


              HTTP头部

              hello.py 文件内容中的" Content-type:text/html"即为 HTTP 头部的一部分,它会发送给浏览器告诉浏览器文件的内容类型。

              HTTP 头部的格式如下:

              HTTP 字段名: 字段内容

              例如:

              Content-type: text/html

              以下表格介绍了 CGI 程序中 HTTP 头部经常使用的信息:

              描述
              Content-type:请求的与实体对应的 MIME 信息。例如: Content-type:text/html
              Expires: Date响应过期的日期和时间
              Location: URL用来重定向接收方到非请求URL的位置来完成请求或标识新的资源
              Last-modified: Date请求资源的最后修改时间
              Content-length: N请求的内容长度
              Set-Cookie: String设置 Http Cookie

              CGI 环境变量

              所有的 CGI 程序都接收以下的环境变量,这些变量在 CGI 程序中发挥了重要的作用:

              变量名描述
              CONTENT_TYPE这个环境变量的值指示所传递来的信息的 MIME 类型。目前,环境变量 CONTENT_TYPE 一般都是:application/x-www-form-urlencoded,他表示数据来自于 HTML 表单。
              CONTENT_LENGTH如果服务器与 CGI 程序信息的传递方式是 POST,这个环境变量即使从标准输入 STDIN 中可以读到的有效数据的字节数。这个环境变量在读取所输入的数据时必须使用。
              HTTP_COOKIE客户机内的 COOKIE 内容。
              HTTP_USER_AGENT提供包含了版本数或其他专有数据的客户浏览器信息。
              PATH_INFO这个环境变量的值表示紧接在 CGI 程序名之后的其他路径信息。它常常作为 CGI 程序的参数出现。
              QUERY_STRING如果服务器与 CGI 程序信息的传递方式是 GET,这个环境变量的值即使所传递的信息。这个信息经跟在 CGI 程序名的后面,两者中间用一个问号'?'分隔。
              REMOTE_ADDR这个环境变量的值是发送请求的客户机的IP地址,例如上面的192.168.1.67。这个值总是存在的。而且它是 Web 客户机需要提供给Web服务器的唯一标识,可以在 CGI 程序中用它来区分不同的 Web 客户机。
              REMOTE_HOST这个环境变量的值包含发送 CGI 请求的客户机的主机名。如果不支持你想查询,则无需定义此环境变量。
              REQUEST_METHOD提供脚本被调用的方法。对于使用 HTTP/1.0 协议的脚本,仅 GET 和 POST 有意义。
              SCRIPT_FILENAMECGI 脚本的完整路径
              SCRIPT_NAMECGI 脚本的的名称
              SERVER_NAME这是你的 WEB 服务器的主机名、别名或IP地址。
              SERVER_SOFTWARE这个环境变量的值包含了调用 CGI 程序的 HTTP 服务器的名称和版本号。例如,上面的值为 Apache/2.2.14(Unix)

              以下是一个简单的 CGI 脚本输出 CGI 的环境变量:

              #!/usr/bin/python3#coding=utf-8import osprint ("Content-type: text/html")print ()print ("<b>环境变量</b><br>")print ("<ul>")for key in os.environ.keys():    print ("<li><span style='color:green'>%30s </span> : %s </li>" % (key,os.environ[key]))print ("</ul>")

              将以上点保存为 test.py ,并修改文件权限为 755,执行结果如下:



              GET 和 POST 方法

              浏览器客户端通过两种方法向服务器传递信息,这两种方法就是 GET 方法和 POST 方法。

              使用 GET 方法传输数据

              GET 方法发送编码后的用户信息到服务端,数据信息包含在请求页面的 URL 上,以"?"号分割, 如下所示:

              http://localhost/webpy/test.py?key1=value1&key2=value2

              有关 GET 请求的其他一些注释:

              • GET 请求可被缓存
              • GET 请求保留在浏览器历史记录中
              • GET 请求可被收藏为书签
              • GET 请求不应在处理敏感数据时使用
              • GET 请求有长度限制
              • GET 请求只应当用于取回数据

              简单的 url 实例:GET 方法

              以下是一个简单的 URL,使用 GET 方法向 test_get.py 程序发送两个参数:

              http://localhost/webpy/test_get.py?name=W3Cschool教程&url=http://www.51coolma.cn

              以下为 test_get.py 文件的代码:

              #!/usr/bin/python3#coding=utf-8# CGI处理模块import cgi, cgitb # 创建 FieldStorage 的实例化form = cgi.FieldStorage() # 获取数据site_name = form.getvalue('name')site_url  = form.getvalue('url')print ("Content-type:text/html")print ()print ("<html>")print ("<head>")print ("<title>W3Cschool教程 CGI 测试实例</title>")print ("</head>")print ("<body>")print ("<h2>%s官网:%s</h2>" % (site_name, site_url))print ("</body>")print ("</html>")

              文件保存后修改 hello_get.py,修改文件权限为 755:

              chmod 755 hello_get.py 

              浏览器请求输出结果:


              简单的表单实例:GET 方法

              以下是一个通过 HTML 的表单使用 GET 方法向服务器发送两个数据,提交的服务器脚本同样是 test_get.py 文件,hello_get.html 代码如下:

              <!DOCTYPE html><html><head><meta charset="utf-8"><title>W3Cschool教程(51coolma.cn)</title></head><body><form action="/webpy/test_get.py" method="get">站点名称: <input type="text" name="name">  <br />站点 URL: <input type="text" name="url" /><input type="submit" value="提交" /></form></body></html>

              默认情况下 webpy 目录只能存放脚本文件,我们将 hello_get.html 存储在 WWW 目录下,修改文件权限为 755:

              chmod 755 hello_get.html

              Gif 演示如下所示:



              使用 POST 方法传递数据

              使用 POST 方法向服务器传递数据是更安全可靠的,像一些敏感信息如用户密码等需要使用 POST 传输数据。

              以下同样是 test_get.py ,它也可以处理浏览器提交的 POST 表单数据:

              #!/usr/bin/python3#coding=utf-8# CGI处理模块import cgi, cgitb # 创建 FieldStorage 的实例化form = cgi.FieldStorage() # 获取数据site_name = form.getvalue('name')site_url  = form.getvalue('url')print ("Content-type:text/html")print ()print ("<html>")print ("<head>")print ("<meta charset="utf-8">")print ("<title>W3Cschool教程 CGI 测试实例</title>")print ("</head>")print ("<body>")print ("<h2>%s官网:%s</h2>" % (site_name, site_url))print ("</body>")print ("</html>")

              以下为表单通过 POST 方法(method="post")向服务器脚本 test_get.py 提交数据:

              <!DOCTYPE html><html><head><meta charset="utf-8"><title>W3Cschool教程(51coolma.cn)</title></head><body><form action="/webpy/hello_get.py" method="post">站点名称: <input type="text" name="name">  <br />站点 URL: <input type="text" name="url" /><input type="submit" value="提交" /></form></body></html></form>

              Gif 演示如下所示:


              通过 CGI 程序传递 checkbox 数据

              checkbox 用于提交一个或者多个选项数据,HTML 代码如下:

              <!DOCTYPE html><html><head><meta charset="utf-8"><title>W3Cschool教程(51coolma.cn)</title></head><body><form action="/webpy/checkbox.py" method="POST" target="_blank"><input type="checkbox" name="youj" value="on" /> W3Cschool教程<input type="checkbox" name="google" value="on" /> Google<input type="submit" value="选择站点" /></form></body></html>

              以下为 checkbox.py 文件的代码:

              #!/usr/bin/python3#coding=utf-8# 引入 CGI 处理模块 import cgi, cgitb # 创建 FieldStorage的实例 form = cgi.FieldStorage() # 接收字段数据if form.getvalue('google'):    google_flag = "是"else:    google_flag = "否"if form.getvalue('youj'):    youj_flag = "是"else:    youj_flag = "否"print ("Content-type:text/html")print ()print ("<html>")print ("<head>")print ("<title>W3Cschool教程 CGI 测试实例</title>")print ("</head>")print ("<body>")print ("<h2> W3Cschool教程是否选择了 : %s</h2>" % youj_flag)print ("<h2> Google 是否选择了 : %s</h2>" % google_flag)print ("</body>")print ("</html>")

              修改 checkbox.py 权限:

              chmod 755 checkbox.py

              浏览器访问 Gif 演示图:


              通过 CGI 程序传递 Radio 数据

              Radio 只向服务器传递一个数据,HTML 代码如下:

              <!DOCTYPE html><html><head><meta charset="utf-8"><title>W3Cschool教程(51coolma.cn)</title></head><body><form action="/webpy/radiobutton.py" method="post" target="_blank"><input type="radio" name="site" value="W3Cschool教程" /> W3Cschool教程<input type="radio" name="site" value="google" /> Google<input type="submit" value="提交" /></form></body></html>

              radiobutton.py 脚本代码如下:

              #!/usr/bin/python3#coding=utf-8# 引入 CGI 处理模块 import cgi, cgitb # 创建 FieldStorage的实例 form = cgi.FieldStorage() # 接收字段数据if form.getvalue('site'):    site = form.getvalue('site')else:    site = "提交数据为空"print ("Content-type:text/html")print ()print ("<html>")print ("<head>")print ("<title>W3Cschool教程 CGI 测试实例</title>")print ("</head>")print ("<body>")print ("<h2> 选中的网站是 %s</h2>" % site)print ("</body>")print ("</html>")

              修改 radiobutton.py 权限:

              chmod 755 radiobutton.py

              浏览器访问 Gif 演示图:


              通过 CGI 程序传递 Textarea 数据

              Textarea 向服务器传递多行数据,HTML 代码如下:

              <!DOCTYPE html><html><head><meta charset="utf-8"><title>W3Cschool教程(51coolma.cn)</title></head><body><form action="/webpy/textarea.py" method="post" target="_blank"><textarea name="textcontent" cols="40" rows="4">在这里输入内容...</textarea><input type="submit" value="提交" /></form></body></html>

              textarea.py 脚本代码如下:

              #!/usr/bin/python3#coding=utf-8# 引入 CGI 处理模块 import cgi, cgitb # 创建 FieldStorage的实例 form = cgi.FieldStorage() # 接收字段数据if form.getvalue('textcontent'):    text_content = form.getvalue('textcontent')else:    text_content = "没有内容"print ("Content-type:text/html")print ()print ("<html>")print ("<head>")print ("<title>W3Cschool教程 CGI 测试实例</title>")print ("</head>")print ("<body>")print ("<h2> 输入的内容是:%s</h2>" % text_content)print ("</body>")print ("</html>")

              修改 textarea.py 权限:

              chmod 755 textarea.py

              浏览器访问 Gif 演示图:


              通过 CGI 程序传递下拉数据。

              HTML 下拉框代码如下:

              <!DOCTYPE html><html><head><meta charset="utf-8"><title>W3Cschool教程(51coolma.cn)</title></head><body><form action="/webpy/dropdown.py" method="post" target="_blank"><select name="dropdown"><option value="W3Cschool教程" selected>W3Cschool教程</option>
              <option value="google">Google</option></select><input type="submit" value="提交"/></form></body></html>

              dropdown.py 脚本代码如下所示:

              #!/usr/bin/python3
              #coding=utf-8# 引入 CGI 处理模块 import cgi, cgitb # 创建 FieldStorage的实例 form = cgi.FieldStorage() # 接收字段数据if form.getvalue('dropdown'): dropdown_value = form.getvalue('dropdown')else: dropdown_value = "没有内容"print ("Content-type:text/html")print ()print ("<html>")print ("<head>")print ("<meta charset="utf-8">")print ("<title>W3Cschool教程 CGI 测试实例</title>")print ("</head>")print ("<body>")print ("<h2> 选中的选项是:%s</h2>" % dropdown_value)print ("</body>")print ("</html>")

              修改 dropdown.py 权限:

              chmod 755 dropdown.py

              浏览器访问 Gif 演示图:



              CGI 中使用 Cookie

              在 http 协议一个很大的缺点就是不对用户身份的进行判断,这样给编程人员带来很大的不便,而 cookie 功能的出现弥补了这个不足。

              cookie 就是在客户访问脚本的同时,通过客户的浏览器,在客户硬盘上写入纪录数据 ,当下次客户访问脚本时取回数据信息,从而达到身份判别的功能,cookie 常用在身份校验中。

              cookie 的语法

              http cookie 的发送是通过 http 头部来实现的,他早于文件的传递,头部set-cookie 的语法如下:

              Set-cookie:name=name;expires=date;path=path;domain=domain;secure 
              • name=name: 需要设置cookie的值(name不能使用";"和","号),有多个name值时用 ";" 分隔,例如:name1=name1;name2=name2;name3=name3
              • expires=date: cookie的有效期限,格式: expires="Wdy,DD-Mon-YYYY HH:MM:SS"
              • path=path: 设置 cookie 支持的路径,如果path是一个路径,则 cookie 对这个目录下的所有文件及子目录生效,例如: path="/webpy/",如果path是一个文件,则cookie指对这个文件生效,例如:path="/webpy/cookie.py"。
              • domain=domain: 对 cookie 生效的域名,例如:domain="www.51coolma.cn"
              • secure: 如果给出此标志,表示cookie只能通过SSL协议的https服务器来传递。
              • cookie的接收是通过设置环境变量 HTTP_COOKIE 来实现的,CGI 程序可以通过检索该变量获取 cookie 信息。

              Cookie 设置

              Cookie 的设置非常简单,cookie 会在 http 头部单独发送。以下实例在 cookie 中设置了name 和 expires:

              #!/usr/bin/python3

              #coding=utf-8

              print ('Content-Type: text/html')

              print ('Set-Cookie: name="W3Cschool";expires=Thu 02 Dec 2021 18:30:00 GMT')//注意,这个cookie在这个时间前有效,之后使用cookie会过期

              print ()

              print ("""

              <html>

                <head>

                  <meta charset="gbk">

                  <title>W3Cschool教程(51coolma.cn)</title>

                </head>

                  <body>

                      <h1>Cookie set OK!</h1>

                  </body>

              </html>

              """)

              将以上代码保存到 cookie_set.py,并修改 cookie_set.py 权限:

              chmod 755 cookie_set.py

              以上实例使用了 Set-Cookie 头信息来设置 Cookie 信息,可选项中设置了 Cookie 的其他属性,如过期时间 Expires,域名 Domain,路径 Path。这些信息设置在 "Content-type:text/html"之前。

              注意:cookie不能存放中文,本文采用英文例子,如果要使用中文可以使用后端编码(可以采用utf-8等编码,python和JavaScript都有提供响应的编解码的功能),传到前端后再将其解码即可。


              检索Cookie信息

              Cookie 信息检索页非常简单,Cookie 信息存储在 CGI 的环境变量 HTTP_COOKIE 中,存储格式如下:

              key1=value1;key2=value2;key3=value3....

              以下是一个简单的 CGI 检索 cookie 信息的程序:

              #!/usr/bin/python3

              #coding=utf-8

              # 导入模块

              import os

              import http.cookies

              print ("Content-type: text/html")

              print ()

              print ("""

              <html>

              <head>

              <meta charset="gbk">

              <title>W3Cschool教程(51coolma.cn)</title>

              </head>

              <body>

              <h1>读取cookie信息</h1>

              """)

              if 'HTTP_COOKIE' in os.environ:

                  cookie_string=os.environ.get('HTTP_COOKIE')

                  c=http.cookies.SimpleCookie()

                  c.load(cookie_string)

                  try:

                      data=c['name'].value

                      print ("cookie data: "+data+"<br>")

                  except KeyError:

                      print ("cookie 没有设置或者已过去<br>")

              print ("""

              </body>

              </html>

              """)

              将以上代码保存到 cookie_get.py,并修改 cookie_get.py 权限:

              chmod 755 cookie_get.py

              以上 cookie 设置的Gif 如下所示:




              文件上传实例

              HTML 设置上传文件的表单需要设置 enctype 属性为 multipart/form-data,代码如下所示:

              <!DOCTYPE html><html><head><meta charset="utf-8"><title>W3Cschool教程(51coolma.cn)</title></head><body> <form enctype="multipart/form-data"                      action="/webpy/save_file.py" method="post">   <p>选中文件: <input type="file" name="filename" /></p>   <p><input type="submit" value="上传" /></p>   </form></body></html>

              save_file.py 脚本文件代码如下:

              #!/usr/bin/python3

              #coding=utf-8

              import cgi, os

              import cgitb

              cgitb.enable()

              form = cgi.FieldStorage()

              # 获取文件名

              fileitem = form['filename']

              # 检测文件是否上传

              if fileitem.filename:

                 # 设置文件路径 

                 fn = os.path.basename(fileitem.filename)

                 open(os.getcwd()+'/tmp/' + fn, 'wb').write(fileitem.file.read())

                 message = '文件 "' + fn + '" 上传成功'

                 

              else:

                 message = '文件没有上传'

              print ("Content-type: text/html")

              print () 

              print ("""

              <html>

              <head>

              <meta charset="gbk">

              <title>W3Cschool教程(51coolma.cn)</title>

              </head>

              <body>

                 <p>%s</p>

              </body>

              </html>

              """ % (message,))

              将以上代码保存到 save_file.py,并修改 save_file.py 权限:

              chmod 755 save_file.py

              以上文件上传代码 Gif 如下所示:



              如果你使用的系统是 Unix/Linux,你必须替换文件分隔符,在 window 下只需要使用open() 语句即可:

              fn = os.path.basename(fileitem.filename.replace("", "/" ))

              另外,请注意在webpy下创建一个tmp文件夹,不然上传的时候会报错



              文件下载对话框

              我们先在当前目录下创建 foo.txt 文件,用于程序的下载。

              文件下载通过设置 HTTP 头信息来实现,功能代码如下:

              #!/usr/bin/python3# HTTP 头部print ("Content-Disposition: attachment; filename="foo.txt"")print ()# 打开文件fo = open("foo.txt", "rb")str = fo.read();print (str)# 关闭文件fo.close()


              很多人抱怨pip安装库有些时候太慢了,那是pip源的问题。

              前面说过pip从PyPi中下载库文件,但由于PyPi服务器在国外,访问起来很慢。

              但国内提供了很多镜像源,用来替代PyPi,像清华源、豆瓣源、阿里云源等。

              这些镜像源备份了PyPi里的数据,由于服务器在国内,速度会快很多。

              但镜像源数据有滞后性,比如说清华源的pypi 镜像每 5 分钟同步一次。

              使用镜像源有两种方式,以清华源为例:

              (1) 临时使用

              pip install -i https://pypi.tuna.tsinghua.edu.cn/simple some-package matplotlib

              除了matplotlib是要安装的库名外,其他都是固定格式

              (2) 设为默认

              pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

              设为默认后,以后安装库都是从清华源下载,而且无需再加镜像源网址

              附主流镜像源地址

              • 清华:https://pypi.tuna.tsinghua.edu.cn/simple
              • 阿里云:http://mirrors.aliyun.com/pypi/simple/
              • 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/
              • 华中理工大学:http://pypi.hustunique.com/
              • 山东理工大学:http://pypi.sdutlinux.org/
              • 豆瓣:http://pypi.douban.com/simple/


              包管理工具是用来对一些应用程序的包进行管理的工具,比如nodejs使用npm,yarn来进行包管理,linux使用apt来进行包管理。python包管理工具或许不如他们有名(实际上pip的大名比前几位更响亮),但绝对比他们好用易用。没错,小编这里要说的就是pip,接下来的这篇文章,我们将对pip使用进行一个详细的介绍。

              认识pip

              众所周知,pip可以对python的第三方库进行安装、更新、卸载等操作,十分方便。

              pip的全称:package installer for python,也就是Python包管理工具。

              可能有些人用了很久pip,但还不清楚包管理工具是个啥。

              我们先从Python这门语言说起,Python之所以受欢迎不光是因为它简单易学,更重要的是它有成千上万的宝藏库。

              这些库相当于是已经集成好的工具,只要安装就能在Python里使用。它们可以处理各式各样的问题,无需你再造轮子,而且随着社区的不断更新维护,有些库越来越强大,几乎能媲美企业级应用。

              那么这些工具库怎么下载安装呢?它们被放在一个统一的“仓库”里,名叫PyPi(Python Package Index),所有的库安装都是从这里调度。

              有了仓库之后,还需要有管理员,pip就是这样一个角色。pip把库从PyPi取出来,然后安装到Python里,还可以管理安装好的库,比如更新、查看、搜索、卸载等等。

              总的来说,pip的Python第三方库的大管家,搞懂它,会让你省很多事。

              下面总结了30个pip使用过程中的常识和技巧,供大家参考。

              「注:因为pip是一个命令行程序,所以pip一般都在命令行中执行各种操作」

              1、安装pip

              从Python 3.4开始,pip已经内置在Python中,所以无需再次安装。

              如果你的Python版本没有pip,那可以使用下面两种方法安装。

              (1) 命令行中输入easy_install pip,非常快捷

              (2) 在下面网址中下载pip安装文件,然后解压到python scripts目录中,执行python setup.py install安装即可

              下载网址:https://pypi.org/project/pip/#files

              下载文件:

              安装pip

              2、查看pip版本

              pip --version

              查看pip版本

              3、升级pip

              如果pip的版本太低,可以升级当前版本

              pip install --upgrade pip

              4、获取帮助

              想了解如何使用pip,以及pip有哪些功能,执行下面语句可以获取详细教程:

              pip help

              5、安装库

              使用pip安装第三方库,执行下面语句

              pip install package_name

              指定package版本:

              pip install package_name==1.1.2

              比如说,我要安装3.4.1版本的matplotlib

              pip install matplotlib==3.4.1

              6、批量安装库

              如果一个项目需要安装很多库,那可以批量安装:

              pip install -r e: equirements.txt

              requirements.txt文件内容格式如下:

              批量安装文件

              7、使用wheel文件安装库

              这种方法适合离线安装,wheel文件是库的源文件,可以下载后放到本地安装。

              步骤如下:

              (1) 在下面网站里找相应库的.whl文件

              https://www.lfd.uci.edu/~gohlke/pythonlibs/

              (2) 下载.whl文件,注意对应的版本

              下载轮子

              (3) 在.whl所在文件夹内,按Shift键+鼠标右键,打开CMD窗口或者PowerShell

              (4) 输入命令:

              pip install matplotlib‑3.4.1‑cp39‑cp39‑win_amd64.whl

              即可完成安装

              8、卸载库

              安装好的库可以再卸载:

              pip uninstall package_name

              9、升级库

              对当前库进行版本升级:

              pip install --upgrade package_name

              10、查看库信息

              pip show -f package_name

              查看库信息

              11、查看已安装的库

              列出所有已安装的第三方库和对应版本

              pip list

              查看已安装库列表

              12、将库列表保存到指定文件中

              把已经安装的库信息保存到到本地txt文件中:

              pip freeze > requirements.txt

              导出库文件列表

              13、查看需要升级的库

              目前已经安装的库中,看哪些需要版本升级

              pip list -o

              查看可升级的库

              14、检查兼容问题

              验证已安装的库是否有兼容依赖问题

              pip check package-name

              兼容性检查

              15、下载库到本地

              将库下载到本地指定文件,保存为whl格式

              pip download package_name -d "要保存的文件路径"

              下载库


              xlrd库是一个python用于操作excel的第三方库。它的主要功能是用来读取excel。通常会与xlwt 、 xlutils组合进行使用。 

              注意!这里的操作excel,实际上与excel无关,不需要下载excel,xlrd库直接操作的是excel打开的xls文件!
              注意!xlrd库只能读取excel,不能修改,编写excel!

              一 、xlrd的安装

              可以使用pip进行安装,这是最简单也是最普遍的安装方式!

              在cmd中输入​pip install xlrd​即可安装xlrd库。

              安装成功后可以使用​pip list​来检查是否正确安装以及查看当前的xlrd版本。

              注意:xlrd较高版本中不支持.xlsx文件,可以手动将版本降至更低的版本或者将.xlsx文件改为.xls文件
              • 先卸载掉现有的 xlrd —> pip uninstall xlrd
              • 重新安装指定版本的 xlrd —> pip install xlrd == 1.2.0
              接下来的文章由于此原因使用1.2.0版本的xlrd进行介绍

              二、xlrd模块的使用

              下面以这个工作簿为例

              1、导入模块

               import xlrd

              2、打开工作薄

              # filename是文件的路径名称workbook = xlrd.open_workbook(filename=r'C:UsersWindows10Desktopxlsx文件.xlsx')

              3、获取需要操作的sheet表格(有三种方法)

              ①通过索引获取

              # 获取第一个sheet表格table = workbook.sheets()[0]

              ②通过索引顺序获取

              # 通过索引顺序获取table = workbook.sheet_by_index(0)

              ③通过sheet名称获取

              # 通过sheet名称获取table = workbook.sheet_by_name(sheet_name='Sheet1')

              补充:获取工作薄中所有sheet名称

              # 获取工作薄中所有的sheet名称names = workbook.sheet_names()print(names)

              运行结果:


              三、行和列的操作

              常用1:获取sheet中有多少行和多少列

              # 获取sheet中有效行数# 需要先指定sheet工作表table = workbook.sheet_by_name(sheet_name='视频课列表')row = table.nrowsprint(row)

              运行结果:



              # 获取sheet中有效列数# 需要先指定sheet工作表table = workbook.sheet_by_name(sheet_name='视频课列表')col = table.ncolsprint(col)

              运行结果


              常用2:获取一行中有多少列数据

              # 返回该行的有效单元格长度# 需要先指定sheet工作表table = workbook.sheet_by_name(sheet_name='视频课列表')num = table.row_len(0)print(num)

              打印结果:


              常用3:获取指定行或者列中所有的数据

              # rowx表示是获取第几行的数据# start_col表示从索引为多少开始,end_colx表示从索引为多少结束,# end_colx为None表示结束没有限制# 获取指定行中的数据并以列表的形式返回# 需要先指定sheet工作表table = workbook.sheet_by_name(sheet_name='视频课列表')table_list = table.row_values(rowx=0, start_colx=0, end_colx=None)print(table_list)

              运行结果为:


              # colx表示是获取第几列的数据
              # start_rowx表示从索引为多少开始,end_rowx表示从索引为多少结束,
              # end_rowx为None表示结束没有限制
              # 获取指定列中的数据并以列表的形式返回

              # 需要先指定sheet工作表
              table = workbook.sheet_by_name(sheet_name='视频课列表')
              table_list = table.col_values(colx=0, start_rowx=0, end_rowx=None)
              print(table_list)

              运行结果为:


              补充:了解即可

              # 需要先指定sheet工作表table = workbook.sheet_by_name(sheet_name='视频课列表')#返回由该列中所有的单元格对象组成的列表print(table.row(0))#返回由该行中所有的单元格对象组成的列表print(table.row_slice(0))#返回由该行中所有单元格的数据类型组成的列表print(table.row_types(0, start_colx=0, end_colx=None))

              运行结果为:

              # 需要先指定sheet工作表
              table = workbook.sheet_by_name(sheet_name='视频课列表')
              #返回由该列中所有的单元格对象组成的列表
              print(table.col(0, start_rowx=0, end_rowx=None))
              #返回由该列中所有的单元格对象组成的列表
              print(table.col_slice(0, start_rowx=0, end_rowx=None))
              #返回由该列中所有单元格的数据类型组成的列表
              print(table.col_types(0, start_rowx=0, end_rowx=None))

              运行结果为:

              四、单元格的操作

              1、获取单元中的值

              # 获取指定单元格内的值(第二行第一列,在python中从零开始计算序号)
              # 需要先指定sheet工作表
              table = workbook.sheet_by_name(sheet_name='视频课列表')
              value = table.cell_value(rowx=1, colx=0)
              print(value)

              运行结果为:


              2、获取单元格内的组成对象和数据

              # 需要先指定sheet工作表
              table = workbook.sheet_by_name(sheet_name='视频课列表')
              value = table.cell(rowx=1, colx=0)
              print(value)

              运行结果


              3、获取单元格的数据类型

              python读取excel中单元格的内容返回的有5种类型。分别为:

              • 0 empty
              • 1 string
              • 2 number
              • 3 date
              • 4 boolean
              • 5 error

              即date的ctype=3,这时需要使用xlrd的​xldate_as_tuple来处理为date格式,先判断表格的ctype=3时xldate才能开始操作。

              # 需要先指定sheet工作表table = workbook.sheet_by_name(sheet_name='视频课列表')value = table.cell_type(rowx=0, colx=1)print(value)

              运行结果为:

              五、案例

              需求:获取上面表格中的数据并依次打印出来

              import xlrdworkbook = xlrd.open_workbook(filename=r'C:UsersEeeDong-10DesktopW3Cschool课程内容.xlsx')# 需要先指定sheet工作表table = workbook.sheet_by_name(sheet_name='视频课列表')# 获取行数rows = table.nrows# 获取列数cols = table.ncols# 循环获取每行的数据for row in range(rows):    for col in range(cols):        value = table.cell_value(row, col)        print('第{}行{}列的数据为:{}'.format(row, col, value))

              运行结果为:



              有一部分小伙伴学习python的目的就是为了实现办公自动化的目的。通过使用更易学习的python替代excel中自带的vbs脚本,来实现excel的批量操作(例如表格调整,批量处理数据等)。

              接下来这篇文章小编带你了解python中常用的几种可以操作excel的第三方库,并在文末附上相应教程的链接,小伙伴可以根据自己的需求挑选最合适自己的库进行学习!

              首先让我们来整体把握下不同库的特点

              1. xlrd 、 xlwt 、 xlutils 各自的功能都有局限性,但三者互为补充,覆盖了Excel文件尤其是 .xls 文件的操作。 xlwt 可以生成 .xls 文件, xlrd 可以读取已经存在的 .xls 文件, xlutils 连接 xlrd 和 xlwt 两个模块,使用户可以同时读写一个 .xls 文件。简单来说, xlrd 负责读、 xlwt 负责写、 xlutils 负责提供辅助和衔接。
              2. xlwings 能够非常方便的读写 Excel 文件中的数据,并且能够进行单元格格式的修改。
              3. XlsxWriter 是一个用来写 .xlsx 文件格式的模块。它可以用来写文本、数字、公式并支持单元格格式化、图片、图表、文档配置、自动过滤等特性。但不能用来读取和修改 Excel 文件。
              4. openpyxl 通过 工作簿 “workbook - 工作表 sheet - 单元格 cell” 的模式对 .xlsx 文件进行读、写、改,并且可以调整样式。
              5. pandas 大家都不陌生,是进行数据处理和分析的强大模块,有时也可以用来自动化处理Excel。



              pandas教程链接地址:https://www.51coolma.cn/pandas/

              pandas教程关于excel教程操作的文章:https://www.51coolma.cn/pandas/pandas-excel.html

              xlrd 教程:https://www.51coolma.cn/python3/python3-xlrd.html


              xlwt库是一个python用于操作excel的第三方库。它的主要功能是用来写入excel。通常会与xlrd 、 xlutils组合进行使用。 

              注意!这里的操作excel,实际上与excel无关,不需要下载excel,xlwt库直接操作的是excel打开的xls文件!注意!xlrd库只能创建和修改excel,不能打开excel!

              一 、xlwt的安装

              可以使用pip进行安装,这是最简单也是最普遍的安装方式!

              在cmd中输入​pip install xlrd​即可安装xlrd库。

              安装成功后可以使用​pip list​来检查是否正确安装以及查看当前的xlrd版本。

              注意:xlrd较高版本中不支持.xlsx文件,可以手动将版本降至更低的版本或者将.xlsx文件改为.xls文件先卸载掉现有的 xlrd —> pip uninstall xlrd重新安装指定版本的 xlrd —> pip install xlrd == 1.2.0接下来的文章由于此原因使用1.2.0版本的xlrd进行介绍

              二、创建表格并写入

              • 创建表格,设置sheet名称
              • 写入指定行列的数据,将表格进行保存
              import xlwt # 创建一个workbook并设置编码workbook = xlwt.Workbook(encoding = 'utf-8')# 添加sheetworksheet = workbook.add_sheet('微课列表')# 写入excel, 参数对应 行, 列, 值worksheet.write(1,0, label = 'MySQL零基础入门课程')# 保存workbook.save('W3Cschool课程内容.xls')

              三、设置单元格样式

              • 给单元格设置样式,包括字体颜色、粗细、是否斜体等
              import xlwt workbook = xlwt.Workbook(encoding = 'utf-8')worksheet = workbook.add_sheet('微课列表')  # 初始化样式style = xlwt.XFStyle() # 为样式创建字体font = xlwt.Font() # 黑体font.name = 'Times New Roman'font.bold = True # 下划线font.underline = True # 斜体字font.italic = True # 设定样式style.font = font # 带样式的写入worksheet.write(0, 0, '带样式的单元格', style) # 保存文件workbook.save('W3Cschool课程内容.xls')

              四、设置单元格宽度

              import xlwt workbook = xlwt.Workbook()worksheet = workbook.add_sheet('微课列表') worksheet.write(1, 1,'MySQL') # 设置单元格宽度worksheet.col(0).width = 3000 workbook.save('W3Cschool课程内容.xls')

              五、设置单元格背景色

              import xlwt workbook = xlwt.Workbook()worksheet = workbook.add_sheet('微课列表') # 创建模式对象Create the Patternpattern = xlwt.Pattern() # May be: NO_PATTERN, SOLID_PATTERN, or 0x00 through 0x12pattern.pattern = xlwt.Pattern.SOLID_PATTERN #设置模式颜色 May be: 8 through 63. 0 = Black, 1 = White, 2 = Red, 3 = Green, 4 = Blue, 5 = Yellow, 6 = Magenta, 7 = Cyan, 16 = Maroon, 17 = Dark Green, 18 = Dark Blue, 19 = Dark Yellow , almost brown), 20 = Dark Magenta, 21 = Teal, 22 = Light Gray, 23 = Dark Gray, the list goes on...pattern.pattern_fore_colour = 5 # 创建样式对象Create the Patternstyle = xlwt.XFStyle() # 将模式加入到样式对象Add Pattern to Stylestyle.pattern = pattern #向单元格写入内容时使用样式对象styleworksheet.write(0, 0, '单元格内容', style) workbook.save('W3Cschool课程内容.xls')

              六、设置单元格内容对其方式

              import xlwt workbook = xlwt.Workbook()worksheet = workbook.add_sheet('微课列表') # 创建对其格式的对象 Create Alignmentalignment = xlwt.Alignment() #水平居中 May be: HORZ_GENERAL, HORZ_LEFT, HORZ_CENTER, HORZ_RIGHT, HORZ_FILLED, HORZ_JUSTIFIED, HORZ_CENTER_ACROSS_SEL, HORZ_DISTRIBUTEDalignment.horz = xlwt.Alignment.HORZ_CENTER #我上下对齐 May be: VERT_TOP, VERT_CENTER, VERT_BOTTOM, VERT_JUSTIFIED, VERT_DISTRIBUTEDalignment.vert = xlwt.Alignment.VERT_CENTER  #创建样式对象 Create Stylestyle = xlwt.XFStyle() # 将格式Alignment对象加入到样式对象Add Alignment to Stylestyle.alignment = alignment #写入的时候调用样式styleworksheet.write(0, 0, '单元居中', style) workbook.save('W3Cschool课程内容.xls')

              七、单元格添加超链接

              import xlwt workbook = xlwt.Workbook()worksheet = workbook.add_sheet('') worksheet.write(2, 3, xlwt.Formula('HYPERLINK("https://www.51coolma.cn/minicourse/play/txymysql";"MySQL零基础入门课程")')) workbook.save('W3Cschool课程内容.xls')

              八、单元格添加公式

              import xlwt workbook = xlwt.Workbook()worksheet = workbook.add_sheet('微课列表') worksheet.write(0, 0, 5) # Outputs 5  #第一行第一列5worksheet.write(0, 1, 2) # Outputs 2  #第一行第二列2 #(A1[5] * A2[2])  第二行第一列,输出第一行数字乘积worksheet.write(1, 0, xlwt.Formula('A1*B1')) #(A1[5] + A2[2])  第二行第二列,输出第一行数字之和worksheet.write(1, 1, xlwt.Formula('SUM(A1,B1)')) workbook.save('W3Cschool课程内容.xls')

              九、单元格中输入日期

              import xlwtimport datetime workbook = xlwt.Workbook()worksheet = workbook.add_sheet('微课列表') style = xlwt.XFStyle() #其他格式包括: D-MMM-YY, D-MMM, MMM-YY, h:mm, h:mm:ss, h:mm, h:mm:ss, M/D/YY h:mm, mm:ss, [h]:mm:ss, mm:ss.0style.num_format_str = 'M/D/YY' worksheet.write(0, 0, datetime.datetime.now(), style) workbook.save('W3Cschool课程内容.xlsx')

              十、合并行和列

              import xlwt workbook = xlwt.Workbook()worksheet = workbook.add_sheet('微课列表') worksheet.write_merge(0, 1, 0, 3, '合并从第一行到第二行,第一列到第四列') #创建字体示例font = xlwt.Font() #bold设置为黑体字font.bold = True # Create Stylestyle = xlwt.XFStyle() # Add Bold Font to Stylestyle.font = fontworksheet.write_merge(2,3, 0, 3, '合并从第三行到第四行,第一列到第四列', style) workbook.save('W3Cschool课程内容.xls')

              十一、单元格添加边框

              import xlwt workbook = xlwt.Workbook()worksheet = workbook.add_sheet('微课列表') # 创建边框对象Create Bordersborders = xlwt.Borders() #对边框对象进行操作,指定边框上下左右的边框类型为虚线# DASHED虚线# NO_LINE没有# THIN实线# May be: NO_LINE, THIN, MEDIUM, DASHED, DOTTED, THICK, DOUBLE, HAIR, MEDIUM_DASHED, THIN_DASH_DOTTED, MEDIUM_DASH_DOTTED, THIN_DASH_DOT_DOTTED, MEDIUM_DASH_DOT_DOTTED, SLANTED_MEDIUM_DASH_DOTTED, or 0x00 through 0x0D.borders.left = xlwt.Borders.DASHEDborders.right = xlwt.Borders.DASHEDborders.top = xlwt.Borders.DASHEDborders.bottom = xlwt.Borders.DASHED #指定上下左右的边框颜色为0x40borders.left_colour = 0x40borders.right_colour = 0x40borders.top_colour = 0x40borders.bottom_colour = 0x40 # Create Style   #创建样式对象style = xlwt.XFStyle() # 将设置好的边框对象borders 加到样式对象style中。Add Borders to Stylestyle.borders = borders #向单元格第一行第一列写入“单元格内容”,并使用创建好的样式对象styleworksheet.write(0, 0, '单元格内容', style)workbook.save('W3Cschool课程内容.xls')


              Python 3.9 已于2020 年 10 月 5 日发布,新版本的特性,你 get 到了吗?对于 Python 程序员来说,这又是一个令人兴奋的时刻。

              相比于之前的版本,Python 3.9 有哪些值得讨论的功能呢?

              简而言之,从字典更新 / 合并到添加新的字符串方法,再到 ​zoneinfo​ 库的引入,Python 3.9 添加了许多新特性。此外,该版本还引入了一种稳定、高性能的新型解析器。

              标准库更新了许多新特性,并添加了新模块 ​zoneinfo ​和 ​graphlib​。此外该版本也对许多模块进行了改进,如 ​ast​、​asyncio​、​concurrent.futures​、​multiprocessing​、​xml ​等。

              现在让我们一起探索 Python 3.9 的新特性。

              Python 3.9:10 个有趣的新特性

              1. 字典更新和合并

              合并 (|) 与更新 (|=) 运算符已被加入内置的 ​dict ​类。 它们为现有的 dict.update 和 {**d1, **d2} 字典合并方法提供了补充。

              示例:

              >>> x = {"key1": "value1 from x", "key2": "value2 from x"}>>> y = {"key2": "value2 from y", "key3": "value3 from y"}>>> x | y{'key1': 'value1 from x', 'key2': 'value2 from y', 'key3': 'value3 from y'}>>> y | x{'key2': 'value2 from x', 'key3': 'value3 from y', 'key1': 'value1 from x'}

              2. 基于 PEG 的高性能解析器

              Python 3.9 提出用高性能和稳定的基于 PEG 的解析器取代当前基于 LL(1) 的 Python 解析器。

              当前的 CPython 解析器基于 LL(1),LL(1) 解析器是一个自顶向下的解析器,它从左到右解析输入。

              Python 3.9 提议将 LL(1) 替换为新的基于 PEG 的解析器,这意味着它将解除当前 LL(1) 语法对 Python 的限制。此外,当前的解析器修补了许多将要删除的 hack。因此,从长远来看,这会降低维护成本。

              3. 新型字符串函数:删除前缀和后缀

              Python 3.9 将两个新函数添加到 str 对象:

              第一个函数用于删除前缀:​str.removeprefix(prefix)

              第二个函数用于删除后缀:​str.removesuffix(suffix)

              4. 对内置泛型类型提供类型提示

              Python 3.9 通过删除并行类型层次结构,使注释程序变得更加简单。Python 3.9 支持 ​typing ​模块所有标准集合中的泛型语法。

              我们可以将 ​list ​或 ​dict ​直接作为列表和字典的类型注释,而不必依赖 ​typing.List​ 或者 ​typing.Dict​。因此,代码现在看起来更加简洁,而且更容易理解和解释。

              5. DateTime 支持 IANA 时区

              zoneinfo ​模块被创建出来支持 IANA 时区数据库。对 IANA 时区数据库的支持已经添加到标准库中。

              示例:

              >>> from zoneinfo import ZoneInfo>>> from datetime import datetime, timedelta>>> # Daylight saving time>>> dt = datetime(2020, 10, 31, 12, tzinfo=ZoneInfo("America/Los_Angeles"))>>> print(dt)2020-10-31 12:00:00-07:00>>> dt.tzname()'PDT'>>> # Standard time>>> dt += timedelta(days=7)>>> print(dt)2020-11-07 12:00:00-08:00>>> print(dt.tzname())PST

              IANA 时区通常称为 ​tz ​或 ​zone info​。存在许多具备不同搜索路径的 IANA 时区,用于为 ​datetime ​对象指定 IANA 时区。例如,我们可以将对 ​datetime ​对象设置搜索路径​Continent/City​来设置​ tzinfo​。

              如果传入一个无效的密钥,则会引发​ zoneinfo.ZoneInfoNotFoundError​ 异常。

              6. concurrent.futures 优化

              concurrent.futures.Executor.shutdown()​ 中添加了一个新参数​ cancel_futures​。此参数可以取消尚未执行的并发任务。在 Python 3.9 之前主进程只有在所有并发任务完成后才能关闭 ​executor ​对象。

              新参数 ​cancel_futures ​已被添加到 ​ThreadPoolExecutor ​以及 ​ProcessPoolExecutor​。它的工作方式是:当参数的值为 ​True ​时,在调用 ​shutdown()​ 函数时取消所有待处理的任务。

              7. 异步编程和多进程优化

              Python 3.9 对异步编程(​asyncio​)和多进程库进行了优化。

              2. 新增了 ​coroutines​、​shutdown_default_executor()​ 和 ​asyncio.to_thread()​ 。​shutdown_default_executor​ 负责关闭默认 ​executor​,​asyncio.to_thread()​ 主要用于在一条单独的线程中运行 IO 密集型函数,以避免事件循环。

              关于多进程库的改进,Python 3.9 向 ​multiprocessing.SimpleQueue​ 类添加了新方法 ​close()​。

              此方法可以显式地关闭队列。这将确保队列关闭并且停留时间不会比预期长。值得注意的是,一旦关闭队列,就不能调用​ get()​、​put() ​和 ​empty() ​方法。

              8. 统一的软件包导入错误

              Python3.9 之前的版本在导入 Python 库时存在的主要问题是:当相对导入超出其顶级包时,Python 中的导入行为不一致。

              builtins.__import__() ​引发 ​ValueError​,而 ​importlib.__import__() ​引发 ​ImportError​。Python3.9 版本进行了修复,它将统一引发 ​ImportError​。

              9. 生成随机字节

              Python 3.9 版本中添加了新的函数​ random.Random.randbytes()​。该函数可用于生成随机字节。

              Python 支持生成随机数,但如果需要生成随机字节呢?在 Python3.9 版本之前,开发人员必须想方设法生成随机字节。尽管他们可以使用​ os.getrandom()​、​os.urandom()​ 或者 ​secrets.token_bytes() ​来生成随机字节,但这些方法无法生成伪随机模式。

              为了确保随机数的产生符合预期行为,并且过程可复现,开发人员通常将种子(seed)与 ​random.Random ​模块一起使用。因此,Python 3.9 添加了 ​random.Random.randbytes()​ 方法,以可控的方式生成随机字节。

              10. 修复字符串替换函数

              在 Python 3.9 版本之前,对于所有非零的 n,"".replace("",s,n) 返回空字符串而不是 s。这个错误使用户困惑,并导致应用程序的不一致行为。

              Python 3.9 修复了该问题,不管 n 是否为 0,其结果都与 "".replace("", s) 一致。

              如果大家想深入了解更多细节,请查阅官方文档:https://docs.python.org/zh-cn/3.9/whatsnew/3.9.html


              以下列出了Python常见的职业方向, 职业树可以直观帮助我们做定位和选择。


              Python math 模块 Python math 模块

              Python math.trunc(x) 方法返回 x 截断整数的部分,即返回整数部分,忽略小数部分。

              math.trunc(x) 方法不会将数字向上/向下舍入到最接近的整数,而只是删除小数。

              语法

              math.trunc() 方法语法如下:

              math.trunc(x)

              参数说明:

              • x -- 必需,数字。如果 x 不是一个数字,返回 TypeError。如果值为 0 或负数,则返回 ValueError。

              返回值

              返回一个整数 int,表示 x 的整数部分。

              实例

              以下实例返回数字的整数部分:

              # 导入 math 包import math# 输出整数部分print(math.trunc(2.77))print(math.trunc(8.32))print(math.trunc(-99.29))

              输出结果:

              28-99


              Python math 模块 Python math 模块

              Python math.tanh(x) 返回 x 的双曲正切值。

              Python 版本: 1.4

              语法

              math.tanh() 方法语法如下:

              math.tanh(x)

              参数说明:

              • x -- 必需,个正数或负数。如果 x 不是一个数字,返回 TypeError。

              返回值

              返回一个浮点数,表示一个数字的双曲正切值。

              实例

              以下实例返回不同数字的双曲正切值:

              # 导入 math 包import math# 输出双曲正切值print(math.tanh(8))print(math.tanh(1))print(math.tanh(-6.2))

              输出结果:

              0.99999977492967580.7615941559557649-0.9999917628565104


              Python math 模块 Python math 模块

              Python math.tan(x) 返回 x 弧度的正切值。

              Python 版本: 1.4

              语法

              math.tan() 方法语法如下:

              math.tan(x)

              参数说明:

              • x -- 必需,数字。如果 x 不是数字,则返回 TypeError。

              返回值

              返回一个浮点数,表示 x 的正切值。

              实例

              以下实例返回数字的正切值:

              # 导入 math 包import math# 输出正切值print (math.tan(90))print (math.tan(-90))print (math.tan(45))print (math.tan(60))

              输出结果:

              -1.9952004122082421.9952004122082421.61977519054386150.3200403893795629


              Python math 模块提供了许多对浮点数的数学运算函数。

              math 模块下的函数,返回值均为浮点数,除非另有明确说明。

              如果你需要计算复数,请使用 cmath 模块中的同名函数。

              要使用 math 函数必须先导入:

              import math

              查看 math 模块中的内容:

              >>> import math>>> dir(math)['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'comb', 'copysign', 'cos', 'cosh', 'degrees', 'dist', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'isqrt', 'lcm', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'nextafter', 'perm', 'pi', 'pow', 'prod', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc', 'ulp']

              math 模块常量

              常量描述
              math.e返回欧拉数 (2.7182...)
              math.inf返回正无穷大浮点数
              math.nan返回一个浮点值 NaN (not a number)
              math.piπ 一般指圆周率。 圆周率 PI (3.1415...)
              math.tau数学常数 τ = 6.283185...,精确到可用精度。Tau 是一个圆周常数,等于 2π,圆的周长与半径之比。

              math 模块方法

              方法描述
              math.acos(x)返回 x 的反余弦,结果范围在 0 到 pi 之间。
              math.acosh(x)返回 x 的反双曲余弦值。
              math.asin(x)返回 x 的反正弦值,结果范围在 -pi/2 到 pi/2 之间。
              math.asinh(x)返回 x 的反双曲正弦值。
              math.atan(x)返回 x 的反正切值,结果范围在 -pi/2 到 pi/2 之间。
              math.atan2(y, x)返回给定的 X 及 Y 坐标值的反正切值,结果是在 -pi 和 pi 之间。
              math.atanh(x)返回 x 的反双曲正切值。
              math.ceil(x)将 x 向上舍入到最接近的整数
              math.comb(n, k)返回不重复且无顺序地从 n 项中选择 k 项的方式总数。
              math.copysign(x, y)返回一个基于 x 的绝对值和 y 的符号的浮点数。
              math.cos()返回 x 弧度的余弦值。
              math.cosh(x)返回 x 的双曲余弦值。
              math.degrees(x)将角度 x 从弧度转换为度数。
              math.dist(p, q)返回 p 与 q 两点之间的欧几里得距离,以一个坐标序列(或可迭代对象)的形式给出。 两个点必须具有相同的维度。
              math.erf(x)返回一个数的误差函数
              math.erfc(x)返回 x 处的互补误差函数
              math.exp(x)返回 e 的 x 次幂,Ex, 其中 e = 2.718281... 是自然对数的基数。
              math.expm1()返回 Ex - 1, e 的 x 次幂,Ex,其中 e = 2.718281... 是自然对数的基数。这通常比 math.e ** x 或 pow(math.e, x) 更精确。
              math.fabs(x)返回 x 的绝对值。
              math.factorial(x)返回 x 的阶乘。 如果 x 不是整数或为负数时则将引发 ValueError。
              math.floor()将数字向下舍入到最接近的整数
              math.fmod(x, y)返回 x/y 的余数
              math.frexp(x)以 (m, e) 对的形式返回 x 的尾数和指数。 m 是一个浮点数, e 是一个整数,正好是 x == m * 2**e 。 如果 x 为零,则返回 (0.0, 0) ,否则返回 0.5 <= abs(m) < 1 。
              math.fsum(iterable)返回可迭代对象 (元组, 数组, 列表, 等)中的元素总和,是浮点值。
              math.gamma(x)返回 x 处的伽马函数值。
              math.gcd()返回给定的整数参数的最大公约数。
              math.hypot()返回欧几里得范数,sqrt(sum(x**2 for x in coordinates))。 这是从原点到坐标给定点的向量长度。
              math.isclose(a,b)检查两个值是否彼此接近,若 a 和 b 的值比较接近则返回 True,否则返回 False。。
              math.isfinite(x)判断 x 是否有限,如果 x 既不是无穷大也不是 NaN,则返回 True ,否则返回 False 。
              math.isinf(x)判断 x 是否是无穷大,如果 x 是正或负无穷大,则返回 True ,否则返回 False 。
              math.isnan()判断数字是否为 NaN,如果 x 是 NaN(不是数字),则返回 True ,否则返回 False 。
              math.isqrt()将平方根数向下舍入到最接近的整数
              math.ldexp(x, i)返回 x * (2**i) 。 这基本上是函数 math.frexp() 的反函数。
              math.lgamma()返回伽玛函数在 x 绝对值的自然对数。
              math.log(x[, base])使用一个参数,返回 x 的自然对数(底为 e )。
              math.log10(x)返回 x 底为 10 的对数。
              math.log1p(x)返回 1+x 的自然对数(以 e 为底)。
              math.log2(x)返回 x 以 2 为底的对数
              math.perm(n, k=None)返回不重复且有顺序地从 n 项中选择 k 项的方式总数。
              math.pow(x, y)将返回 x 的 y 次幂。
              math.prod(iterable)计算可迭代对象中所有元素的积。
              math.radians(x)将角度 x 从度数转换为弧度。
              math.remainder(x, y)返回 IEEE 754 风格的 x 除于 y 的余数。
              math.sin(x)返回 x 弧度的正弦值。
              math.sinh(x)返回 x 的双曲正弦值。
              math.sqrt(x)返回 x 的平方根。
              math.tan(x)返回 x 弧度的正切值。
              math.tanh(x)返回 x 的双曲正切值。
              math.trunc(x)返回 x 截断整数的部分,即返回整数部分,删除小数部分


              Python math 模块 Python math 模块

              Python math.sqrt(x) 方法返回 x 的平方根。

              数字必须大于等于 0。

              语法

              math.sqrt() 方法语法如下:

              math.sqrt(x)

              参数说明:

              • x -- 必需,数字。如果 x 不是一个数字,返回 TypeError。如果数字小于 0,则返回 ValueError。

              返回值

              返回一个浮点数,表示一个数的平方根。

              实例

              以下实例返回数字的平方根:

              # 导入 math 包import math# 输出平方根print (math.sqrt(9))print (math.sqrt(25))print (math.sqrt(16))

              输出结果:

              3.05.04.0


              Python math 模块 Python math 模块

              Python math.sin(x) 返回 x 弧度的正弦值。

              要获取指定角度的正弦,必须首先使用 math.radians() 方法将其转换为弧度。

              Python 版本: 1.4

              语法

              math.sin() 方法语法如下:

              math.sin(x)

              参数说明:

              • x -- 必需,数字。如果 x 不是数字,则返回 TypeError。

              返回值

              返回一个浮点数,表示 x 的正弦值,介于 -1 到 1 之间。

              实例

              以下实例返回数字的正弦值:

              # 导入 math 包import math# 输出正弦值print (math.sin(0.00))print (math.sin(-1.23))print (math.sin(10))print (math.sin(math.pi))print (math.sin(math.pi/2))

              输出结果:

              0.0-0.9424888019316975-0.54402111088936991.2246467991473532e-161.0

              要获取指定角度的正弦,必须首先使用 math.radians() 方法将其转换为弧度:

              # 导入 math 包import math# 角度 30 先转换为弧度再计算正弦值print(math.sin(math.radians(30)))# 角度 90 先转换为弧度再计算正弦值print(math.sin(math.radians(90)))

              输出结果:

              0.499999999999999941.0


              Python math 模块 Python math 模块

              Python mathremainder(x, y) 方法返回 x/y 的余数。

              Python 版本:3.7

              语法

              math.remainder() 方法语法如下:

              math.remainder(x, y)

              参数说明:

              • x -- 必需,被除数。
              • y -- 可选,除数。必须是非零数字,否则会发生 ValueError。

              返回值

              一个浮点值,返回余数。

              实例

              以下实例计算余数:

              # 导入 math 包import math# x/y 的余数print (math.remainder(9, 2))print (math.remainder(9, 3))print (math.remainder(18, 4))print (math.remainder(23.5, 5))print (math.remainder(23, 5.5))print (math.remainder(12.5, 2.5))print (math.remainder(12, 2))

              输出结果:

              1.00.02.0-1.51.00.00.0


              Python math 模块 Python math 模块

              Python math.sinh(x) 返回 x 的双曲正弦值。

              Python 版本: 1.4

              语法

              math.sinh() 方法语法如下:

              math.sinh(x)

              参数说明:

              • x -- 必需,个正数或负数。如果 x 不是一个数字,返回 TypeError。

              返回值

              返回一个浮点数,表示一个数字的双曲正弦值。

              实例

              以下实例返回不同数字的双曲正弦值:

              # 导入 math 包import math# 输出双曲正弦值print(math.sinh(0.00))print(math.sinh(-23.45))print(math.sinh(23))print(math.sinh(1.00))print(math.sinh(math.pi))

              输出结果:

              0.0-7641446994.9793674872401723.1244521.175201193643801411.548739357257746


              Python math 模块 Python math 模块

              Python math.prod() 方法用于计算可迭代对象中所有元素的积。

              Python 版本:3.8

              语法

              math.prod() 方法语法如下:

              math.prod(iterable, start)

              参数说明:

              • iterable -- 必需,可迭代对象。
              • start -- 可选,指起始值。 默认值为 1。

              返回值

              一个浮点值或整数,可迭代元素的乘积,类型会根据元素判断,如果元素都是整数返回的是整数,如果元素有浮点数,返回的是浮点数。

              实例

              以下实例计算可迭代元素的乘积:

              # 导入 math 包import math# 计算可迭代元素的乘积sequence = (2, 2, 2)print(math.prod(sequence))

              输出结果:

              8


              Python math 模块 Python math 模块

              Python math.perm(x, i) 方法返回不重复且有顺序地从 n 项中选择 k 项的方式总数。

              注意:k 参数是可选的。 如果我们没有设置 k,这个方法将返回 n! (例如,math.perm(7) 将返回 5040)。

              Python 版本:3.8

              语法

              math.perm() 方法语法如下:

              math.perm(n, k)

              参数说明:

              • x -- 必需,一个正数。如果值不是数字,则返回 TypeError。
              • k -- 可选,一个正数。如果值不是数字,则返回 TypeError。

              注意:如果 k 大于 n,则返回 0。

              注意:如果 n 或 k 为负数,则会发生 ValueError。 如果 n 或 k 不是整数,则会发生 TypeError。

              返回值

              一个整数 int,返回不重复且有顺序地从 n 项中选择 k 项的方式总数。

              实例

              以下实例计算从 n 个项中选择 k 项的方式总数:

              # 导入 math 包import math# 初始化 nn = 7# 初始化 kk = 5# 输出从 n 个项中选择 k 项的方式总数print (math.perm(n, k))

              输出结果:

              2520


              Python math 模块 Python math 模块

              Python math.pow(x, y) 方法返回返回 x 的 y 次幂( 次方 )。

              如果 x 为负且 y 不是整数,则返回 ValueError。 该方法会将两个参数转换为浮点数。 math.pow(1.0,x) 或 math.pow(x,0.0),始终返回 1.0。

              语法

              math.pow() 方法语法如下:

              math.pow(x, y)

              参数说明:

              • x -- 必需,一个代表基数的数字。
              • y -- 必需,一个代表指数的数字。

              返回值

              返回一个浮点数,表示 x 的 y 次幂。

              实例

              以下实例返回 9 的 3 次方:

              # 导入 math 包import math# 输出 9 的 3 次方print(math.pow(9, 3))

              输出结果:

              729.0


              Python math 模块 Python math 模块

              Python math.log2(x) 方法返回 x 以 2 为底的对数。

              语法

              math.log2() 方法语法如下:

              math.log2(x)

              参数说明:

              • x -- 必需,数字。如果 x 不是一个数字,返回 TypeError。如果值为 0 或负数,则返回 ValueError。

              返回值

              返回一个整数浮点数 float,表示一个数字以 2 为底的自然对数。

              实例

              以下实例返回一个数字以 2 为底的自然对数:

              # 导入 math 包import math# 输出一个数字以 2 为底的自然对数print(math.log2(2.7183))print(math.log2(2))print(math.log2(1))

              输出结果:

              1.44270468518122221.00.0


              Python math 模块 Python math 模块

              Python math.log1p(x) 方法返回 1+x 的自然对数(以 e 为底)。

              语法

              math.log1p() 方法语法如下:

              math.log1p(x)

              参数说明:

              • x -- 必需,数字。如果 x 不是一个数字,返回 TypeError。如果值为 0 或负数,则返回 ValueError。

              返回值

              返回一个整数浮点数 float,表示 1+x 以 e 为底的自然对数。

              实例

              以下实例返回一个 1+x 以 e 为底的自然对数:

              # 导入 math 包import math# 输出 1+x 以 e 为底的自然对数print(math.log1p(2.7183))print(math.log1p(2))print(math.log1p(1))

              输出结果:

              1.3132665745863341.09861228866810980.6931471805599453


              Python math 模块 Python math 模块

              Python math.log10(x) 方法返回 x 以 10 为底的对数。

              语法

              math.log10() 方法语法如下:

              math.log10(x)

              参数说明:

              • x -- 必需,数字。如果 x 不是一个数字,返回 TypeError。如果值为 0 或负数,则返回 ValueError。

              返回值

              返回一个整数浮点数 float,表示一个数字以 10 为底的自然对数。

              实例

              以下实例返回一个数字以 10 为底的自然对数:

              # 导入 math 包import math# 输出一个数字以 10 为底的自然对数print(math.log10(2.7183))print(math.log10(2))print(math.log10(1))

              输出结果:

              0.434297385124508660.30102999566398120.0


              Python math 模块 Python math 模块

              Python math.log(x) 方法使用一个参数,返回 x 的自然对数(底为 e )。

              语法

              math.log() 方法语法如下:

              math.log(x[, base])

              参数说明:

              • x -- 必需,数字。如果 x 不是一个数字,返回 TypeError。如果值为 0 或负数,则返回 ValueError。
              • base -- 可选,底数,默认为 e。

              返回值

              返回一个整数浮点数 float,表示一个数字的自然对数。

              实例

              以下实例返回一个数字的自然对数:

              # 导入 math 包import math# 输出一个数字的自然对数print(math.log(2.7183))print(math.log(2))print(math.log(1))

              输出结果:

              1.00000668491398770.69314718055994530.0


              Python math 模块 Python math 模块

              Python math.lgamma(x) 方法返回一个数字的自然对数伽玛值。

              我们也可以通过使用 math.gamma() 方法找到伽玛值,然后使用 math.log() 方法计算该值的自然对数。

              伽玛值等于 factorial(x-1)。

              Python 版本: 3.2

              语法

              math.lgamma() 方法语法如下:

              math.lgamma(x)

              参数说明:

              • x -- 必需,数字。如果数字是负整数,则返回 ValueError。 如果不是数字,则返回 TypeError。。

              返回值

              一个浮点值,表示一个数字的对数伽玛值。

              实例

              以下实例计算不同数的自然对数伽玛值:

              # 导入 math 包import math# 计算不同数的自然对数伽玛值print (math.lgamma(7))print (math.lgamma(-4.2))

              输出结果:

              6.579251212010102-1.8075166614192908


              Python math 模块 Python math 模块

              Python math.ldexp(x, i) 方法返回 x * (2**i),math.frexp() 的反函数。

              Python 版本:2.6

              语法

              math.ldexp() 方法语法如下:

              math.ldexp(x, i)

              参数说明:

              • x -- 必需,一个正数或负数。如果值不是数字,则返回 TypeError。
              • i -- 必需,一个正数或负数。如果值不是数字,则返回 TypeError。

              返回值

              一个浮点值,返回 x * (2**i)

              实例

              以下实例计算 x * (2**i):

              # 导入 math 包import math# 返回 x * (2**i)print(math.ldexp(9, 3))print(math.ldexp(-5, 2))print(math.ldexp(15, 2))

              输出结果:

              72.0-20.060.0


              Python math 模块 Python math 模块

              Python math.isqrt(x) 方法返回 x 的平方根,并将平方根数向下舍入到最接近的整数。

              数字必须大于等于 0。

              Python 版本:3.8

              语法

              math.isqrt() 方法语法如下:

              math.isqrt(x)

              参数说明:

              • x -- 必需,数字。如果 x 不是一个数字,返回 TypeError。如果数字小于 0,则返回 ValueError。

              返回值

              返回一个整数 int,表示一个数的平方根,并将平方根数向下舍入到最接近的整数。

              实例

              以下实例返回数字的平方根,并将平方根数向下舍入到最接近的整数:

              # 导入 math 包import math# 输出平方根# Print the square root of different numbersprint (math.sqrt(10))print (math.sqrt (12))print (math.sqrt (68))print (math.sqrt (100))# 输出平方根,并将平方根数向下舍入到最接近的整数print (math.isqrt(10))print (math.isqrt (12))print (math.isqrt (68))print (math.isqrt (100))

              输出结果:

              3.16227766016837953.46410161513775448.24621125123532110.033810


              Python math 模块 Python math 模块

              Python math.isinf() 方法判断 x 是否是无穷大,如果 x 是正或负无穷大,则返回 True ,否则返回 False 。

              Python 版本:2.6

              语法

              math.isinf() 方法语法如下:

              math.isinf(x)

              参数说明:

              • x -- 必需,数字。如果 x 不是一个数字,返回 TypeError。

              返回值

              返回一个布尔值,如果 x 是正或负无穷大,则返回 True ,否则返回 False 。

              实例

              以下实例检查数字是否是无穷大:

              # 导入 math 包import math# 检查数字是否是无穷大print(math.isinf(56))print(math.isinf(-45.34))print(math.isinf(+45.34))print(math.isinf(math.inf))print(math.isinf(float("nan")))print(math.isinf(float("inf")))print(math.isinf(float("-inf")))print(math.isinf(-math.inf))

              输出结果:

              FalseFalseFalseTrueFalseTrueTrueTrue


              Python math 模块 Python math 模块

              Python math.isfinite() 方法判断 x 是否有限,如果 x 既不是无穷大也不是 NaN,则返回 True ,否则返回 False 。

              Python 版本:3.2

              语法

              math.isfinite() 方法语法如下:

              math.isfinite(x)

              参数说明:

              • x -- 必需,数字。如果 x 不是一个数字,返回 TypeError。

              返回值

              返回一个布尔值,如果 x 既不是无穷大也不是 NaN,则返回 True ,否则返回 False 。

              实例

              以下实例检查数字是否有限:

              # 导入 math 包import math# 检查数字是否有限print(math.isfinite(2000))print(math.isfinite(-45.34))print(math.isfinite(+45.34))print(math.isfinite(math.inf))print(math.isfinite(float("nan")))print(math.isfinite(float("inf")))print(math.isfinite(float("-inf")))print(math.isfinite(-math.inf))print(math.isfinite(0.0))

              输出结果:

              TrueTrueTrueFalseFalseFalseFalseFalseTrue


              Python math 模块 Python math 模块

              Python math.isnan() 方法判断数字是否为 NaN(非数字),如果数字是 NaN(不是数字),则返回 True ,否则返回 False 。

              Python 版本: 3.5

              语法

              math.isnan() 方法语法如下:

              math.isnan(x)

              参数说明:

              • x -- 必需,数字。如果 x 不是一个数字,返回 TypeError。

              返回值

              返回一个布尔值,如果数字是 NaN(不是数字),则返回 True ,否则返回 False 。

              实例

              以下实例检查数字是否是 NaN(不是数字):

              # 导入 math 包import math# 检查数字是否为 NaNprint (math.isnan (56))print (math.isnan (-45.34))print (math.isnan (+45.34))print (math.isnan (math.inf))print (math.isnan (float("nan")))print (math.isnan (float("inf")))print (math.isnan (float("-inf")))print (math.isnan (math.nan))

              输出结果:

              FalseFalseFalseFalseTrueFalseFalseTrue


              Python math 模块 Python math 模块

              Python math.hypot() 方法返回欧几里得范数。

              欧几里得范数是从原点到给定坐标的距离。

              欧几里得度量又称为欧几里得距离,指的是欧几里得空间中两点间"普通"(即直线)距离。

              在 Python 3.8 之前,此方法用于查找直角三角形的斜边:sqrt(x*x + y*y)。

              从 Python 3.8 开始,此方法也用于计算欧几里得范数。 对于 n 维情况,假定传递的坐标类似于 (x1, x2, x3, ..., xn),从原点开始的欧几里得长度由 sqrt(x1*x1 + x2*x2 +x3*x3 .... xn*xn) 计算。

              Python 版本: 3.8

              语法

              math.hypot() 方法语法如下:

              math.hypot(x1, x2, x3, ..., xn)

              参数说明:

              • x1, x2, x3, ..., xn -- 必需,表示多个坐标点。

              返回值

              一个浮点值,表示 n 个输入到原点的欧几里得距离,或两个输入的直角三角形的斜边

              实例

              以下实例计算直角三角形的斜边:

              # 导入 math 包import math# 设置垂直线和底边parendicular = 10base = 5# 输出直角三角形的斜边print(math.hypot(parendicular, base))

              输出结果:

              11.180339887498949

              以下实例计算给定坐标的欧几里得范数:

              # 导入 math 包import math# 输出给定坐标的欧几里得范数print(math.hypot(10, 2, 4, 13))print(math.hypot(4, 7, 8))print(math.hypot(12, 14))

              输出结果:

              17.011.35781669160054718.439088914585774


              Python math 模块 Python math 模块

              Python math.gcd() 方法返回给定的整数参数的最大公约数。

              gcd(0,0) 返回 0。

              Python 版本:3.5

              在 3.9 版更改: 添加了对任意数量的参数的支持,之前的版本只支持两个参数。

              语法

              math.gcd() 方法语法如下:

              math.gcd(*integers)

              参数说明:

              • *integers -- 必需,数字。如果 x 不是一个数字,返回 TypeError。

              返回值

              返回一个整数 int,表示两个或多个整数的最大公约数 (GCD)。

              实例

              以下实例返回数字的最大公约数:

              # 导入 math 包import math# 输出最大公约数print (math.gcd(3, 6))print (math.gcd(6, 12))print (math.gcd(12, 36))print (math.gcd(-12, -36))print (math.gcd(5, 12))print (math.gcd(10, 0))print (math.gcd(0, 34))print (math.gcd(0, 0))

              输出结果:

              361212110340


              Python math 模块 Python math 模块

              Python math.gamma(x) 方法返回 x 处的伽玛函数(Gamma 函数)。

              伽玛函数,也叫欧拉第二积分,是阶乘函数在实数与复数上扩展的一类函数。

              要查找数字的对数伽玛值,请使用 math.lgamma() 方法。

              Python 版本: 3.2

              语法

              math.gamma() 方法语法如下:

              math.gamma(x)

              参数说明:

              • x -- 必需,数字。如果数字是负整数,则返回 ValueError。 如果不是数字,则返回 TypeError。

              返回值

              一个浮点值,表示表示 x 处的伽玛函数。

              实例

              以下实例计算不同数的伽玛函数:

              # 导入 math 包import math# 计算不同数的伽玛函数print(math.gamma(-0.1))print(math.gamma(8))print(math.gamma(1.2))print(math.gamma(80))print(math.gamma(-0.55))

              输出结果:

              -10.6862870211931935040.00.91816874239976048.946182130782976e+116-3.578429819277059


              Python math 模块 Python math 模块

              Python math.frexp(x) 方法以 (m, e) 对的形式返回 x 的尾数和指数。

              该方法的数学公式为: number = m * 2**e。

              Python 版本:2.6

              语法

              math.frexp() 方法语法如下:

              math.frexp(x)

              参数说明:

              • x -- 必需,正数或负数。如果 x 不是一个数字,返回 TypeError。

              返回值

              一个元组,以 (m, e) 对的形式返回 x 的尾数和指数。

              实例

              以下实例计算一个数的尾数和指数:

              # 导入 math 包import math# 返回数字的尾数和指数print(math.frexp(4))print(math.frexp(-4))print(math.frexp(7))

              输出结果:

              (0.5, 3)(-0.5, 3)(0.875, 3)


              Python math 模块 Python math 模块

              Python math.isclose() 方法返回用于检查两个值是否彼此接近,如果值接近,则返回 True,否则返回 False。

              math.isclose() 根据给定的绝对和相对容差确定两个值是否被认为是接近的。

              Python 版本:3.5

              计算公式为:

              abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)

              语法

              math.isclose() 方法语法如下:

              math.isclose(a, b, *, rel_tol=1e-09, abs_tol=0.0)

              参数说明:

              • a -- 必需,数字。如果 x 不是一个数字,返回 TypeError。如果值为 0 或负数,则返回 ValueError。
              • b -- 必需,数字。如果 x 不是一个数字,返回 TypeError。如果值为 0 或负数,则返回 ValueError。
              • rel_tol -- 是相对容差,它是 a 和 b 之间允许的最大差值,相对于 a 或 b 的较大绝对值。例如,要设置5%的容差,请传递 rel_tol=0.05 。默认容差为 1e-09,确保两个值在大约9位十进制数字内相同。 rel_tol 必须大于零。
              • abs_tol -- 是最小绝对容差,对于接近零的比较很有用。 abs_tol 必须至少为零。

              返回值

              返回一个布尔值,检查两个值是否彼此接近,如果值接近,则返回 True,否则返回 False。

              实例

              以下实例检查两个值是否彼此接近:

              # 导入 math 包import math# 输出两个值是否接近print(math.isclose(8.005, 8.450, abs_tol = 0.4))print(math.isclose(8.005, 8.450, abs_tol = 0.5))

              输出结果:

              FalseTrue

              以下实例检查两个浮点数是否接近:

              # 导入 math 包import math# 可用于浮点数判断# 这样会输出 false,0.1+0.2 不会等于 0.3print(0.1+0.2 == 0.3)print(0.1+0.2 )# 这样会输出 trueprint(math.isclose(0.1+0.2, 0.3))

              输出结果:

              False0.30000000000000004True


              Python math 模块 Python math 模块

              Python math.fsum(iterable) 方法计算可迭代对象 (元组, 数组, 列表, 等)中的元素的总和。

              Python 版本:2.6

              语法

              math.fsum() 方法语法如下:

              math.fsum(iterable)

              参数说明:

              • iterable -- 必需,可迭代对象,可以是列表、元组、数组。如果可迭代对象元素不是数字,返回 TypeError。

              返回值

              一个浮点值,表示可迭代对象中所有元素的总和。

              实例

              以下实例计算所有元素的总和:

              # 导入 math 包import math# 计算所有元素的总和print(math.fsum([1, 2, 3, 4, 5]))print(math.fsum([100, 400, 340, 500]))print(math.fsum([1.7, 0.3, 1.5, 4.5]))

              输出结果:

              15.01340.08.0


              Python math 模块 Python math 模块

              Python math.fmod(x, y) 方法返回 x/y 的余数。

              Python 版本:2.7

              语法

              math.fmod() 方法语法如下:

              math.fmod(x, y)

              参数说明:

              • x -- 必需,正数或负数。被除数。如果 x 不是一个数字,返回 TypeError。
              • y -- 必需,正数或负数。除数。如果 y 不是一个数字,返回 TypeError。

              注意:如果 x 和 y = 0,则返回 ValueError。

              注意:如果 y = 0,则返回 ValueError。

              注意:如果 x 或 y 不是数字,则返回 TypeError。

              返回值

              一个浮点值,表示 x/y 的余数

              实例

              以下实例计算余数:

              # 导入 math 包import math# 计算余数print(math.fmod(20, 4))print(math.fmod(20, 3))print(math.fmod(15, 6))print(math.fmod(-10, 3))# 报错,ValueError: math domain errorprint(math.fmod(0, 0))

              输出结果:

              0.02.03.0-1.0Traceback (most recent call last):    File "/Users/RUNOOB/runoob-test/test.py", line 9, in <module>    print(math.fmod(0, 0))ValueError: math domain error


              Python math 模块 Python math 模块

              Python math.fabs(x) 方法返回 x 的绝对值。

              绝对值是非负数,有负号会删除。

              与 Python 内置的 abs() 不同,此方法始终将值转换为浮点值。

              语法

              math.fabs() 方法语法如下:

              math.fabs(x)

              参数说明:

              • x -- 必需,数字。如果 x 不是一个数字,返回 TypeError。

              返回值

              返回一个浮点数,表示 x 的绝对值。

              实例

              以下实例返回数字的绝对值:

              # 导入 math 包import math# 输出绝对值print(math.fabs(2.77))print(math.fabs(8.32))print(math.fabs(-99.29))

              输出结果:

              2.778.3299.29


              Python math 模块 Python math 模块

              Python math.erfc(x) 方法返回 x 处的互补误差函数。

              math.erfc(x) 方法接受 - inf 和 + inf 之间的值,并返回 - 1 到 + 1 之间的值。

              Python 版本: 3.2

              语法

              math.erfc() 方法语法如下:

              math.erfc(x)

              参数说明:

              • x -- 必需,数字。如果 x 不是一个数字,返回 TypeError。

              返回值

              一个浮点值,代表一个数字互补的误差函数。

              实例

              以下实例数字的互补误差函数:

              # 导入 math 包import math# 输出不同数字的互补误差函数print (math.erfc(0.67))print (math.erfc(1.34))print (math.erfc(-6))

              输出结果:

              0.343372297699694960.058086284741634662.0


              Python math 模块 Python math 模块

              Python math.erf(x) 方法返回一个数的误差函数

              math.erf(x) 方法接受 - inf 和 + inf 之间的值,并返回 - 1 到 + 1 之间的值。

              Python 版本:3.2

              语法

              math.erf() 方法语法如下:

              math.erf(x)

              参数说明:

              • x -- 必需,数字。如果 x 不是一个数字,返回 TypeError。

              返回值

              一个浮点值,代表一个数字的误差函数。

              实例

              以下实例计算相同正负数的误差函数:

              # 导入 math 包import math# 输出误差函数print (math.erf(1.28))print (math.erf(-1.28))

              输出结果:

              0.9297341930135782-0.9297341930135782


              Python math 模块 Python math 模块

              Python math.dist(p, q) 方法返回 p 与 q 两点之间的欧几里得距离,以一个坐标序列(或可迭代对象)的形式给出。 两个点必须具有相同的维度。

              传入的参数必须是正整数。

              Python 版本:3.8

              语法

              math.dist() 方法语法如下:

              math.dist(p, q)

              参数说明:

              • p -- 必需,指定第一个点。
              • q -- 必需,指定第二个点。

              返回值

              返回一个浮点值,表示 p 和 q 之间的欧几里得距离。

              实例

              以下实例返回两个点的欧几里得距离:

              # 导入 math 包import mathp = [3]q = [1]# 计算欧几里得距离print (math.dist(p, q))p = [3, 3]q = [6, 12]# 计算欧几里得距离print (math.dist(p, q))

              输出结果:

              2.09.486832980505138


              Python math 模块 Python math 模块

              Python math.factorial(x) 方法返回 x 的阶乘。

              参数只能是正整数。

              一个数字的阶乘是所有整数的乘积之和,例如,6 的阶乘是: 6 x 5 x 4 x 3 x 2 x 1 = 720。

              语法

              math.factorial() 方法语法如下:

              math.factorial(x)

              参数说明:

              • x -- 必需,正整数。如果数字为负数或不是整数,则返回 ValueError。 如果值不是数字,则返回 TypeError。

              返回值

              返回一个正整数,表示正整数的阶乘。

              实例

              以下实例返回正整数的阶乘:

              # 导入 math 包import math# 输出正整数的阶乘print(math.factorial(9))print(math.factorial(6))print(math.factorial(12))

              输出结果:

              362880720479001600


              Python math 模块 Python math 模块

              Python math.expm1(x) 方法返回 e 的 x 次幂(次方)减 1,Ex - 1,其中 e = 2.718281... 是自然对数的基数。

              math.expm1(x) 方法比调用 math.exp() 减去 1 更精确。

              Python 版本:2.7

              语法

              math.expm1() 方法语法如下:

              math.expm1(x)

              参数说明:

              • x -- 必需,数字,指定指数。如果 x 不是一个数字,返回 TypeError。

              返回值

              一个浮点值,表示 Ex - 1。

              实例

              以下实例指定不同的指数:

              # 导入 math 包import math# 指定不同的指数print(math.expm1(32))print(math.expm1(-10.89))

              输出结果:

              78962960182679.69-0.9999813562576685


              Python math 模块 Python math 模块

              Python math.exp(x) 方法返回 e 的 x 次幂(次方)Ex,其中 e = 2.718281... 是自然对数的基数。

              Python 版本:1.6.1

              语法

              math.exp() 方法语法如下:

              math.exp(x)

              参数说明:

              • x -- 必需,数字,指定指数。如果 x 不是一个数字,返回 TypeError。

              返回值

              一个浮点值,表示 e 的 x 次幂。

              实例

              以下实例指定不同的指数:

              # 导入 math 包import math# 指定不同的指数print(math.exp(65))print(math.exp(-6.89))

              输出结果:

              1.6948892444103338e+280.0010179138409954387


              Python math 模块 Python math 模块

              Python math.degrees(x) 方法将角度 x 从弧度转换为度数。

              PI (3.14..) 弧度等于 180 度,也就是说 1 弧度等于 57.2957795 度。

              math.radians() 方法将度数值转换为弧度。

              Python 版本: 2.3

              语法

              math.degrees() 方法语法如下:

              math.degrees(x)

              参数说明:

              • x -- 必需,数字。如果 x 不是一个数字,返回 TypeError。

              返回值

              返回一个浮点数,表示角度。

              实例

              以下实例返回不同弧度转换为度数:

              # 导入 math 包import math# 输出弧度转换为度数print (math.degrees(8.90))print (math.degrees(-20))print (math.degrees(1))print (math.degrees(90))

              输出结果:

              509.9324376664327-1145.915590261646557.295779513082325156.620156177409


              Python math 模块 Python math 模块

              Python math.radians(x) 方法将角度 x 从度数转换为弧度。

              math.degrees() 方法将弧度值转换为度数。

              Python 版本: 2.0

              语法

              math.radians() 方法语法如下:

              math.radians(x)

              参数说明:

              • x -- 必需,数字。如果 x 不是一个数字,返回 TypeError。

              返回值

              返回一个浮点数,表示弧度值。

              实例

              以下实例返回不同度数转换为弧度:

              # 导入 math 包import math# 输出度数转换为弧度print(math.radians(180))print(math.radians(100.03))print(math.radians(-20))

              输出结果:

              3.1415926535897931.7458528507699278-0.3490658503988659


              Python math 模块 Python math 模块

              Python math.cosh(x) 返回 x 的双曲余弦值,相当于 (exp(number) + exp(-number)) / 2。

              Python 版本: 1.4

              语法

              math.cosh() 方法语法如下:

              math.cosh(x)

              参数说明:

              • x -- 必需,个正数或负数。如果 x 不是一个数字,返回 TypeError。

              返回值

              返回一个浮点数,表示一个数字的双曲余弦值。

              实例

              以下实例返回不同数字的双曲余弦值:

              # 导入 math 包import math# 输出双曲余弦值print (math.cosh(1))print (math.cosh(8.90))print (math.cosh(0))print (math.cosh(1.52))

              输出结果:

              1.54308063481524373665.9868377724611.02.395468541047187


              Python math 模块 Python math 模块

              Python math.cos(x) 返回 x 弧度的余弦值。

              Python 版本: 1.4

              语法

              math.cos() 方法语法如下:

              math.cos(x)

              参数说明:

              • x -- 必需,数字。如果 x 不是数字,则返回 TypeError。

              返回值

              返回一个浮点数,表示 x 的余弦值,介于 -1 到 1 之间。

              实例

              以下实例返回数字的余弦值:

              # 导入 math 包import math# 输出余弦值print (math.cos(0.00))print (math.cos(-1.23))print (math.cos(10))print (math.cos(3.14159265359))

              输出结果:

              1.00.3342377271245026-0.8390715290764524-1.0


              Python math 模块 Python math 模块

              Python math.copysign(x,y) 方法返回一个基于 x 的绝对值和 y 的符号 +/- 的浮点数。

              Python 版本:2.6

              语法

              math.copysign() 方法语法如下:

              math.copysign(x, y)

              参数说明:

              • x -- 必需,数字。
              • y -- 必需,数字,返回将值具有该参数的符号 +/-。

              返回值

              返回一个浮点值,由第一个参数的值和第二个参数的符号组成。

              实例

              以下实例返回第一个参数的值和第二个参数的符号:

              # 导入 math 包import math# 返回第一个参数的值和第二个参数的符号print(math.copysign(4, -1))print(math.copysign(-8, 97.21))print(math.copysign(-43, -76))

              输出结果:

              -4.08.0-43.0


              Python math 模块 Python math 模块

              Python math.comb(x) 方法返回不重复且无顺序地从 n 项中选择 k 项的方式总数。

              传入的参数必须是正整数。

              Python 版本:3.8

              语法

              math.comb() 方法语法如下:

              math.comb(n, k)

              参数说明:

              • n -- 必需,正整数数字。
              • k -- 必需,正整数数字。

              返回值

              返回一个整数,代表组合的总数。

              实例

              以下实例返回从 5 项中选择 7 项的方式总数:

              # 导入 math 包import math# 初始化可供选择的项数n = 7# 始化可供选择的可能性数量k = 5# 打印可能组合的总数print (math.comb(n, k))

              输出结果:

              21


              Python math 模块 Python math 模块

              Python math.ceil(x) 方法将 x 向上舍入到最接近的整数。

              math.floor() 方法将数字向下舍入到最接近的整数。

              语法

              math.ceil() 方法语法如下:

              math.ceil(x)

              参数说明:

              • x -- 必需,数字。如果 x 不是一个数字,返回 TypeError。

              返回值

              返回一个整数,表示舍入的数字。

              实例

              以下实例返回向上舍入到最接近的整数:

              # 导入 math 包import math# 输出向上舍入到最接近的整数print(math.ceil(1.4))print(math.ceil(5.3))print(math.ceil(-5.3))print(math.ceil(22.6))print(math.ceil(10.0))

              输出结果:

              26-52310


              Python math 模块 Python math 模块

              Python math.floor(x) 方法将 x 向下舍入到最接近的整数。

              math.ceil() 方法将数字向上舍入到最接近的整数。

              语法

              math.floor() 方法语法如下:

              math.floor(x)

              参数说明:

              • x -- 必需,数字。如果 x 不是一个数字,返回 TypeError。

              返回值

              返回一个整数 int,表示向下舍入的数字。

              实例

              以下实例返回向下舍入到最接近的整数:

              # 导入 math 包import math# 输出向下舍入到最接近的整数print(math.floor(0.6))print(math.floor(1.4))print(math.floor(5.3))print(math.floor(-5.3))print(math.floor(22.6))print(math.floor(10.0))

              输出结果:

              015-62210


              Python math 模块 Python math 模块

              Python math.atanh(x) 返回 x 的反双曲正切值。

              math.atanh(x) 的参数介于 -0.99 到 0.99 之间。

              Python 版本: 2.6

              语法

              math.atanh() 方法语法如下:

              math.atanh(x)

              参数说明:

              • x -- 必需,介于 -0.99 和 0.99 之间的正数或负数。 如果 x 不是数字,则返回 TypeError.

              返回值

              返回一个浮点数,表示 x 的反双曲正切值。

              实例

              以下实例返回数字的双曲正切值:

              # 导入 math 包import math# 输出双曲正切值print(math.atanh(0.59))print(math.atanh(-0.12))

              输出结果:

              0.6776660677579618-0.12058102840844402


              Python math 模块 Python math 模块

              Python math.atan2(y,x) 返回给定的 y 及 x 坐标值的反正切值 atan(y / x),以弧度为单位,结果是在 -pi 和 pi 之间。

              Python 版本:1.4

              语法

              math.atan2() 方法语法如下:

              math.atan2(y, x)

              参数说明:

              • x -- 必需,个正数或负数。
              • y -- 必需,个正数或负数。

              返回值

              返回一个浮点数,表示y 及 x 坐标值的反正切值,结果是在 -pi 和 pi 之间。

              实例

              以下实例返回 y/x 的反正切:

              # 导入 math 包import math# 输出 y/x 反正切值print(math.atan2(8, 5))print(math.atan2(20, 10))print(math.atan2(34, -7))

              输出结果:

              1.01219701145133411.10714871779409041.7738415440483617


              Python math 模块 Python math 模块

              Python math.atan(x) 返回 x 的反正切值,以弧度为单位,结果范围在 -pi/2 到 pi/2 之间。

              Python 版本: 1.6.1

              语法

              math.atan() 方法语法如下:

              math.atan(x)

              参数说明:

              • x -- 必需,个正数或负数。如果 x 不是一个数字,返回 TypeError。

              返回值

              返回一个浮点数,表示一个数字的反正切值,范围在 -pi/2 到 pi/2 之间。

              实例

              以下实例返回不同数字的反正切:

              # 导入 math 包import math# 输出反正切值print (math.atan(0.39))print (math.atan(67))print (math.atan(-21))

              输出结果:

              0.371856073848581271.5558720618048116-1.5232132235179132


              Python math 模块 Python math 模块

              Python math.asinh(x) 返回 x 的反双曲正弦值。

              Python 版本: 2.6

              语法

              math.asinh() 方法语法如下:

              math.asinh(x)

              参数说明:

              • x -- 必需,个正数或负数。如果 x 不是一个数字,返回 TypeError。

              返回值

              返回一个浮点数,表示一个数字的反双曲正弦值。

              实例

              以下实例返回不同数字的反双曲正弦:

              # 导入 math 包import math# 输出反双曲正弦值print(math.asinh(7))print(math.asinh(56))print(math.asinh(2.45))print(math.asinh(1))

              输出结果:

              2.6441207610586294.7185785811517671.62849981928419090.881373587019543


              Python math 模块 Python math 模块

              Python math.acos(x) 返回 x 的反余弦,结果范围在 0 到 pi 之间。

              math.acos() 接收的参数为 -1 到 1。

              math.acos(-1) 返回 math.pi 常量。

              Python 版本: 1.4

              语法

              math.acos() 方法语法如下:

              math.acos(x)

              参数说明:

              • x -- 必需,一个数字, -1 到 1 之间。如果 x 不是一个数字,返回 TypeError。

              返回值

              返回一个浮点数,表示一个数字的反余弦。

              实例

              以下实例返回指定数字的反余弦:

              # 导入 math 包import math# 输出反余弦值print(math.acos(0.55))print(math.acos(-0.55))print(math.acos(0))print(math.acos(1))print(math.acos(-1))

              输出结果:

              0.98843208892615312.153160564663641.57079632679489660.03.141592653589793


              Python math 模块 Python math 模块

              Python math.acosh(x) 返回 x 的反双曲余弦值。

              math.acosh() 接收的参数大于等于 1。

              Python 版本: 2.6

              语法

              math.acosh() 方法语法如下:

              math.acosh(x)

              参数说明:

              • x -- 必需,一个数字,大于等于 1。如果 x 不是一个数字,返回 TypeError。

              返回值

              返回一个浮点数,表示一个数字的反双曲余弦值。

              实例

              以下实例返回不同数字的反双曲余弦:

              # 导入 math 包import math# 输出反双曲余弦值print (math.acosh(7))print (math.acosh(56))print (math.acosh(2.45))print (math.acosh(1))

              输出结果:

              2.63391579384963364.7184191423728791.54471311787073940.0


              Python math 模块 Python math 模块

              Python math.asin(x) 返回 x 的反正弦值,结果范围在 -pi/2 到 pi/2 之间。。

              math.asin() 接收的参数为 -1 到 1。

              Python 版本: 1.4

              语法

              math.asin() 方法语法如下:

              math.asin(x)

              参数说明:

              • x -- 必需,一个数字, -1 到 1 之间。如果 x 不是一个数字,返回 TypeError。

              返回值

              返回一个浮点数,表示一个数字的反正弦值。

              实例

              以下实例返回不同数字的反正弦值:

              # 导入 math 包import math# 输出反正弦值print(math.asin(0.55))print(math.asin(-0.55))print(math.asin(0))print(math.asin(1))print(math.asin(-1))

              输出结果:

              0.5823642378687435-0.58236423786874350.01.5707963267948966-1.5707963267948966


              Python math 模块 Python math 模块

              Python math.tau 返回数学常数 τ = 6.283185..., tau 是一个圆周常数,等于 2π,圆的周长与半径之比。

              tau 值为 6.283185307179586。

              语法

              math.tau 常量语法如下:

              math.tau

              返回值

              返回一个浮点数 6.283185307179586,表示圆的周长与半径之比。

              实例

              以下实例返回 tau:

              # 导入 math 包import math# 输出 tauprint (math.tau)

              输出结果:

              6.283185307179586


              Python math 模块 Python math 模块

              Python math.pi 返回一个浮点值 π, 一般指圆周率,圆周率 PI (3.1415...)。

              PI: 3.141592653589793。

              语法

              math.pi 常量语法如下:

              math.pi

              返回值

              返回一个浮点数 3.141592653589793,表示圆周率。

              实例

              以下实例返回 PI:

              # 导入 math 包import math# 输出 PIprint (math.pi)

              输出结果:

              3.141592653589793


              Python math 模块 Python math 模块

              Python math.nan 返回一个浮点值 nan(not a number,不是一个数字),这个值不是一个合法数字。

              math.nan 相当于 float('nan') 的输出。

              语法

              math.nan 常量语法如下:

              math.nan

              返回值

              返回一个浮点数 nan。

              实例

              以下实例返回 nan:

              # 导入 math 包import math# 输出 nanprint (math.nan)# 输出 nan 类型print (type(math.nan))

              输出结果:

              nan<class 'float'>


              Python math 模块 Python math 模块

              Python math.inf 正无穷大的浮点数,负无穷大,使用 -math.inf 。

              math.inf 相当于 float('inf') 的输出。

              语法

              math.inf 常量语法如下:

              math.inf

              返回值

              返回一个浮点数,表示正无穷大。

              实例

              以下实例返回正无穷大与负无穷大:

              # 导入 math 包import math# 输出正无穷大print (math.inf)# 输出负无穷大print (-math.inf)

              输出结果:

              inf-inf


              Python math 模块 Python math 模块

              Python math.e 常量用于返回欧拉数 (2.7182...)。

              语法

              math.e 常量语法如下:

              math.e

              返回值

              返回一个浮点数 2.718281828459045,表示数学常数 e。

              实例

              以下实例返回欧拉数 (2.7182...):

              # 导入 math 包import math# 输出 e 的值print (math.e)

              输出结果:

              2.718281828459045


              Python2.x 版本中,使用 cmp() 函数来比较两个列表、数字或字符串等的大小关系。

              Python 3.X 的版本中已经没有 cmp() 函数,如果你需要实现比较功能,需要引入 operator 模块,适合任何对象,包含的方法有:

              operator.lt(a, b)operator.le(a, b)operator.eq(a, b)operator.ne(a, b)operator.ge(a, b)operator.gt(a, b)operator.__lt__(a, b)operator.__le__(a, b)operator.__eq__(a, b)operator.__ne__(a, b)operator.__ge__(a, b)operator.__gt__(a, b)

              operator.lt(a, b) 与 a < b 相同, operator.le(a, b) 与 a <= b 相同,operator.eq(a, b) 与 a == b 相同,operator.ne(a, b) 与 a != b 相同,operator.gt(a, b) 与 a > b 相同,operator.ge(a, b) 与 a >= b 相同。

              # 导入 operator 模块import operator # 数字x = 10y = 20print("x:",x, ", y:",y)print("operator.lt(x,y): ", operator.lt(x,y))print("operator.gt(y,x): ", operator.gt(y,x))print("operator.eq(x,x): ", operator.eq(x,x))print("operator.ne(y,y): ", operator.ne(y,y))print("operator.le(x,y): ", operator.le(x,y))print("operator.ge(y,x): ", operator.ge(y,x))print()# 字符串x = "Google"y = "w3cschool"print("x:",x, ", y:",y)print("operator.lt(x,y): ", operator.lt(x,y))print("operator.gt(y,x): ", operator.gt(y,x))print("operator.eq(x,x): ", operator.eq(x,x))print("operator.ne(y,y): ", operator.ne(y,y))print("operator.le(x,y): ", operator.le(x,y))print("operator.ge(y,x): ", operator.ge(y,x))print()# 查看返回值print("type((operator.lt(x,y)): ", type(operator.lt(x,y)))

              以上代码输出结果为:

              x: 10 , y: 20operator.lt(x,y):  Trueoperator.gt(y,x):  Trueoperator.eq(x,x):  Trueoperator.ne(y,y):  Falseoperator.le(x,y):  Trueoperator.ge(y,x):  Truex: Google , y: w3cschooloperator.lt(x,y):  Trueoperator.gt(y,x):  Trueoperator.eq(x,x):  Trueoperator.ne(y,y):  Falseoperator.le(x,y):  Trueoperator.ge(y,x):  True

              比较两个列表:

              # 导入 operator 模块import operatora = [1, 2]b = [2, 3]c = [2, 3]print("operator.eq(a,b): ", operator.eq(a,b))print("operator.eq(c,b): ", operator.eq(c,b))

              以上代码输出结果为:

              operator.eq(a,b):  Falseoperator.eq(c,b):  True

              运算符函数

              operator 模块提供了一套与 Python 的内置运算符对应的高效率函数。例如,operator.add(x, y) 与表达式 x+y 相同。

              函数包含的种类有:对象的比较运算、逻辑运算、数学运算以及序列运算。

              对象比较函数适用于所有的对象,函数名根据它们对应的比较运算符命名。

              许多函数名与特殊方法名相同,只是没有双下划线。为了向后兼容性,也保留了许多包含双下划线的函数,为了表述清楚,建议使用没有双下划线的函数。

              # Python 实例# add(), sub(), mul() # 导入  operator 模块import operator # 初始化变量a = 4 b = 3 # 使用 add() 让两个值相加print ("add() 运算结果 :",end="");print (operator.add(a, b)) # 使用 sub() 让两个值相减print ("sub() 运算结果 :",end="");print (operator.sub(a, b)) # 使用 mul() 让两个值相乘print ("mul() 运算结果 :",end="");print (operator.mul(a, b))

              以上代码输出结果为:

              add() 运算结果 :7sub() 运算结果 :1mul() 运算结果 :12

              运算

              语法

              函数

              加法

              a + b

              add(a, b)

              字符串拼接

              seq1 + seq2

              concat(seq1, seq2)

              包含测试

              obj in seq

              contains(seq, obj)

              除法

              a / b

              truediv(a, b)

              除法

              a // b

              floordiv(a, b)

              按位与

              a & b

              and_(a, b)

              按位异或

              a ^ b

              xor(a, b)

              按位取反

              ~ a

              invert(a)

              按位或

              a | b

              or_(a, b)

              取幂

              a ** b

              pow(a, b)

              标识

              a is b

              is_(a, b)

              标识

              a is not b

              is_not(a, b)

              索引赋值

              obj[k] = v

              setitem(obj, k, v)

              索引删除

              del obj[k]

              delitem(obj, k)

              索引取值

              obj[k]

              getitem(obj, k)

              左移

              a << b

              lshift(a, b)

              取模

              a % b

              mod(a, b)

              乘法

              a * b

              mul(a, b)

              矩阵乘法

              a @ b

              matmul(a, b)

              取反(算术)

              - a

              neg(a)

              取反(逻辑)

              not a

              not_(a)

              正数

              + a

              pos(a)

              右移

              a >> b

              rshift(a, b)

              切片赋值

              seq[i:j] = values

              setitem(seq, slice(i, j), values)

              切片删除

              del seq[i:j]

              delitem(seq, slice(i, j))

              切片取值

              seq[i:j]

              getitem(seq, slice(i, j))

              字符串格式化

              s % obj

              mod(s, obj)

              减法

              a - b

              sub(a, b)

              真值测试

              obj

              truth(obj)

              比较

              a < b

              lt(a, b)

              比较

              a <= b

              le(a, b)

              相等

              a == b

              eq(a, b)

              不等

              a != b

              ne(a, b)

              比较

              a >= b

              ge(a, b)

              比较

              a > b

              gt(a, b)


              pip 是 Python 包管理工具,该工具提供了对 Python 包的查找、下载、安装、卸载的功能。

              软件包也可以在 https://pypi.org/ 中找到。

              目前最新的 Python 版本已经预装了 pip。

              查看是否已经安装 pip 可以使用以下命令:

              pip --version

              下载安装包使用以下命令:

              pip install some-package-name

              例如我们安装 numpy 包:

              pip install numpy

              我们也可以轻易地通过以下的命令来移除软件包:

              pip uninstall some-package-name

              例如我们移除 numpy 包:

              pip uninstall numpy

              如果要查看我们已经安装的软件包,可以使用以下命令:

              pip list


              MongoDB 是目前最流行的 NoSQL 数据库之一,使用的数据类型 BSON(类似 JSON)。

              MongoDB 数据库安装与介绍可以查看我们的 MongoDB 教程。

              PyMongo

              Python 要连接 MongoDB 需要 MongoDB 驱动,这里我们使用 PyMongo 驱动来连接。

              pip 安装

              pip 是一个通用的 Python 包管理工具,提供了对 Python 包的查找、下载、安装、卸载的功能。

              安装 pymongo:

              $ python3 -m pip3 install pymongo

              也可以指定安装的版本:

              $ python3 -m pip3 install pymongo==3.5.1

              更新 pymongo 命令:

              $ python3 -m pip3 install --upgrade pymongo

              easy_install 安装

              旧版的 Python 可以使用 easy_install 来安装,easy_install 也是 Python 包管理工具。

              $ python -m easy_install pymongo

              更新 pymongo 命令:

              $ python -m easy_install -U pymongo

              测试 PyMongo

              接下来我们可以创建一个测试文件 demo_test_mongodb.py,代码如下:

              demo_test_mongodb.py 文件代码:

              #!/usr/bin/python3 import pymongo

              执行以上代码文件,如果没有出现错误,表示安装成功。

              创建数据库

              创建一个数据库

              创建数据库需要使用 MongoClient 对象,并且指定连接的 URL 地址和要创建的数据库名。

              如下实例中,我们创建的数据库 w3cschool :

              实例

              #!/usr/bin/python3 import pymongo myclient = pymongo.MongoClient("mongodb://localhost:27017/")mydb = myclient["w3cschool"]
              注意: 在 MongoDB 中,数据库只有在内容插入后才会创建! 就是说,数据库创建后要创建集合(数据表)并插入一个文档(记录),数据库才会真正创建。

              判断数据库是否已存在

              我们可以读取 MongoDB 中的所有数据库,并判断指定的数据库是否存在:

              实例

              #!/usr/bin/python3 import pymongo myclient = pymongo.MongoClient('mongodb://localhost:27017/') dblist = myclient.list_database_names()# dblist = myclient.database_names() if "w3cschool" in dblist:  print("数据库已存在!")
              注意:database_names 在最新版本的 Python 中已废弃,Python3.7+ 之后的版本改为了 list_database_names()。

              创建集合

              MongoDB 中的集合类似 SQL 的表。

              创建一个集合

              MongoDB 使用数据库对象来创建集合,实例如下:

              实例

              #!/usr/bin/python3 import pymongo myclient = pymongo.MongoClient("mongodb://localhost:27017/")mydb = myclient["w3cschool"] mycol = mydb["sites"]
              注意: 在 MongoDB 中,集合只有在内容插入后才会创建! 就是说,创建集合(数据表)后要再插入一个文档(记录),集合才会真正创建。

              判断集合是否已存在

              我们可以读取 MongoDB 数据库中的所有集合,并判断指定的集合是否存在:

              实例

              #!/usr/bin/python3 import pymongo myclient = pymongo.MongoClient('mongodb://localhost:27017/') mydb = myclient['w3cschool'] collist = mydb. list_collection_names()# collist = mydb.collection_names()if "sites" in collist:   # 判断 sites 集合是否存在  print("集合已存在!")
              注意:collection_names 在最新版本的 Python 中已废弃,Python3.7+ 之后的版本改为了 list_collection_names()。

              增、删、改、查等操作

              下表列出了 MongoDB 的更多操作,详情可点击具体链接:

              序号功能
              1添加数据
              2查询数据
              3修改数据
              4数据排序
              5删除数据


              Python random 模块主要用于生成随机数。

              random 模块实现了各种分布的伪随机数生成器。

              要使用 random 函数必须先导入:

              import random

              查看 random 模块中的内容:

              >>> import random>>> dir(random)['BPF', 'LOG4', 'NV_MAGICCONST', 'RECIP_BPF', 'Random', 'SG_MAGICCONST', 'SystemRandom', 'TWOPI', '_Sequence', '_Set', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_accumulate', '_acos', '_bisect', '_ceil', '_cos', '_e', '_exp', '_floor', '_inst', '_log', '_os', '_pi', '_random', '_repeat', '_sha512', '_sin', '_sqrt', '_test', '_test_generator', '_urandom', '_warn', 'betavariate', 'choice', 'choices', 'expovariate', 'gammavariate', 'gauss', 'getrandbits', 'getstate', 'lognormvariate', 'normalvariate', 'paretovariate', 'randbytes', 'randint', 'random', 'randrange', 'sample', 'seed', 'setstate', 'shuffle', 'triangular', 'uniform', 'vonmisesvariate', 'weibullvariate']

              接下来我们使用 random() 方法返回一个随机数,它在 [0,1) 范围内,包含 0 但不包含 1。

              # 导入 random 包import random# 生成随机数print(random.random())

              以上实例输出结果为:

              0.4784904215869241

              seed() 方法改变随机数生成器的种子,可以在调用其他随机模块函数之前调用此函数。

              #!/usr/bin/python3import randomrandom.seed()print ("使用默认种子生成随机数:", random.random())print ("使用默认种子生成随机数:", random.random())random.seed(10)print ("使用整数 10 种子生成随机数:", random.random())random.seed(10)print ("使用整数 10 种子生成随机数:", random.random())random.seed("hello",2)print ("使用字符串种子生成随机数:", random.random())

              以上实例运行后输出结果为:

              使用默认种子生成随机数: 0.7908102856355441使用默认种子生成随机数: 0.81038961519195使用整数 10 种子生成随机数: 0.5714025946899135使用整数 10 种子生成随机数: 0.5714025946899135使用字符串种子生成随机数: 0.3537754404730722

              random 模块方法

              random 模块方法如下:

              方法描述
              seed()初始化随机数生成器
              getstate()返回捕获生成器当前内部状态的对象。
              setstate()state 应该是从之前调用 getstate() 获得的,并且 setstate() 将生成器的内部状态恢复到 getstate() 被调用时的状态。
              getrandbits(k)返回具有 k 个随机比特位的非负 Python 整数。 此方法随 MersenneTwister 生成器一起提供,其他一些生成器也可能将其作为 API 的可选部分提供。 在可能的情况下,getrandbits() 会启用 randrange() 来处理任意大的区间。
              randrange()从 range(start, stop, step) 返回一个随机选择的元素。
              randint(a, b) 返回随机整数 N 满足 a <= N <= b。
              choice(seq) 从非空序列 seq 返回一个随机元素。 如果 seq 为空,则引发 IndexError。
              choices(population, weights=None, *, cum_weights=None, k=1)从 population 中选择替换,返回大小为 k 的元素列表。 如果 population 为空,则引发 IndexError。
              shuffle(x[, random]) 将序列 x 随机打乱位置。
              sample(population, k, *, counts=None)返回从总体序列或集合中选择的唯一元素的 k 长度列表。 用于无重复的随机抽样。
              random() 返回 [0.0, 1.0) 范围内的下一个随机浮点数。
              uniform() 返回一个随机浮点数 N ,当 a <= b 时 a <= N <= b ,当 b < a 时 b <= N <= a 。
              triangular(low, high, mode)返回一个随机浮点数 N ,使得 low <= N <= high 并在这些边界之间使用指定的 mode 。 low 和 high 边界默认为零和一。 mode 参数默认为边界之间的中点,给出对称分布。
              betavariate(alpha, beta)Beta 分布。 参数的条件是 alpha > 0 和 beta > 0。 返回值的范围介于 0 和 1 之间。
              expovariate(lambd)指数分布。 lambd 是 1.0 除以所需的平均值,它应该是非零的。
              gammavariate()Gamma 分布( 不是伽马函数) 参数的条件是 alpha > 0 和 beta > 0。
              gauss(mu, sigma)正态分布,也称高斯分布。 mu 为平均值,而 sigma 为标准差。 此函数要稍快于下面所定义的 normalvariate() 函数。
              lognormvariate(mu, sigma)对数正态分布。 如果你采用这个分布的自然对数,你将得到一个正态分布,平均值为 mu 和标准差为 sigma 。 mu 可以是任何值,sigma 必须大于零。
              normalvariate(mu, sigma)正态分布。 mu 是平均值,sigma 是标准差。
              vonmisesvariate(mu, kappa)冯·米塞斯分布。 mu 是平均角度,以弧度表示,介于0和 2*pi 之间,kappa 是浓度参数,必须大于或等于零。 如果 kappa 等于零,则该分布在 0 到 2*pi 的范围内减小到均匀的随机角度。
              paretovariate(alpha)帕累托分布。 alpha 是形状参数。
              weibullvariate(alpha, beta)威布尔分布。 alpha 是比例参数,beta 是形状参数。


              Python random 模块 Python random 模块

              Python random.randint() 方法返回指定范围内的整数。

              randint(start, stop) 等价于 randrange(start, stop+1)

              语法

              random.randint() 方法语法如下:

              random.randint(start, stop)

              参数说明:

              • start -- 必需, 一个整数,指定开始值。
              • stop -- 必需, 一个整数,指定结束值。

              返回值

              返回指定范围内的整数。

              实例

              以下实例返回一个 1 到 9 之间的数字(大于等于 1,小于等于 9 ):

              # 导入 random 包import random# 返回一个 1 到 9 之间的数字print(random.randint(1, 9))

              输出结果:

              8


              Python 内置了 requests 模块,该模块主要用来发 送 HTTP 请求,requests 模块比 urllib 模块更简洁。

              # 导入 requests 包import requests# 发送请求x = requests.get('https://www.w3cschool.cn/')# 返回网页内容print(x.text)

              每次调用 requests 请求之后,会返回一个 response 对象,该对象包含了具体的响应信息。

              响应信息如下:

              属性或方法说明
              apparent_encoding编码方式
              close()关闭与服务器的连接
              content返回响应的内容,以字节为单位
              cookies返回一个 CookieJar 对象,包含了从服务器发回的 cookie
              elapsed返回一个 timedelta 对象,包含了从发送请求到响应到达之间经过的时间量,可以用于测试响应速度。比如 r.elapsed.microseconds 表示响应到达需要多少微秒。
              encoding解码 r.text 的编码方式
              headers返回响应头,字典格式
              history返回包含请求历史的响应对象列表(url)
              is_permanent_redirect如果响应是永久重定向的 url,则返回 True,否则返回 False
              is_redirect如果响应被重定向,则返回 True,否则返回 False
              iter_content()迭代响应
              iter_lines()迭代响应的行
              json()返回结果的 JSON 对象 (结果需要以 JSON 格式编写的,否则会引发错误)
              links返回响应的解析头链接
              next返回重定向链中下一个请求的 PreparedRequest 对象
              ok检查 "status_code" 的值,如果小于400,则返回 True,如果不小于 400,则返回 False
              raise_for_status()如果发生错误,方法返回一个 HTTPError 对象
              reason响应状态的描述,比如 "Not Found" 或 "OK"
              request返回请求此响应的请求对象
              status_code返回 http 的状态码,比如 404 和 200(200 是 OK,404 是 Not Found)
              text返回响应的内容,unicode 类型数据
              url返回响应的 URL
              # 导入 requests 包import requests# 发送请求x = requests.get('https://www.w3cschool.cn/')# 返回 http 的状态码print(x.status_code)# 响应状态的描述print(x.reason)# 返回编码print(x.apparent_encoding)

              输出结果如下:

              200OKutf-8

              请求 json 数据文件,返回 json 内容:

              # 导入 requests 包import requests# 发送请求x = requests.get('https://www.w3cschool.cn/try/ajax/json_demo.json')# 返回 json 数据print(x.json())

              输出结果如下:

              {'name': '网站', 'num': 3, 'sites': [{'name': 'Google', 'info': ['Android', 'Google 搜索', 'Google 翻译']}, {'name': 'w3cschool', 'info': ['编程狮', '编程狮工具', '编程狮微信']}, {'name': 'Taobao', 'info': ['淘宝', '网购']}]}

              requests 方法

              requests 方法如下表:

              方法描述
              delete(urlargs)发送 DELETE 请求到指定 url
              get(urlparams, args)发送 GET 请求到指定 url
              head(urlargs)发送 HEAD 请求到指定 url
              patch(urldata, args)发送 PATCH 请求到指定 url
              post(urldata, json, args)发送 POST 请求到指定 url
              put(urldata, args)发送 PUT 请求到指定 url
              request(methodurlargs)向指定的 url 发送指定的请求方法

              使用 requests.request() 发送 get 请求:

              # 导入 requests 包import requests# 发送请求x = requests.request('get', 'https://www.w3cschool.cn/')# 返回网页内容print(x.status_code)

              输出结果如下:

              200

              设置请求头:

              # 导入 requests 包import requests kw = {'w':'python 教程'}# 设置请求头headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"} # params 接收一个字典或者字符串的查询参数,字典类型自动转换为url编码,不需要urlencode()response = requests.get("https://www.w3cschool.cn/search/", params = kw, headers = headers)# 查看响应状态码print (response.status_code)# 查看响应头部字符编码print (response.encoding)# 查看完整url地址print (response.url)# 查看响应内容,response.text 返回的是Unicode格式的数据print(response.text)

              输出结果如下:

              200UTF-8https://www.w3cschool.cn/search/?w=python+%E6%95%99%E7%A8%8B... 其他内容...

              post() 方法可以发送 POST 请求到指定 url,一般格式如下:

              requests.post(url, data={key: value}, json={key: value}, args)
              • url 请求 url。
              • data 参数为要发送到指定 url 的字典、元组列表、字节或文件对象。
              • json 参数为要发送到指定 url 的 JSON 对象。
              • args 为其他参数,比如 cookies、headers、verify等。
              # 导入 requests 包import requests# 发送请求x = requests.post('https://www.w3cschool.cn/try/ajax/demo_post.php')# 返回网页内容print(x.text)

              输出结果如下:

              <p style='color:red;'>本内容是使用 POST 方法请求的。</p><p style='color:red;'>请求时间:2022-05-26 17:30:47</p>

              post 请求带参数:

              # 导入 requests 包import requests# 表单参数,参数名为 fname 和 lnamemyobj = {'fname': 'w3cschool','lname': 'Boy'}# 发送请求x = requests.post('https://www.w3cschool.cn/try/ajax/demo_post2.php', data = myobj)# 返回网页内容print(x.text)

              输出结果如下:

              <p style='color:red;'>你好,w3cschool Boy,今天过得怎么样?</p>


              Python 内置函数 Python 内置函数


              描述

              all() ​函数用于判断一个列表中的所有元素是否为真(TRUE)。


              给定的可迭代参数 iterable 中的所有元素是否都为 TRUE,如果是返回 True,否则返回 False。

              元素除了是 0、空、None、False 外都算 True。

               为了便于理解,上述文本中使用了列表作为可迭代对象的替换。实际上这是片面的,all()函数接受的参数为可迭代的对象,也就是说,以下这些类型都可以作为

              1.list,tuple,dict、set、str
              2.generator,带yield的generator function,统称为iterator。生成器可以使用for可以被next函数调用并返回下一个值。

              函数等价于:

              def all(iterable):    for element in iterable:        if not element:            return False    return True


              语法

              以下是 all() 方法的语法:

              all(iterable)

              参数

              • iterable -- 元组或列表。

              返回值

              如果iterable的所有元素不为0、''、False或者iterable为空,all(iterable)返回True,否则返回False;

              注意:空元组、空列表返回值为True,这里要特别注意。

              实例

              以下展示了使用 all() 方法的实例:

              >>> all(['a', 'b', 'c', 'd'])  # 列表list,元素都不为空或0True>>> all(['a', 'b', '', 'd'])   # 列表list,存在一个为空的元素False>>> all([0, 1,2, 3])          # 列表list,存在一个为0的元素False   >>> all(('a', 'b', 'c', 'd'))  # 元组tuple,元素都不为空或0True>>> all(('a', 'b', '', 'd'))   # 元组tuple,存在一个为空的元素False>>> all((0, 1, 2, 3))          # 元组tuple,存在一个为0的元素False   >>> all([])             # 空列表True>>> all(())             # 空元组True

              Python 内置函数 Python 内置函数


              Python3 数字 Python3 数字


              描述

              abs() ​函数接受一个参数,并返回该参数的绝对值。

              注:虽然​abs()​函数是数学运算相关的方法,但是​abs()​函数是python内置函数,不是math模块的函数。

               math模块也有求绝对值的方法(​math.fabs()​)
              二者有所区别:​

              abs()​方法可以接受int,float和复数类型的参数。返回相对应的值(复数返回模)。

              fabs()​方法只能接受int和float类型的参数,返回值为float。


              语法

              以下是 abs() 方法的语法:

              abs(x)

              参数

              • x -- 可以是整数、浮点数、复数或任何实现了 __abs__() 的对象。

              返回值

              函数返回 x(数字)的绝对值,如果参数是一个复数,则返回它的模。

              实例

              以下展示了使用​ abs()​ 方法的实例:

              #!/usr/bin/python3x = -40 #定义一个int类型的变量print(type(x)) #查看x是不是int类型x =abs(x) # 求x的绝对值print(x) # x的绝对值print(type(x)) # 查看int类型的变量求完绝对值后是什么类型y =-12.5 #定义一个float类型的变量print(type(y)) # 查看y是不是float类型x =abs(y) # 求y的绝对值print(y) # y的绝对值print(type(y)) #查看float类型的变量求完绝对值后是什么类型z = -101 - 0.3j  # 定义一个complex(复数)类型的变量print(type(z)) # 查看z是不是complex类型x =abs(z) # 求z的绝对值print(z) #  z的绝对值print(type(z)) # 查看complex类型的变量求完绝对值后是什么类型

              以上实例运行后输出结果为:

              <class 'int'>

              40

              <class 'int'>

              <class 'float'>

              -12.5

              <class 'float'>

              <class 'complex'>

              (-101-0.3j)

              <class 'complex'>


              Python3 数字 Python3 数字


              Python3 数字Python3 数字


              描述

              randrange() ​方法返回指定递增基数集合中的一个随机数,基数缺省值为1。


              语法

              以下是 randrange() 方法的语法:

              import randomrandom.randrange ([start,] stop [,step])

              注意:randrange()是不能直接访问的,需要导入 random 模块,然后通过 random 静态对象调用该方法。


              参数

              • start -- 指定范围内的开始值,包含在范围内。
              • stop -- 指定范围内的结束值,不包含在范围内。
              • step -- 指定递增基数。

              返回值

              从给定的范围返回随机项。


              实例

              以下展示了使用 randrange() 方法的实例:

              #!/usr/bin/python3import random# 从 1-100 中选取一个奇数print ("randrange(1,100, 2) : ", random.randrange(1, 100, 2))# 从 0-99 选取一个随机数print ("randrange(100) : ", random.randrange(100))

              以上实例运行后输出结果为:

              randrange(1,100, 2) :  97randrange(100) :  42

              Python3 数字Python3 数字


              Python3 数字Python3 数字


              描述

              ceil(x) 函数返回一个大于或等于 x 的的最小整数。


              语法

              以下是 ceil() 方法的语法:

              import mathmath.ceil( x )

              注意:ceil()​是不能直接访问的,需要导入 math 模块,通过静态对象调用该方法。


              参数

              x -- 数值表达式。


              返回值

              函数返回返回一个大于或等于 x 的的最小整数。


              实例

              以下展示了使用 ceil() 方法的实例:

              #!/usr/bin/python3import math   # 导入 math 模块print ("math.ceil(-45.17) : ", math.ceil(-45.17))print ("math.ceil(100.12) : ", math.ceil(100.12))print ("math.ceil(100.72) : ", math.ceil(100.72))print ("math.ceil(math.pi) : ", math.ceil(math.pi))

              以上实例运行后输出结果为:

              math.ceil(-45.17) :  -45math.ceil(100.12) :  101math.ceil(100.72) :  101math.ceil(math.pi) :  4

              Python3 数字Python3 数字


              Python 内置函数 Python 内置函数


              描述

              Python​ iter() ​函数用来生成迭代器。

              有些对象(尤其是自定义的对象)可以像数组一样读出数据,但本身不是可迭代对象,这个时候就可以使用iter()将其转换成可迭代对象。

               在类中实现了如果只实现​__getitem__()​的对象可以通过​iter()​函数转化成迭代器但其本身不是可迭代对象。所以当一个对象能够在for循环中运行时,不能确定是Iterable对象。 


              语法

              iter()​ 方法的语法有两种,分别是:

              iter(object)

              iter(object, sentinel)

              sentinel参数用于指示迭代的停止条件。


              参数

              • object:支持迭代的集合对象(在不传入sentinel参数时)或者可调用的对象(第二种情况)。
              • sentinel:如果传递了第二个参数,则参数 object 必须是一个可调用的对象(如,函数),此时,iter 创建了一个迭代器对象,每次调用这个迭代器对象的​__next__()​方法时,都会调用 object。

              返回值

              迭代器对象。


              实例

              from typing import Iterableclass LinearDataStructure:    # 一个自己实现的线性表,未传参时默认为1,2,3        def __init__(self, data=[1, 2, 3]):        self.data = data    def get_data(self):        return self.data        def __getitem__(self,idx):        return(self.data[idx])    # 第一种语法lds = LinearDataStructure()print(isinstance(lds,Iterable))  # 这个线性表不是可迭代对象print(isinstance(iter(lds),Iterable)) # 使用iter方法可以把这个线性表变成可迭代对象# 第二种语法def read_until(f, stop):    return iter(lambda: f.readline().strip(), stop)with open('file.txt') as f:    for line in read_until(f, ''):        print(line)



              Python 内置函数 Python 内置函数



              我们知道,​type()​函数是python的内置函数,可以用来查看变量的类型,它是小编最常用的一个函数。小编之所以如此中意他并不仅仅是因为它只有四个字母,在使用上比​isinstance()​输入更快,还因为使用​type()​可以直接看到变量的类型,而使用​isinstance()​需要先知道大概是什么类型,才能判断是不是这个类型,从直观程度上​type()​更加直观。它也成为小编手册示例代码的优选函数之一。但是​type()​函数的作用不止于此,今天这篇文章我们就来重温一下​type(​)函数的功能吧。

              简介

              type()​函数有两种语法,分别是:

              type(object)#或者type(name, bases, dict, **kwds)

              前一种用法接受一个对象(变量),返回 object 的类型。 返回值是一个 type 对象,通常与 ​object.__class__ ​所返回的对象相同。

              说人话,就是返回这个对象的类型,举个例子:

              class Animal():    name = ""    def __init__(self,name):        self.name = name    def get_name(self):        return self.name      def breathe():        print("我可以呼吸")a = Animal('大象')print(type(a))            # 返回类Animal的实例对象  (aka 'object') 或者 <class '__main__.Animal'>)print(dir(a))

              他的返回值是:

              <class '__main__.Animal'>

              ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'breathe', 'get_name', 'name']

              我们可以看出,这是一个Animal对象。它有一个name属性和两个方法(get_name()和breathe())

               所有的动物都会呼吸!!

              动态创建类

              让我们再来看看第二种语法:

              type(name, bases, dict, **kwds)

              这个时候​type()​函数可以传入三个参数,第一个参数name是我们要创建的类的类名,第二个参数bases为这个类继承于谁(也就是谁是他的父类),如果为空的话则继承于object类,第三个参数dict是一个字典,包含类的属性和方法定义。

               注意,bases参数必须是一个元组,所以要使用元组的形式把参数传进去!

              创建一个子类,增加新的属性

              前面我们提到dict参数可以





              当使用type()函数创建类时,可以在第三个参数attr中添加方法。attr是一个字典,key为方法名,value为方法。例如,下面的代码创建了一个名为MyClass的类,并添加了一个名为my_method的方法:

              MyClass = type('MyClass', (object,), {'my_method': lambda x: x+1})

              这里的第一个参数是类名,第二个参数是继承的父类,第三个参数是属性字典。在这个例子中,我们使用了lambda表达式来定义my_method方法。这个方法接受一个参数x,并返回x+1。

              如果要添加多个方法,可以在属性字典中添加多个键值对。例如:

              MyClass = type('MyClass', (object,), {'my_method': lambda x: x+1,                                       'my_other_method': lambda x: x-1})

              这里我们定义了两个方法:my_method和my_other_method。

              请注意,这里的方法都是类方法而不是实例方法。如果要添加实例方法,请使用types.MethodType()函数。例如:

              import typesdef my_instance_method(self):    return self.x + 1MyClass = type('MyClass', (object,), {'my_instance_method': types.MethodType(my_instance_method, None)})

              这里我们定义了一个名为my_instance_method的实例方法,并将其添加到了MyClass类中。


              Python 内置函数 Python 内置函数


              描述

              Python ​dir()​ 函数不带参数时,返回当前作用域内的所有名称;

              带参数时,返回参数的属性、方法列表。

              如果对象实现了​​​__dir__()​​​方法,该方法将被调用。

              如果对象没有实现​​__dir__()​​​,该方法将最大限度地收集参数信息。

              注意:因为 ​dir() ​主要是为了便于在交互式shell中使用,所以它会试图返回人们感兴趣的名字集合,而不是试图保证结果的严格性或一致性,它具体的行为也可能在不同版本之间改变。

              例如,当实参是一个类时,metaclass 的属性不包含在结果列表中。


              语法

              dir() ​语法:

              dir(object)

              参数说明:

              • object:对象、变量、模块。

              返回值

              不带参数时,返回当前作用域中的所有名称。

              返回模块的属性和方法列表。


              实例

              以下实例展示了​ dir()​在命令行中的使用方法:

              >>>dir() # 获得当前模块的属性列表['__builtins__', '__doc__', '__name__', '__package__', 'arr', 'myslice']>>> dir([ ]) # 查看列表的方法['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']>>>

              dir()​方法也可以使用在代码行内:

              print(dir())print(dir([]))

              运行结果如下:

              ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

              Python 内置函数 Python 内置函数


              Python 内置函数 Python 内置函数


              描述

              type() 函数

              如果你只有第一个参数则返回对象的类型,三个参数返回新的类型对象。

              isinstance() 与 type() 区别:type() 不会认为子类是一种父类类型,不考虑继承关系。isinstance() 会认为子类是一种父类类型,考虑继承关系。如果要判断两个类型是否相同推荐使用 isinstance()。

              语法

              以下是 type() 方法的语法:

              type(object)type(name, bases, dict)

              参数

              • name:类的名称。
              • bases:基类的元组。
              • dict:字典,类内定义的命名空间变量。

              返回值

              一个参数返回对象类型, 三个参数,返回新的类型对象。


              实例

              以下展示了使用 type 函数的实例:

              # 一个参数实例>>> type(1)<type 'int'>>>> type('school')<type 'str'>>>> type([2])<type 'list'>>>> type({0:'zero'})<type 'dict'>>>> x = 1>>> type( x ) == int # 判断类型是否相等True# 三个参数>>> class X(object):... a = 1...>>> X = type('X', (object,), dict(a=1)) # 产生一个新的类型 X>>> X<class '__main__.X'>

              type() 与 isinstance()区别:

              class A:passclass B(A):passisinstance(A(), A) # returns Truetype(A()) == A # returns Trueisinstance(B(), A) # returns Truetype(B()) == A # returns False

              Python 内置函数 Python 内置函数


              Python3 数字 Python3 数字    |    Python 内置函数 Python 内置函数


              描述

              pow() 方法返回 xy(x的y次方) 的值。

              在python中,求x的y次方的方法有很多,例如内置函数​pow()​,math模块的​math.pow()​,以及​**​运算符,他们都需要接受两个参数,但他们各有区别:

              1. **​运算符可以用来计算幂次方,但只能计算整数次幂,如果需要计算浮点数次幂,请使用内置函数​pow()​或者​math.pow()
              2. 内置函数​pow()​和math模块的​math.pow()​功能是一样的,但在返回值上,​math.pow()​总是返回浮点型

              语法

              以下是​ pow()​ 方法的语法:

              math.pow(x,y)

              参数

              • x -- 数值表达式。
              • y -- 数值表达式。

              返回值

              返回 xy(x的y次方) 的值。


              实例

              以下展示了使用​ pow()​ 方法的实例:

              #!/usr/bin/python3print ("pow(100, 2) : ", pow(100, 2))print ("pow(100, -2) : ", pow(100, -2))print ("pow(2, 4) : ", pow(2, 4))print ("pow(3, 0) : ", pow(3, 0))

              以上实例运行后输出结果为:

              pow(100, 2) :  10000

              pow(100, -2) :  0.0001

              pow(2, 4) :  16

              pow(3, 0) :  1

              Python3 数字 Python3 数字    |    Python 内置函数 Python 内置函数


              Python3 数字 Python3 数字    |    Python 内置函数 Python 内置函数


              描述

              min() ​方法返回给定参数的最小值,参数可以为序列。


              语法

              以下是 ​min() ​方法的语法:

              min( x, y, z, .... )

              参数

              • x -- 数值表达式。
              • y -- 数值表达式。
              • z -- 数值表达式。

              返回值

              返回给定参数的最小值。


              实例

              以下展示了使用​ min()​ 方法的实例:

              #!/usr/bin/python3print ("min(80, 100, 1000) : ", min(80, 100, 1000))print ("min(-20, 100, 400) : ", min(-20, 100, 400))print ("min(-80, -20, -10) : ", min(-80, -20, -10))print ("min(0, 100, -400) : ", min(0, 100, -400))

              以上实例运行后输出结果为:

              min(80, 100, 1000) :  80min(-20, 100, 400) :  -20min(-80, -20, -10) :  -80min(0, 100, -400) :  -400

              Python3 数字 Python3 数字    |    Python 内置函数 Python 内置函数


              Python3 数字 Python3 数字    |    Python 内置函数 Python 内置函数


              描述

              max()​ 方法返回给定参数的最大值,参数可以为序列。


              语法

              以下是​ max()​ 方法的语法:

              max( x, y, z, .... )

              参数

              • x -- 数值表达式。
              • y -- 数值表达式。
              • z -- 数值表达式。

              返回值

              返回给定参数的最大值。


              实例

              以下展示了使用 ​max()​ 方法的实例:

              #!/usr/bin/python3print ("max(80, 100, 1000) : ", max(80, 100, 1000))print ("max(-20, 100, 400) : ", max(-20, 100, 400))print ("max(-80, -20, -10) : ", max(-80, -20, -10))print ("max(0, 100, -400) : ", max(0, 100, -400))

              以上实例运行后输出结果为:

              max(80, 100, 1000) :  1000max(-20, 100, 400) :  400max(-80, -20, -10) :  -10max(0, 100, -400) :  100

              Python3 数字 Python3 数字    |    Python 内置函数 Python 内置函数


              Python 内置函数 Python 内置函数


              描述

              ​any() ​​函数用于判断一个列表中的所有元素是否为假(False)。

              如果列表中的所有元素都为假(True或者可以转换为True),则返回False,否则返回True

              注:元素除了 0、空、None、False 外都算 True。

              为了便于理解,上述文本中使用了列表作为可迭代对象的替换。实际上这是片面的,​​any()​​函数接受的参数为可迭代的对象(iterable ),也就是说,以下这些类型都可以作为​any()​的参数:
              1.list,tuple,dict、set、str
              2.generator,带​yield​的generator function,统称为iterator。生成器可以使用​for​可以被​next​函数调用并返回下一个值。

              函数等价于:

              def any(iterable):    for element in iterable:        if element:            return True    return False
              它与​all()​函数是一对功能相反的函数,可以简单的记为:​all()​全真才真,​any()​全假才假(刚好与与运算和或运算类似)

              语法

              以下是 ​any() ​方法的语法:

              any(iterable)

              参数

              • iterable --  可迭代的参数,包括.list,tuple,dict、set、str以及生成器生成的iterable对象。

              返回值

              如果iterable的所有元素都为​0​、​''​、​False​或者iterable为空,all(iterable)返回False,否则返回True;

              注意:空元组、空列表,空字符串返回值为False,这里要特别注意。


              实例

              以下展示了使用​ any()​ 方法的实例:

              print(any(['a', 'b', 'c', 'd']))  # 列表list,元素都不为空或0# 返回 Trueprint(any(['a', 'b', '', 'd']))   # 列表list,存在一个为空的元素# 返回Falseprint(any([0, "" , False,None]))         # 列表list,元素都为空或0或False或None# 返回Falseprint(any(('a', 'b', 'c', 'd')))  # 元组tuple,元素都不为空或0# 返回 Trueprint(any(('a', 'b', '', 'd')))   # 元组tuple,存在一个为空的元素#返回 Tureprint(any((0, "" , False,None)))  # 元组tuple,元素都为空或0或False或None# 返回 Falseprint(any("w3cschool001"))        # 字符串也是可迭代对象,可以作为any()的参数# 返回 Trueprint(any('0'))            #字符串的0不算False# 返回 Trueprint(any(''))                   # 空字符串会返回False     # 返回 Falseprint(any([]))             # 空列表# 返回 Falseprint(any(()))            # 空元组# 返回 False

              运行结果如下:

              TrueTrueFalseTrueTrueFalseTrueTrueFalseFalseFalse

              Python 内置函数 Python 内置函数



              Python 内置函数 Python 内置函数


              描述

              Python ​​eval()​函数用来执行一条字符串中的python表达式,并返回表达式的值。

               简单的说,就是执行一行python代码。


              语法

              以下是​ eval()​ 方法的语法:

              eval(expression[, globals[, locals]])

              参数

              • expression:表达式。
              • globals:变量作用域,全局命名空间,如果被提供,则必须是一个字典对象。
              • locals:变量作用域,局部命名空间,如果被提供,可以是任何映射对象。

              返回值

              返回表达式计算结果。


              实例

              以下展示了使用 eval() 方法的实例:

              >>>x = 7>>> eval( '3 * x' )21>>> eval('pow(2,2)')4>>> eval('2 + 2')4>>> n=81>>> eval("n + 4")85

              拓展

              将字符串对应的名字的变量转换成该变量对应的值:

              >>> x='8'>>> x'8'>>> a=eval(x)>>> a8>>> b='a'     # 等价于b='8'>>> c=eval(b)>>> c8>>>


              Python 内置函数 Python 内置函数


              Python3 字符串Python3 字符串    |    Python 内置函数 Python 内置函数


              描述

              len() ​方法返回一个对象的长度(元素个数),这里的对象可以是序列(如 stringbytestuplelist range 等),也可以是集合(如 dictionaryset frozen set 等)。


              语法

              len()​方法语法:

              len(seq)#或者len(set)

              参数

              • 可以是序列(如 stringbytestuplelist range 等)
              • 也可以是集合(如 dictionaryset frozen set 等)

               实际上,只要自定义的类实现了​__len__()​方法,就可以使用​len()​来获取这个对象的长度!
              __len__()​是Python中的一个特殊方法,用于返回对象的长度或元素个数。
              如果一个类表现得像一个list,要获取有多少个元素,就得用​ len() ​函数。 要让 ​len()​ 函数工作正常,类必须提供一个特殊方法​__len__()​,它返回元素的个数。


              返回值

              返回序列或者集合的长度(元素的个数)。


              实例

              以下实例展示了​len()​的使用方法:

              #!/usr/bin/pythonstr = "W3CSchool example....wow!!!"print("字符串长度: ", len(str))list = ["w3cschool","编程狮","python"]print("列表元素个数: ", len(str))dict = {"w3cschool":"编程平台","python":"Django"}print("字典元素个数: ", len(dict))

              以上实例输出结果如下:

              字符串长度:  27

              列表元素个数:  27

              字典元素个数:  2


              Python3 字符串Python3 字符串    |    Python 内置函数 Python 内置函数


              Python3 内置函数 Python3 内置函数


              描述

              Python3 zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象,这样做的好处是节约了不少的内存。

              我们可以使用 list() 转换来输出列表。

              如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。

              zip 方法在 Python 2 和 Python 3 中的不同:在 Python 2.x zip() 返回的是一个列表。
              如果需要了解 Pyhton2 的应用,可以参考 Python zip()。

              语法

              zip 语法:

              zip([iterable, ...])

              参数说明:

              • iterabl -- 一个或多个迭代器;

              返回值

              返回一个对象。


              实例

              以下实例展示了 zip 的使用方法:

              >>> a = [1,2,3]>>> b = [4,5,6]>>> c = [4,5,6,7,8]>>> zipped = zip(a,b) # 返回一个对象>>> zipped<zip object at 0x103abc288>>>> list(zipped) # list() 转换为列表[(1, 4), (2, 5), (3, 6)]>>> list(zip(a,c)) # 元素个数与最短的列表一致[(1, 4), (2, 5), (3, 6)]>>> a1, a2 = zip(*zip(a,b)) # 与 zip 相反,zip(*) 可理解为解压,返回二维矩阵式>>> list(a1)[1, 2, 3]>>> list(a2)[4, 5, 6]>>>

              Python3 内置函数 Python3 内置函数


              Python 内置函数 Python 内置函数


              描述

              Python id() 函数用于获取对象的内存地址。


              语法

              id 语法:

              id([object])

              参数说明:

              • object:对象。

              返回值

              返回对象的内存地址。


              实例

              以下实例展示了 id 的使用方法:

              >>> a = 'w3cschool'>>> id(a)40599920>>> b = 8>>> id(b)8791028446256

              Python 内置函数 Python 内置函数


              Python 内置函数 Python 内置函数


              描述

              help()​函数用于查看函数或模块用途的详细说明。


              语法

              help 语法:

              help([object])

              参数说明:

              • object:对象

              返回值

              返回对象帮助信息。


              实例

              以下实例展示了 help 的使用方法:

              >>>help('sys') # 查看 sys 模块的帮助……显示帮助信息……>>>help('str') # 查看 str 数据类型的帮助……显示帮助信息……>>>a = [1,2,3]>>>help(a) # 查看列表 list 帮助信息……显示帮助信息……>>>help(a.append) # 显示list的append方法的帮助……显示帮助信息……

              Python 内置函数 Python 内置函数


              Python 内置函数 Python 内置函数


              描述

              print() ​方法用于打印输出,最常见的一个函数。


              语法

              以下是 ​print()​ 方法的语法:

              print(*objects, sep=' ', end='
              ', file=sys.stdout)

              参数

              • objects:复数,表示可以一次输出多个对象。输出多个对象时,需要用 , 分隔。
              • sep:用来间隔多个对象,默认值是一个空格。
              • end:用来设定以什么结尾。默认值是换行符 ,我们可以换成其他字符串。
              • file:要写入的文件对象。

              返回值


              实例

              以下展示了使用 print 函数的实例:

              >>>print(1)1>>> print("Hello World")Hello World>>> a = 1>>> b = 'w3cschool'>>> print(a,b)1 w3cschool>>> print("aaa""bbb")aaabbb>>> print("aaa","bbb")aaa bbb>>>>>> print("www","w3cschool","cn",sep=".") # 设置间隔符www.w3cschool.cn

              Python 内置函数 Python 内置函数


              Python 内置函数 Python 内置函数


              描述

              isinstance()​ 函数来判断一个对象是否是一个已知的类型,类似 ​type()​。

              isinstance()​函数在使用时需要有一个已知类型的对象作为比较,比如要判断一个对象是不是列表,你需要传入一个列表对象

              isinstance() ​与​ type()​ 区别:​type() ​不会认为子类是一种父类类型,不考虑继承关系。​isinstance() ​会认为子类是一种父类类型,考虑继承关系。如果要判断两个类型是否相同推荐使用​ isinstance()​。

              语法

              以下是 ​isinstance() ​方法的语法:

              isinstance(object, classinfo)

              参数

              • object:实例对象。
              • classinfo:可以是直接或间接类名、基本类型或者由它们组成的元组。

               在python3.10中,可以classinfo使用联合类型(union类型)


              返回值

              如果对象的类型与参数二的类型(classinfo)相同则返回 True,否则返回 False。


              实例

              以下展示了使用 isinstance 函数的实例:

              >>>a = 2>>> isinstance (a,int)True>>> isinstance (a,str)False>>> isinstance (a,(str,int,list)) # 是元组中的一个返回 TrueTrue

              type() 与 isinstance() 的区别:

              class A:passclass B(A):passisinstance(A(), A) # returns Truetype(A()) == A # returns Trueisinstance(B(), A) # returns Truetype(B()) == A # returns False

              拓展

              对于基本类型来说,classinfo 可以是:

              int,float,bool,complex,str(字符串),list,dict(字典),set,tuple

              要注意的是,classinfo 的字符串是 str 而不是 string,字典也是简写 dict。

              实例:

              arg=123isinstance(arg, int)    #输出Trueisinstance(arg, str)    #输出Falseisinstance(arg, string) #报错

              Python 内置函数 Python 内置函数


              Python 内置函数 Python 内置函数


              描述

              type() ​函数通常被用来判断对象的类型,在传入三个参数的时候它可以用来动态创建类。

              本文着重介绍传入一个参数的情况,动态创建类请移步:python type()函数专题——动态创建类

              另一个函数​isinstance()​方法也可以用来判断对象的类型。

              isinstance() ​与​ type()​ 区别:
              type()​ 不会认为子类是一种父类类型,不考虑继承关系。
              isinstance()​ 会认为子类是一种父类类型,考虑继承关系。
              如果要判断两个类型是否相同推荐使用 ​isinstance()​。

              语法

              以下是​ type() ​方法的语法:

              type(object)# 或者type(name, bases, dict)

              参数

              单参数情况:

              • object:一个对象

              三参数情况:

              • name:要动态创建的类的名称。
              • bases:继承于哪个父类(这是一个元组!)。
              • dict:要添加的属性和方法(这是一个字典!)

              返回值

              单参数情况:返回这个对象的类型

              三参数情况:返回一个新的类型对象(一个动态创建的类)。


              实例

              以下展示了使用 ​type()​ 函数判断对象类型的实例:

              print("数值对象的变量类型:")print(type(1))print('字符串对象的变量类型:')print(type('W3Cschool'))print('列表对象的变量类型:')print(type([2]))print('元组对象的变量类型:')print(type((1,2)))print('字典对象的变量类型:')print(type({0:'zero'}))print('判断两个对象的类型是否相等')x = 1print(type(x) == int)

              运行结果如下:

              数值对象的变量类型:<class 'int'>字符串对象的变量类型:<class 'str'>列表对象的变量类型:<class 'list'>元组对象的变量类型:<class 'tuple'>字典对象的变量类型:<class 'dict'>判断两个对象的类型是否相等True

              以下展示了使用​type()​函数动态创建一个类的代码:

              class Animal():     #一个父类,用来被继承的类。通常我们使用都是直接继承object类,但这边为了直观所以自己弄了一个类    #这个父类有一个name属性,一个get_name方法,一个breathe方法    name = ""    def __init__(self,name):        self.name = name        def get_name(self):        return self.name             def breathe():        print("我可以呼吸")#使用动态创建类的方法创建一个people类,继承了animal类,需要多一个属性sex  People = type("People",(Animal,) , {'sex':'M'}) # 我们定义了一个新类叫People,他继承于animal类,多了一个新的属性sexhuman = People('男人') #实例化这个类,让我们来看看他有什么表现吧print(type(human))  # 返回类People的实例化对象human 的类型<class '__main__.People'>)print(dir(human))  #用来查看这个类有什么属性或方法#我们使用的是dir方法,虽然看着很复杂,不过我们可以看到乱七八糟的结果里确实有父类的两个方法一个属性,和我们添加进去的sex属性# 当然也可以自己使用以下这个类的方法和属性,这里我只想证明存在这些内容,不多做功能展示# 使用动态创建了的方法创建一个Bird类,继承于animal类,需要多一个fly的方法def fly(self):    print("我可以飞")Bird = type('Bird', (Animal,), {'fly': fly}) #我们定义了一个新类叫Bird,继承于Animal类,多了一个新的方法flybird =Bird('乌鸦')           # 实例化这个类,让我们看到他有什么表现吧print(type(bird))            # 返回类Bird的实例化对象bird的类型 <class '__main__.Bird'>)print(dir(bird))             # 用来查看这个类有什么属性或方法bird.fly()                   # 试用一下这个fly方法,看它是否实现了功能#使用动态创建类的方法创建一个Durk类,继承于animal类,需要多一个属性weight和一个方法fly()Durk = type("Durk",(Animal,),{"weight":0,"fly":fly}) #我们定义了一个新类叫Durk,继承于Animal类,多了一个新的方法fly()和一个新属性weightcallDuck =  Durk('柯尔鸭') #实例化这个类,让我们看到他有什么表现吧print(type(callDuck))            # 返回类Durk的实例化对象callDark的类型 <class '__main__.Dark'>) print(dir(callDuck))             # 用来查看这个类有什么属性或方法  

              运行结果如下:

              <class '__main__.People'>['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'breathe', 'get_name', 'name', 'sex']<class '__main__.Bird'>['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'breathe', 'fly', 'get_name', 'name']我可以飞<class '__main__.Durk'>['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'breathe', 'fly', 'get_name', 'name', 'weight']

              补充

              type() ​与​ isinstance()​区别:

              class A:passclass B(A):passisinstance(A(), A) # returns Truetype(A()) == A # returns Trueisinstance(B(), A) # returns Truetype(B()) == A # returns False

              Python 内置函数 Python 内置函数



              Python 内置函数 Python 内置函数


              描述

              ​any() ​​函数用于判断一个列表中的所有元素是否为假(False)。

              如果列表中的所有元素都为假(True或者可以转换为True),则返回False,否则返回True

              注:元素除了 0、空、None、False 外都算 True。

              为了便于理解,上述文本中使用了列表作为可迭代对象的替换。实际上这是片面的,​​any()​​函数接受的参数为可迭代的对象(iterable ),也就是说,以下这些类型都可以作为​any()​的参数:
              1.list,tuple,dict、set、str
              2.generator,带​yield​的generator function,统称为iterator。生成器可以使用​for​可以被​next​函数调用并返回下一个值。

              函数等价于:

              def any(iterable):    for element in iterable:        if element:            return True    return False
              它与​all()​函数是一对功能相反的函数,可以简单的记为:​all()​全真才真,​any()​全假才假(刚好与与运算和或运算类似)

              语法

              以下是 ​any() ​方法的语法:

              any(iterable)

              参数

              • iterable --  可迭代的参数,包括.list,tuple,dict、set、str以及生成器生成的iterable对象。

              返回值

              如果iterable的所有元素都为​0​、​''​、​False​或者iterable为空,all(iterable)返回False,否则返回True;

              注意:空元组、空列表,空字符串返回值为False,这里要特别注意。


              实例

              以下展示了使用​ any()​ 方法的实例:

              print(any(['a', 'b', 'c', 'd']))  # 列表list,元素都不为空或0# 返回 Trueprint(any(['a', 'b', '', 'd']))   # 列表list,存在一个为空的元素# 返回Falseprint(any([0, "" , False,None]))         # 列表list,元素都为空或0或False或None# 返回Falseprint(any(('a', 'b', 'c', 'd')))  # 元组tuple,元素都不为空或0# 返回 Trueprint(any(('a', 'b', '', 'd')))   # 元组tuple,存在一个为空的元素#返回 Tureprint(any((0, "" , False,None)))  # 元组tuple,元素都为空或0或False或None# 返回 Falseprint(any("w3cschool001"))        # 字符串也是可迭代对象,可以作为any()的参数# 返回 Trueprint(any('0'))            #字符串的0不算False# 返回 Trueprint(any(''))                   # 空字符串会返回False     # 返回 Falseprint(any([]))             # 空列表# 返回 Falseprint(any(()))            # 空元组# 返回 False

              运行结果如下:

              TrueTrueFalseTrueTrueFalseTrueTrueFalseFalseFalse

              Python 内置函数 Python 内置函数



              Python 内置函数 Python 内置函数


              描述

              Python ​dir()​ 函数不带参数时,返回当前作用域内的所有名称;

              带参数时,返回参数的属性、方法列表。

              如果对象实现了​​​__dir__()​​​方法,该方法将被调用。

              如果对象没有实现​​__dir__()​​​,该方法将最大限度地收集参数信息。

              注意:因为 ​dir() ​主要是为了便于在交互式shell中使用,所以它会试图返回人们感兴趣的名字集合,而不是试图保证结果的严格性或一致性,它具体的行为也可能在不同版本之间改变。

              例如,当实参是一个类时,metaclass 的属性不包含在结果列表中。


              语法

              dir() ​语法:

              dir(object)

              参数说明:

              • object:对象、变量、模块。

              返回值

              不带参数时,返回当前作用域中的所有名称。

              返回模块的属性和方法列表。


              实例

              以下实例展示了​ dir()​在命令行中的使用方法:

              >>>dir() # 获得当前模块的属性列表['__builtins__', '__doc__', '__name__', '__package__', 'arr', 'myslice']>>> dir([ ]) # 查看列表的方法['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']>>>

              dir()​方法也可以使用在代码行内:

              print(dir())print(dir([]))

              运行结果如下:

              ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

              Python 内置函数 Python 内置函数


              Python 内置函数 Python 内置函数


              描述

              all() ​函数用于判断一个列表中的所有元素是否为真(True)。

              如果列表中的所有元素都为真(True或者可以转换为True),则返回True,否则返回False

              注:元素除了 0、空、None、False 外都算 True。

               为了便于理解,上述文本中使用了列表作为可迭代对象的替换。实际上这是片面的,​all()​函数接受的参数为可迭代的对象(iterable ),也就是说,以下这些类型都可以作为all()的参数:

              1.list,tuple,dict、set、str
              2.generator,带yield的generator function,统称为iterator。生成器可以使用for可以被next函数调用并返回下一个值。

              函数等价于:

              def all(iterable):    for element in iterable:        if not element:            return False    return True
              它与​any()
              ​函数是一对功能相反的函数,可以简单的记为:all()
              ​全真才真,​any()
              ​全假才假(刚好与与运算和或运算类似)

              语法

              以下是 ​all()​ 方法的语法:

              all(iterable)

              参数

              • iterable -- 可迭代的参数,包括.list,tuple,dict、set、str以及生成器生成的iterable对象。

              返回值

              如果iterable的所有元素不为​0​、​''​、​False​或者iterable为空,all(iterable)返回True,否则返回False;

              注意:空元组、空列表返回值为True,这里要特别注意。


              实例

              以下展示了使用 all() 方法的实例:

              print(all(['a', 'b', 'c', 'd']))  # 列表list,元素都不为空或0# 返回 Trueprint(all(['a', 'b', '', 'd']))   # 列表list,存在一个为空的元素# 返回Falseprint(all([0, 1 , 2, 3]))         # 列表list,存在一个为0的元素# 返回Falseprint(all(('a', 'b', 'c', 'd')))  # 元组tuple,元素都不为空或0# 返回 Trueprint(all(('a', 'b', '', 'd')))   # 元组tuple,存在一个为空的元素#返回 Falseprint(all((0, 1, 2, 3)))          # 元组tuple,存在一个为0的元素# 返回 Falseprint(all(''))                    # 字符串也是可迭代对象,可以作为all()的参数# 返回 Trueprint(all("w3cschool001"))        # 但是字符串中的数字0,空字符串并不算         # 返回 Trueprint(all([]))             # 空列表# 返回 Trueprint(all(()))            # 空元组# 返回 True

              运行结果为:

              True
              False
              False
              True
              False
              False
              True
              True
              True
              True

              Python 内置函数 Python 内置函数


              Python 内置函数 Python 内置函数


              描述

              Python ​​eval()​函数用来执行一条字符串中的python表达式,并返回表达式的值。

               简单的说,就是执行一行python代码。


              语法

              以下是​ eval()​ 方法的语法:

              eval(expression[, globals[, locals]])

              参数

              • expression:表达式。
              • globals:变量作用域,全局命名空间,如果被提供,则必须是一个字典对象。
              • locals:变量作用域,局部命名空间,如果被提供,可以是任何映射对象。

              返回值

              返回表达式计算结果。


              实例

              以下展示了使用 eval() 方法的实例:

              >>>x = 7>>> eval( '3 * x' )21>>> eval('pow(2,2)')4>>> eval('2 + 2')4>>> n=81>>> eval("n + 4")85

              拓展

              将字符串对应的名字的变量转换成该变量对应的值:

              >>> x='8'>>> x'8'>>> a=eval(x)>>> a8>>> b='a'     # 等价于b='8'>>> c=eval(b)>>> c8>>>


              Python 内置函数 Python 内置函数


              Python 内置函数 Python 内置函数


              描述

              Python​ iter() ​函数用来生成迭代器。

              有些对象(尤其是自定义的对象)可以像数组一样读出数据,但本身不是可迭代对象,这个时候就可以使用iter()将其转换成可迭代对象。

               在类中实现了如果只实现​__getitem__()​的对象可以通过​iter()​函数转化成迭代器但其本身不是可迭代对象。所以当一个对象能够在for循环中运行时,不能确定是Iterable对象。 


              语法

              iter()​ 方法的语法有两种,分别是:

              iter(object)

              iter(object, sentinel)

              sentinel参数用于指示迭代的停止条件。


              参数

              • object:支持迭代的集合对象(在不传入sentinel参数时)或者可调用的对象(第二种情况)。
              • sentinel:如果传递了第二个参数,则参数 object 必须是一个可调用的对象(如,函数),此时,iter 创建了一个迭代器对象,每次调用这个迭代器对象的​__next__()​方法时,都会调用 object。

              返回值

              迭代器对象。


              实例

              from typing import Iterableclass LinearDataStructure:    # 一个自己实现的线性表,未传参时默认为1,2,3        def __init__(self, data=[1, 2, 3]):        self.data = data    def get_data(self):        return self.data        def __getitem__(self,idx):        return(self.data[idx])    # 第一种语法lds = LinearDataStructure()print(isinstance(lds,Iterable))  # 这个线性表不是可迭代对象print(isinstance(iter(lds),Iterable)) # 使用iter方法可以把这个线性表变成可迭代对象# 第二种语法def read_until(f, stop):    return iter(lambda: f.readline().strip(), stop)with open('file.txt') as f:    for line in read_until(f, ''):        print(line)



              Python 内置函数 Python 内置函数



              Python3 数字 Python3 数字


              描述

              sqrt() 方法返回数字x的平方根。


              语法

              以下是 ​sqrt() ​方法的语法:

              import mathmath.sqrt( x )

              注意:sqrt()​是不能直接访问的,需要导入 math 模块,通过静态对象调用该方法。


              参数

              • x -- 数值表达式。

              返回值

              返回数字x的平方根。

              实例

              以下展示了使用 sqrt() 方法的实例:

              #!/usr/bin/python3import math   # 导入 math 模块print ("math.sqrt(100) : ", math.sqrt(100))print ("math.sqrt(7) : ", math.sqrt(7))print ("math.sqrt(math.pi) : ", math.sqrt(math.pi))

              以上实例运行后输出结果为:

              math.sqrt(100) :  10.0math.sqrt(7) :  2.6457513110645907math.sqrt(math.pi) :  1.7724538509055159

              Python3 数字 Python3 数字


              Python urllib 库用于操作网页 URL,并对网页的内容进行抓取处理。

              本文主要介绍 Python3 的 urllib。

              urllib 包 包含以下几个模块:

              • urllib.request - 打开和读取 URL。
              • urllib.error - 包含 urllib.request 抛出的异常。
              • urllib.parse - 解析 URL。
              • urllib.robotparser - 解析 robots.txt 文件。

              urllib.request

              urllib.request 定义了一些打开 URL 的函数和类,包含授权验证、重定向、浏览器 cookies等。

              urllib.request 可以模拟浏览器的一个请求发起过程。

              我们可以使用 urllib.request 的 urlopen 方法来打开一个 URL,语法格式如下:

              urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
              • url:url 地址。
              • data:发送到服务器的其他数据对象,默认为 None。
              • timeout:设置访问超时时间。
              • cafile 和 capath:cafile 为 CA 证书, capath 为 CA 证书的路径,使用 HTTPS 需要用到。
              • cadefault:已经被弃用。
              • context:ssl.SSLContext类型,用来指定 SSL 设置。

              实例如下:

              from urllib.request import urlopenmyURL = urlopen("https://www.w3cschool.cn/")print(myURL.read())

              以上代码使用 urlopen 打开一个 URL,然后使用 read() 函数获取网页的 HTML 实体代码。

              read() 是读取整个网页内容,我们可以指定读取的长度:

              from urllib.request import urlopenmyURL = urlopen("https://www.w3cschool.cn/")print(myURL.read(300))

              除了 read() 函数外,还包含以下两个读取网页内容的函数:

              • readline() - 读取文件的一行内容
              from urllib.request import urlopenmyURL = urlopen("https://www.w3cschool.cn/")print(myURL.readline()) #读取一行内容
            • readlines() - 读取文件的全部内容,它会把读取的内容赋值给一个列表变量。
            • from urllib.request import urlopenmyURL = urlopen("https://www.w3cschool.cn/")lines = myURL.readlines()for line in lines:    print(line) 

              我们在对网页进行抓取时,经常需要判断网页是否可以正常访问,这里我们就可以使用 getcode() 函数获取网页状态码,返回 200 说明网页正常,返回 404 说明网页不存在:

              import urllib.requestmyURL1 = urllib.request.urlopen("https://www.w3cschool.cn/")print(myURL1.getcode())   # 200try:    myURL2 = urllib.request.urlopen("https://www.w3cschool.cn/no.html")except urllib.error.HTTPError as e:    if e.code == 404:        print(404)   # 404

              更多网页状态码可以查阅:https://www.w3cschool.cn/http/http-status-codes.html

              如果要将抓取的网页保存到本地,可以使用 Python3 File write() 方法 函数:

              from urllib.request import urlopenmyURL = urlopen("https://www.w3cschool.cn/")f = open("w3cschool_urllib_test.html", "wb")content = myURL.read()  # 读取网页内容f.write(content)f.close()

              执行以上代码,在本地就会生成一个 w3cschool_urllib_test.html 文件,里面包含了 https://www.w3cschool.cn/ 网页的内容。

              更多Python File 处理,可以参阅:https://www.w3cschool.cn/python3/python3-file-methods.html

              URL 的编码与解码可以使用 urllib.request.quote() 与 urllib.request.unquote() 方法:

              import urllib.requestencode_url = urllib.request.quote("https://www.w3cschool.cn/")  # 编码print(encode_url)unencode_url = urllib.request.unquote(encode_url)    # 解码print(unencode_url)

              输出结果为:

              https%3A//www.w3cschool.cn/https://www.w3cschool.cn/

              模拟头部信息

              我们抓取网页一般需要对 headers(网页头信息)进行模拟,这时候需要使用到 urllib.request.Request 类:

              class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
              • url:url 地址。
              • data:发送到服务器的其他数据对象,默认为 None。
              • headers:HTTP 请求的头部信息,字典格式。
              • origin_req_host:请求的主机地址,IP 或域名。
              • unverifiable:很少用整个参数,用于设置网页是否需要验证,默认是False。。
              • method:请求方法, 如 GET、POST、DELETE、PUT等。
              import urllib.requestimport urllib.parseurl = 'https://www.w3cschool.cn/search?w='  # 编程狮搜索页面keyword = 'Python 教程'key_code = urllib.request.quote(keyword)  # 对请求进行编码url_all = url+key_codeheader = {    'User-Agent':'Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'}   #头部信息request = urllib.request.Request(url_all,headers=header)reponse = urllib.request.urlopen(request).read()fh = open("./urllib_test_w3cschool_search.html","wb")    # 将文件写入到当前目录中fh.write(reponse)fh.close()

              执行以上 Python 代码,会在当前目录生成 urllib_test_w3cschool_search.html 文件,打开 urllib_test_w3cschool_search.html 文件(可以使用浏览器打开),内容如下:


              表单 POST 传递数据,我们先创建一个表单,代码如下,我这里使用了 PHP 代码来获取表单的数据:

              <!DOCTYPE html><html><head><meta charset="utf-8"><title>编程狮(w3cschool.cn) urllib POST  测试</title></head><body><form action="" method="post" name="myForm">    Name: <input type="text" name="name"><br>    Tag: <input type="text" name="tag"><br>    <input type="submit" value="提交"></form><hr><?php// 使用 PHP 来获取表单提交的数据,你可以换成其他的if(isset($_POST['name']) && $_POST['tag'] ) {   echo $_POST["name"] . ', ' . $_POST['tag'];}?></body></html>
              import urllib.requestimport urllib.parseurl = 'https://www.w3cschool.cn/try/py3/py3_urllib_test.php'  # 提交到表单页面data = {'name':'w3cschool', 'tag' : '编程狮'}   # 提交数据header = {    'User-Agent':'Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'}   #头部信息data = urllib.parse.urlencode(data).encode('utf8')  # 对参数进行编码,解码使用 urllib.parse.urldecoderequest=urllib.request.Request(url, data, header)   # 请求处理reponse=urllib.request.urlopen(request).read()      # 读取结果fh = open("./urllib_test_post_w3cschool.html","wb")    # 将文件写入到当前目录中fh.write(reponse)fh.close()

              执行以上代码,会提交表单数据到 py3_urllib_test.php 文件,输出结果写入到 urllib_test_post_w3cschool.html 文件。

              打开 urllib_test_post_w3cschool.html 文件(可以使用浏览器打开),显示结果如下:

              CFE5A0A5-6E9C-4CBF-B866-0C559F239DF8

              urllib.error

              urllib.error 模块为 urllib.request 所引发的异常定义了异常类,基础异常类是 URLError。

              urllib.error 包含了两个方法,URLError 和 HTTPError。

              URLError 是 OSError 的一个子类,用于处理程序在遇到问题时会引发此异常(或其派生的异常),包含的属性 reason 为引发异常的原因。

              HTTPError 是 URLError 的一个子类,用于处理特殊 HTTP 错误例如作为认证请求的时候,包含的属性 code 为 HTTP 的状态码, reason 为引发异常的原因,headers 为导致 HTTPError 的特定 HTTP 请求的 HTTP 响应头。

              对不存在的网页抓取并处理异常:

              import urllib.requestimport urllib.errormyURL1 = urllib.request.urlopen("https://www.w3cschool.cn/")print(myURL1.getcode())   # 200try:    myURL2 = urllib.request.urlopen("https://www.w3cschool.cn/no.html")except urllib.error.HTTPError as e:    if e.code == 404:        print(404)   # 404

              urllib.parse

              urllib.parse 用于解析 URL,格式如下:

              urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)

              urlstring 为 字符串的 url 地址,scheme 为协议类型,

              allow_fragments 参数为 false,则无法识别片段标识符。相反,它们被解析为路径,参数或查询组件的一部分,并 fragment 在返回值中设置为空字符串。

              from urllib.parse import urlparseo = urlparse("https://www.w3cschool.cn/?s=python+%E6%95%99%E7%A8%8B")print(o)

              以上实例输出结果为:

              ParseResult(scheme='https', netloc='www.w3cschool.cn', path='/', params='', query='s=python+%E6%95%99%E7%A8%8B', fragment='')

              从结果可以看出,内容是一个元组,包含 6 个字符串:协议,位置,路径,参数,查询,判断。

              我们可以直接读取协议内容:

              from urllib.parse import urlparseo = urlparse("https://www.w3cschool.cn/?s=python+%E6%95%99%E7%A8%8B")print(o.scheme)

              以上实例输出结果为:

              https

              完整内容如下:

              属性

              索引

              值(如果不存在)

              scheme

              0

              URL协议

              scheme 参数

              netloc

              1

              网络位置部分

              空字符串

              path

              2

              分层路径

              空字符串

              params

              3

              最后路径元素的参数

              空字符串

              query

              4

              查询组件

              空字符串

              fragment

              5

              片段识别

              空字符串

              username

              用户名

              None

              password

              密码

              None

              hostname

              主机名(小写)

              None

              port

              端口号为整数(如果存在)

              None

              urllib.robotparser

              urllib.robotparser 用于解析 robots.txt 文件。

              robots.txt(统一小写)是一种存放于网站根目录下的 robots 协议,它通常用于告诉搜索引擎对网站的抓取规则。

              urllib.robotparser 提供了 RobotFileParser 类,语法如下:

              class urllib.robotparser.RobotFileParser(url='')

              这个类提供了一些可以读取、解析 robots.txt 文件的方法:

              • set_url(url) - 设置 robots.txt 文件的 URL。
              • read() - 读取 robots.txt URL 并将其输入解析器。
              • parse(lines) - 解析行参数。
              • can_fetch(useragent, url) - 如果允许 useragent 按照被解析 robots.txt 文件中的规则来获取 url 则返回 True。
              • mtime() -返回最近一次获取 robots.txt 文件的时间。 这适用于需要定期检查 robots.txt 文件更新情况的长时间运行的网页爬虫。
              • modified() - 将最近一次获取 robots.txt 文件的时间设置为当前时间。
              • crawl_delay(useragent) -为指定的 useragent 从 robots.txt 返回 Crawl-delay 形参。 如果此形参不存在或不适用于指定的 useragent 或者此形参的 robots.txt 条目存在语法错误,则返回 None。
              • request_rate(useragent) -以 named tuple RequestRate(requests, seconds) 的形式从 robots.txt 返回 Request-rate 形参的内容。 如果此形参不存在或不适用于指定的 useragent 或者此形参的 robots.txt 条目存在语法错误,则返回 None。
              • site_maps() - 以 list() 的形式从 robots.txt 返回 Sitemap 形参的内容。 如果此形参不存在或者此形参的 robots.txt 条目存在语法错误,则返回 None。
              >>> import urllib.robotparser>>> rp = urllib.robotparser.RobotFileParser()>>> rp.set_url("http://www.musi-cal.com/robots.txt")>>> rp.read()>>> rrate = rp.request_rate("*")>>> rrate.requests3>>> rrate.seconds20>>> rp.crawl_delay("*")6>>> rp.can_fetch("*", "http://www.musi-cal.com/cgi-bin/search?city=San+Francisco")False>>> rp.can_fetch("*", "http://www.musi-cal.com/")True


              Python3 log10() 函数

              Python3 数字 Python3 数字


              描述

              log10() ​方法返回以10为基数的x对数,x>0。


              语法

              以下是 ​log10() ​方法的语法:

              import mathmath.log10( x )

              注意:log10()​是不能直接访问的,需要导入​ math​ 模块,通过静态对象调用该方法。


              参数

              • x -- 数值表达式。

              返回值

              返回以10为基数的x对数,x>0。

              实例

              以下展示了使用​ log10() ​方法的实例:

              #!/usr/bin/python3import math   # 导入 math 模块print ("math.log10(100.12) : ", math.log10(100.12))print ("math.log10(100.72) : ", math.log10(100.72))print ("math.log10(119) : ", math.log10(119))print ("math.log10(math.pi) : ", math.log10(math.pi))

              以上实例运行后输出结果为:

              math.log10(100.12) :  2.0005208409361854math.log10(100.72) :  2.003115717099806math.log10(119) :  2.075546961392531math.log10(math.pi) :  0.4971498726941338

              Python3 数字 Python3 数字


              Python3 数字 Python3 数字    |    Python 内置函数 Python 内置函数


              描述

              round() 方法返回浮点数x的四舍五入值。


              语法

              以下是​ round()​ 方法的语法:

              round( x [, n]  )

              参数

              • x -- 数值表达式。
              • n -- 表示从小数点位数,其中 x 需要四舍五入,默认值为 0。

              返回值

              返回浮点数x的四舍五入值。


              实例

              以下展示了使用​ round() ​方法的实例:

              #!/usr/bin/python3print ("round(70.23456) : ", round(70.23456))print ("round(56.659,1) : ", round(56.659,1))print ("round(80.264, 2) : ", round(80.264, 2))print ("round(100.000056, 3) : ", round(100.000056, 3))print ("round(-100.000056, 3) : ", round(-100.000056, 3))

              以上实例运行后输出结果为:

              round(70.23456) :  70round(56.659,1) :  56.7round(80.264, 2) :  80.26round(100.000056, 3) :  100.0round(-100.000056, 3) :  -100.0

              Python3 数字 Python3 数字    |    Python 内置函数 Python 内置函数


              Python math 模块  math 模块


              描述

              math.ulp(x)方法返回给定浮点数的最小单位。

              这个单位是指在给定浮点数的范围内,两个相邻的浮点数之间的差值。

              例如,对于输入值3.1415926,math.ulp(x)将返回2.220446049250313e-16。

              这意味着在3.1415926的范围内,相邻的两个浮点数之间的差值为2.220446049250313e-16。

              ULP(Unit in the last place)是计算机科学中的一个误差单位。

              我们知道,计算机使用IEEE754的标准来表示浮点数,这个方法与我们现实中使用的小数是有所不同的


              语法

              math.ulp()方法语法如下:

              math.ulp(x)

              参数说明:

              • x -- 必需,一个数字

              返回值

              • 如果 x 是 NaN (非数字),则返回 x。
              • 如果 x 为负数,则返回 ulp(-x)。
              • 如果 x 为正数,则返回 x。
              • 如果 x 等于零,则返回 去正规化的 可表示最小正浮点数 (小于 正规化的 最小正浮点数 sys.float_info.min)。
              • 如果 x 等于可表示最大正浮点数,则返回 x 的最低有效比特位的值,使得小于 x 的第一个浮点数为 x - ulp(x)。
              • 在其他情况下 (x 是一个有限的正数),则返回 x 的最低有效比特位的值,使得大于 x 的第一个浮点数为 x + ulp(x)。

              实例

              以下实例返回指定数字的:


              输出结果:



              Python math 模块  math 模块


              Python math 模块 math 模块


              描述

              返回给定的整数参数的最小公倍数。 

              如果所有参数均非零,则返回值将是为所有参数的整数倍的最小正整数。

               如果参数之一为零,则返回值为 0。 

              不带参数的 lcm() 返回 1

              本函数要求最低版本为Python 3.9

              语法

              math.lcm() 方法语法如下:

              math.lcm(*integers)

              参数说明:

              • integers -- 必需,数字。如果 x 不是一个数字,返回 TypeError。

               *表示可以传递多个integers参数


              返回值

              返回一个整数 int,表示两个或多个整数的最小公倍数(LCM)。


              实例

              以下实例返回数字的最小公倍数:

              #导入math模块import math#输出最小公倍数print (math.lcm(3, 6))print (math.lcm(11, 12))print (math.lcm(0, 36))print (math.lcm(-12, -36))print (math.lcm(5, 12,60))print (math.lcm(12,13,14,15))

              输出结果:

              6132036605460

              Python math 模块 math 模块


              Python math 模块 math 模块


              描述

              modf() 方法返回x的整数部分与小数部分,两部分的数值符号与x相同,整数部分以浮点型表示。


              语法

              以下是 modf() 方法的语法:

              import mathmath.modf( x )

              注意:modf()是不能直接访问的,需要导入 math 模块,通过静态对象调用该方法。


              参数

              • x -- 数值表达式。

              返回值

              返回x的整数部分与小数部分,


              实例

              以下展示了使用 modf() 方法的实例:

              #!/usr/bin/python3import math   # 导入 math 模块print ("math.modf(100.12) : ", math.modf(100.12))print ("math.modf(100.72) : ", math.modf(100.72))print ("math.modf(119) : ", math.modf(119))print ("math.modf(math.pi) : ", math.modf(math.pi))

              以上实例运行后输出结果为:

              math.modf(100.12) :  (0.12000000000000455, 100.0)math.modf(100.72) :  (0.7199999999999989, 100.0)math.modf(119) :  (0.0, 119.0)math.modf(math.pi) :  (0.14159265358979312, 3.0)

              Python math 模块 math 模块


              什么是装饰器

              装饰器(decorators)是 一种设计模式,之所以被称为装饰器,是因为其本质是对一个函数或者对象进行了"修饰",装饰器可以在你进入对象或者函数前后进行一些操作,可以在不修改原来的代码的情况下让函数的行为发生改变。

              面向切面编程(AOP),是指某些业务流程具有相似性,只有部分核心代码有差异,我们可以把相同部分的代码提取出来,不同的代码(切片)另外实现,这就是面向切面编程。在 java 的 spring 中,这是一种很重要的技术,而 python 也有类似的实现方式,最常见的就是装饰器。


              装饰器的功能

              装饰器允许你动态地修改函数或类的行为。它本质上是一个函数,可以接受一个函数作为参数,并返回一个新的函数或者修改原来的函数。


              装饰器语法

              装饰器虽然是一个函数,但它更常见的使用方式是使用 ​@decorator_name​ 来应用在函数或方法上。

              例如:

              from flask import Flask
              app =Flask(__name__)

              # app.route就是一个Flask内置的装饰器
              @app.route("index")
              def index():
                 return "hello"

              Python 还提供了一些内置的装饰器,比如 ​@staticmethod​ 和 ​@classmethod​,用于定义静态方法和类方法。


              装饰器的应用场景:

              • 日志记录: 装饰器可用于记录函数的调用信息、参数和返回值。
              • 性能分析: 可以使用装饰器来测量函数的执行时间。
              • 权限控制: 装饰器可用于限制对某些函数的访问权限。
              • 缓存: 装饰器可用于实现函数结果的缓存,以提高性能。


              简单案例

              import time
              def runtime(func):#定义一个装饰器函数叫runtime 他接受一个函数func作为参数
               def wrapper(*args, **kwargs): # 包装函数wrapper,这里接受所有参数
                 
                 # 这里是在调用原始函数前添加的新功能
                 starttime= time.time() #获取开始执行的时间
                 
                 # 在包装函数中调用原始函数(可以不调用)
                 result = func(*args, **kwargs) # 函数传递的参数为包装函数接受的所有参数
                 
                # 这里是在调用原始函数后添加的新功能
                 endtime= time.time() #获取结束执行的时间

                 print(f"函数{func.__name__}运行时间:{endtime-starttime}秒") #输出函数运行的时间

                 return result # 返回函数运行的结果
               return wrapper

              # 使用装饰器装饰一个函数,现在运行这个函数时,会运行装饰器的代码,然后再由装饰器运行这个func
              # (如果装饰器不调用这个函数,而是调用别的函数,就可以替换掉原有函数的功能)
              @runtime
              def sleepfunc(arg1, arg2):
               time.sleep(2)
               return arg1 + arg2

              print(sleepfunc(1, 2))
              函数sleepfunc运行时间:2.005006790161133秒
              3

              解析:​runtime​是一个装饰器函数,它接受一个函数 ​func​ 作为参数,并返回一个内部函数 ​wrapper​,在 ​wrapper​ 函数内部,你可以执行一些额外的操作,然后调用原始函数 ​func​,并返回其结果。

              • runtime 是装饰器,它接收一个函数 func 作为参数。
              • wrapper 是内部函数,它是实际会被调用的新函数,它包裹了原始函数的调用,并在其前后增加了额外的行为。
              • 当我们使用 ​@runtime​ 前缀在 ​sleepfunc​ 定义前,Python会自动将 ​sleepfunc​ 作为参数传递给 ​runtime​,然后将返回的 ​wrapper​ 函数替换掉原来的 ​sleepfunc​。


              使用装饰器

              装饰器通过 ​@​ 符号应用在函数定义之前,例如:

              @time_logger
              def target_function():
                pass

              等同于:

              def target_function():
                pass
              target_function = time_logger(target_function)

              这会将 ​target_function​ 函数传递给 ​decorator​ 装饰器,并将返回的函数重新赋值给 ​target_function​。从而,每次调用 ​target_function​ 时,实际上是调用了经过装饰器处理后的函数。

              通过装饰器,开发者可以在保持代码整洁的同时,灵活且高效地扩展程序的功能。


              带参数的装饰器

              装饰器函数也可以接受参数,但是需要在原有的装饰器外再套一层装饰器。

              例如:

              实例

              import time



              def runtime(n:int):#定义一个装饰装饰器的装饰函数,他可以接受参数
               def decorator(func):#定义一个装饰器函数,接受一个函数func作为参数
                 def wrapper(*args, **kwargs): # 包装函数wrapper,这里接受所有参数
                 
                     # 这里是在调用原始函数前添加的新功能
                     starttime= time.time() #获取开始执行的时间
                 
                     # 在包装函数中调用原始函数(可以不调用)
                     result = func(*args, **kwargs) # 函数传递的参数为包装函数接受的所有参数
                 
                     # 这里是在调用原始函数后添加的新功能
                     endtime= time.time() #获取结束执行的时间

                     print(f"函数{func.__name__}运行时间:{endtime-starttime}秒") #输出函数运行的时间
                     print("装饰器传递过来的参数为:",n)

                     return result # 返回函数运行的结果
                 return wrapper # 返回包装函数
               return decorator # 返回装饰器函数


              # 使用装饰器装饰一个函数,现在运行这个函数时,会运行装饰器的代码,然后再由装饰器运行这个func
              # (如果装饰器不调用这个函数,而是调用别的函数,就可以替换掉原有函数的功能)
              @runtime(1)
              def sleepfunc(arg1, arg2):
               time.sleep(2)
               return arg1 + arg2

              print(sleepfunc(1, 2))

              运行结果为:

              函数sleepfunc运行时间:2.000138521194458秒
              装饰器传递过来的参数为: 1
              3

              以上代码中 ​runtime​函数是一个带参数的装饰器,它接受一个整数参数 ​n​,然后返回一个装饰器函数。该装饰器函数内部定义了 ​wrapper​ 函数,我们可以在装饰器内部获取到这个参数n(内层函数可以获取到外层函数的变量),上面只是简单的打印了这个参数,我们也可以让这个参数参与到代码运行中。

              比如​flask​的​@app.route​就可以接受参数来决定该方法是​get​还是​post​。


              类装饰器

              除了函数装饰器,Python 还支持类装饰器。类装饰器是包含 ​call​ 方法的类,它接受一个函数作为参数,并返回一个新的函数。

              实例

              class DecoratorClass:
               def __init__(self, func):
                 self.func = func

               def __call__(self, *args, **kwargs):
                 # 在调用原始函数之前/之后执行的代码
                 result = self.func(*args, **kwargs)
                 # 在调用原始函数之后执行的代码
                 return result
                 
              @DecoratorClass
              def my_function():
                 pass
              ## turtle.py: a Tkinter based turtle graphics module for Python# Version 1.1b - 4. 5. 2009## Copyright (C) 2006 - 2010  Gregor Lingl# email: glingl@aon.at## This software is provided 'as-is', without any express or implied# warranty.  In no event will the authors be held liable for any damages# arising from the use of this software.## Permission is granted to anyone to use this software for any purpose,# including commercial applications, and to alter it and redistribute it# freely, subject to the following restrictions:## 1. The origin of this software must not be misrepresented; you must not#    claim that you wrote the original software. If you use this software#    in a product, an acknowledgment in the product documentation would be#    appreciated but is not required.# 2. Altered source versions must be plainly marked as such, and must not be#    misrepresented as being the original software.# 3. This notice may not be removed or altered from any source distribution."""Turtle graphics is a popular way for introducing programming tokids. It was part of the original Logo programming language developedby Wally Feurzig and Seymour Papert in 1966.Imagine a robotic turtle starting at (0, 0) in the x-y plane. After an ``import turtle``, give itthe command turtle.forward(15), and it moves (on-screen!) 15 pixels inthe direction it is facing, drawing a line as it moves. Give it thecommand turtle.right(25), and it rotates in-place 25 degrees clockwise.By combining together these and similar commands, intricate shapes andpictures can easily be drawn.----- turtle.pyThis module is an extended reimplementation of turtle.py from thePython standard distribution up to Python 2.5. (See: https://www.python.org)It tries to keep the merits of turtle.py and to be (nearly) 100%compatible with it. This means in the first place to enable thelearning programmer to use all the commands, classes and methodsinteractively when using the module from within IDLE run withthe -n switch.Roughly it has the following features added:- Better animation of the turtle movements, especially of turning the  turtle. So the turtles can more easily be used as a visual feedback  instrument by the (beginning) programmer.- Different turtle shapes, gif-images as turtle shapes, user defined  and user controllable turtle shapes, among them compound  (multicolored) shapes. Turtle shapes can be stretched and tilted, which  makes turtles very versatile geometrical objects.- Fine control over turtle movement and screen updates via delay(),  and enhanced tracer() and speed() methods.- Aliases for the most commonly used commands, like fd for forward etc.,  following the early Logo traditions. This reduces the boring work of  typing long sequences of commands, which often occur in a natural way  when kids try to program fancy pictures on their first encounter with  turtle graphics.- Turtles now have an undo()-method with configurable undo-buffer.- Some simple commands/methods for creating event driven programs  (mouse-, key-, timer-events). Especially useful for programming games.- A scrollable Canvas class. The default scrollable Canvas can be  extended interactively as needed while playing around with the turtle(s).- A TurtleScreen class with methods controlling background color or  background image, window and canvas size and other properties of the  TurtleScreen.- There is a method, setworldcoordinates(), to install a user defined  coordinate-system for the TurtleScreen.- The implementation uses a 2-vector class named Vec2D, derived from tuple.  This class is public, so it can be imported by the application programmer,  which makes certain types of computations very natural and compact.- Appearance of the TurtleScreen and the Turtles at startup/import can be  configured by means of a turtle.cfg configuration file.  The default configuration mimics the appearance of the old turtle module.- If configured appropriately the module reads in docstrings from a docstring  dictionary in some different language, supplied separately  and replaces  the English ones by those read in. There is a utility function  write_docstringdict() to write a dictionary with the original (English)  docstrings to disc, so it can serve as a template for translations.Behind the scenes there are some features included with possibleextensions in mind. These will be commented and documented elsewhere."""_ver = "turtle 1.1b- - for Python 3.1   -  4. 5. 2009"# print(_ver)import tkinter as TKimport typesimport mathimport timeimport inspectimport sysfrom os.path import isfile, split, joinfrom copy import deepcopyfrom tkinter import simpledialog_tg_classes = ['ScrolledCanvas', 'TurtleScreen', 'Screen',               'RawTurtle', 'Turtle', 'RawPen', 'Pen', 'Shape', 'Vec2D']_tg_screen_functions = ['addshape', 'bgcolor', 'bgpic', 'bye',        'clearscreen', 'colormode', 'delay', 'exitonclick', 'getcanvas',        'getshapes', 'listen', 'mainloop', 'mode', 'numinput',        'onkey', 'onkeypress', 'onkeyrelease', 'onscreenclick', 'ontimer',        'register_shape', 'resetscreen', 'screensize', 'setup',        'setworldcoordinates', 'textinput', 'title', 'tracer', 'turtles', 'update',        'window_height', 'window_width']_tg_turtle_functions = ['back', 'backward', 'begin_fill', 'begin_poly', 'bk',        'circle', 'clear', 'clearstamp', 'clearstamps', 'clone', 'color',        'degrees', 'distance', 'dot', 'down', 'end_fill', 'end_poly', 'fd',        'fillcolor', 'filling', 'forward', 'get_poly', 'getpen', 'getscreen', 'get_shapepoly',        'getturtle', 'goto', 'heading', 'hideturtle', 'home', 'ht', 'isdown',        'isvisible', 'left', 'lt', 'onclick', 'ondrag', 'onrelease', 'pd',        'pen', 'pencolor', 'pendown', 'pensize', 'penup', 'pos', 'position',        'pu', 'radians', 'right', 'reset', 'resizemode', 'rt',        'seth', 'setheading', 'setpos', 'setposition', 'settiltangle',        'setundobuffer', 'setx', 'sety', 'shape', 'shapesize', 'shapetransform', 'shearfactor', 'showturtle',        'speed', 'st', 'stamp', 'tilt', 'tiltangle', 'towards',        'turtlesize', 'undo', 'undobufferentries', 'up', 'width',        'write', 'xcor', 'ycor']_tg_utilities = ['write_docstringdict', 'done']__all__ = (_tg_classes + _tg_screen_functions + _tg_turtle_functions +           _tg_utilities + ['Terminator']) # + _math_functions)_alias_list = ['addshape', 'backward', 'bk', 'fd', 'ht', 'lt', 'pd', 'pos',               'pu', 'rt', 'seth', 'setpos', 'setposition', 'st',               'turtlesize', 'up', 'width']_CFG = {"width" : 0.5,               # Screen        "height" : 0.75,        "canvwidth" : 400,        "canvheight": 300,        "leftright": None,        "topbottom": None,        "mode": "standard",          # TurtleScreen        "colormode": 1.0,        "delay": 10,        "undobuffersize": 1000,      # RawTurtle        "shape": "classic",        "pencolor" : "black",        "fillcolor" : "black",        "resizemode" : "noresize",        "visible" : True,        "language": "english",        # docstrings        "exampleturtle": "turtle",        "examplescreen": "screen",        "title": "Python Turtle Graphics",        "using_IDLE": False       }def config_dict(filename):    """Convert content of config-file into dictionary."""    with open(filename, "r") as f:        cfglines = f.readlines()    cfgdict = {}    for line in cfglines:        line = line.strip()        if not line or line.startswith("#"):            continue        try:            key, value = line.split("=")        except ValueError:            print("Bad line in config-file %s:
              %s" % (filename,line))            continue        key = key.strip()        value = value.strip()        if value in ["True", "False", "None", "''", '""']:            value = eval(value)        else:            try:                if "." in value:                    value = float(value)                else:                    value = int(value)            except ValueError:                pass # value need not be converted        cfgdict[key] = value    return cfgdictdef readconfig(cfgdict):    """Read config-files, change configuration-dict accordingly.    If there is a turtle.cfg file in the current working directory,    read it from there. If this contains an importconfig-value,    say 'myway', construct filename turtle_mayway.cfg else use    turtle.cfg and read it from the import-directory, where    turtle.py is located.    Update configuration dictionary first according to config-file,    in the import directory, then according to config-file in the    current working directory.    If no config-file is found, the default configuration is used.    """    default_cfg = "turtle.cfg"    cfgdict1 = {}    cfgdict2 = {}    if isfile(default_cfg):        cfgdict1 = config_dict(default_cfg)    if "importconfig" in cfgdict1:        default_cfg = "turtle_%s.cfg" % cfgdict1["importconfig"]    try:        head, tail = split(__file__)        cfg_file2 = join(head, default_cfg)    except Exception:        cfg_file2 = ""    if isfile(cfg_file2):        cfgdict2 = config_dict(cfg_file2)    _CFG.update(cfgdict2)    _CFG.update(cfgdict1)try:    readconfig(_CFG)except Exception:    print ("No configfile read, reason unknown")class Vec2D(tuple):    """A 2 dimensional vector class, used as a helper class    for implementing turtle graphics.    May be useful for turtle graphics programs also.    Derived from tuple, so a vector is a tuple!    Provides (for a, b vectors, k number):       a+b vector addition       a-b vector subtraction       a*b inner product       k*a and a*k multiplication with scalar       |a| absolute value of a       a.rotate(angle) rotation    """    def __new__(cls, x, y):        return tuple.__new__(cls, (x, y))    def __add__(self, other):        return Vec2D(self[0]+other[0], self[1]+other[1])    def __mul__(self, other):        if isinstance(other, Vec2D):            return self[0]*other[0]+self[1]*other[1]        return Vec2D(self[0]*other, self[1]*other)    def __rmul__(self, other):        if isinstance(other, int) or isinstance(other, float):            return Vec2D(self[0]*other, self[1]*other)        return NotImplemented    def __sub__(self, other):        return Vec2D(self[0]-other[0], self[1]-other[1])    def __neg__(self):        return Vec2D(-self[0], -self[1])    def __abs__(self):        return (self[0]**2 + self[1]**2)**0.5    def rotate(self, angle):        """rotate self counterclockwise by angle        """        perp = Vec2D(-self[1], self[0])        angle = angle * math.pi / 180.0        c, s = math.cos(angle), math.sin(angle)        return Vec2D(self[0]*c+perp[0]*s, self[1]*c+perp[1]*s)    def __getnewargs__(self):        return (self[0], self[1])    def __repr__(self):        return "(%.2f,%.2f)" % self################################################################################# From here up to line    : Tkinter - Interface for turtle.py            ###### May be replaced by an interface to some different graphics toolkit     ################################################################################### helper functions for Scrolled Canvas, to forward Canvas-methods## to ScrolledCanvas classdef __methodDict(cls, _dict):    """helper function for Scrolled Canvas"""    baseList = list(cls.__bases__)    baseList.reverse()    for _super in baseList:        __methodDict(_super, _dict)    for key, value in cls.__dict__.items():        if type(value) == types.FunctionType:            _dict[key] = valuedef __methods(cls):    """helper function for Scrolled Canvas"""    _dict = {}    __methodDict(cls, _dict)    return _dict.keys()__stringBody = (    'def %(method)s(self, *args, **kw): return ' +    'self.%(attribute)s.%(method)s(*args, **kw)')def __forwardmethods(fromClass, toClass, toPart, exclude = ()):    ### MANY CHANGES ###    _dict_1 = {}    __methodDict(toClass, _dict_1)    _dict = {}    mfc = __methods(fromClass)    for ex in _dict_1.keys():        if ex[:1] == '_' or ex[-1:] == '_' or ex in exclude or ex in mfc:            pass        else:            _dict[ex] = _dict_1[ex]    for method, func in _dict.items():        d = {'method': method, 'func': func}        if isinstance(toPart, str):            execString =                 __stringBody % {'method' : method, 'attribute' : toPart}        exec(execString, d)        setattr(fromClass, method, d[method])   ### NEWU!class ScrolledCanvas(TK.Frame):    """Modeled after the scrolled canvas class from Grayons's Tkinter book.    Used as the default canvas, which pops up automatically when    using turtle graphics functions or the Turtle class.    """    def __init__(self, master, width=500, height=350,                                          canvwidth=600, canvheight=500):        TK.Frame.__init__(self, master, width=width, height=height)        self._rootwindow = self.winfo_toplevel()        self.width, self.height = width, height        self.canvwidth, self.canvheight = canvwidth, canvheight        self.bg = "white"        self._canvas = TK.Canvas(master, width=width, height=height,                                 bg=self.bg, relief=TK.SUNKEN, borderwidth=2)        self.hscroll = TK.Scrollbar(master, command=self._canvas.xview,                                    orient=TK.HORIZONTAL)        self.vscroll = TK.Scrollbar(master, command=self._canvas.yview)        self._canvas.configure(xscrollcommand=self.hscroll.set,                               yscrollcommand=self.vscroll.set)        self.rowconfigure(0, weight=1, minsize=0)        self.columnconfigure(0, weight=1, minsize=0)        self._canvas.grid(padx=1, in_ = self, pady=1, row=0,                column=0, rowspan=1, columnspan=1, sticky='news')        self.vscroll.grid(padx=1, in_ = self, pady=1, row=0,                column=1, rowspan=1, columnspan=1, sticky='news')        self.hscroll.grid(padx=1, in_ = self, pady=1, row=1,                column=0, rowspan=1, columnspan=1, sticky='news')        self.reset()        self._rootwindow.bind('<Configure>', self.onResize)    def reset(self, canvwidth=None, canvheight=None, bg = None):        """Adjust canvas and scrollbars according to given canvas size."""        if canvwidth:            self.canvwidth = canvwidth        if canvheight:            self.canvheight = canvheight        if bg:            self.bg = bg        self._canvas.config(bg=bg,                        scrollregion=(-self.canvwidth//2, -self.canvheight//2,                                       self.canvwidth//2, self.canvheight//2))        self._canvas.xview_moveto(0.5*(self.canvwidth - self.width + 30) /                                                               self.canvwidth)        self._canvas.yview_moveto(0.5*(self.canvheight- self.height + 30) /                                                              self.canvheight)        self.adjustScrolls()    def adjustScrolls(self):        """ Adjust scrollbars according to window- and canvas-size.        """        cwidth = self._canvas.winfo_width()        cheight = self._canvas.winfo_height()        self._canvas.xview_moveto(0.5*(self.canvwidth-cwidth)/self.canvwidth)        self._canvas.yview_moveto(0.5*(self.canvheight-cheight)/self.canvheight)        if cwidth < self.canvwidth or cheight < self.canvheight:            self.hscroll.grid(padx=1, in_ = self, pady=1, row=1,                              column=0, rowspan=1, columnspan=1, sticky='news')            self.vscroll.grid(padx=1, in_ = self, pady=1, row=0,                              column=1, rowspan=1, columnspan=1, sticky='news')        else:            self.hscroll.grid_forget()            self.vscroll.grid_forget()    def onResize(self, event):        """self-explanatory"""        self.adjustScrolls()    def bbox(self, *args):        """ 'forward' method, which canvas itself has inherited...        """        return self._canvas.bbox(*args)    def cget(self, *args, **kwargs):        """ 'forward' method, which canvas itself has inherited...        """        return self._canvas.cget(*args, **kwargs)    def config(self, *args, **kwargs):        """ 'forward' method, which canvas itself has inherited...        """        self._canvas.config(*args, **kwargs)    def bind(self, *args, **kwargs):        """ 'forward' method, which canvas itself has inherited...        """        self._canvas.bind(*args, **kwargs)    def unbind(self, *args, **kwargs):        """ 'forward' method, which canvas itself has inherited...        """        self._canvas.unbind(*args, **kwargs)    def focus_force(self):        """ 'forward' method, which canvas itself has inherited...        """        self._canvas.focus_force()__forwardmethods(ScrolledCanvas, TK.Canvas, '_canvas')class _Root(TK.Tk):    """Root class for Screen based on Tkinter."""    def __init__(self):        TK.Tk.__init__(self)    def setupcanvas(self, width, height, cwidth, cheight):        self._canvas = ScrolledCanvas(self, width, height, cwidth, cheight)        self._canvas.pack(expand=1, fill="both")    def _getcanvas(self):        return self._canvas    def set_geometry(self, width, height, startx, starty):        self.geometry("%dx%d%+d%+d"%(width, height, startx, starty))    def ondestroy(self, destroy):        self.wm_protocol("WM_DELETE_WINDOW", destroy)    def win_width(self):        return self.winfo_screenwidth()    def win_height(self):        return self.winfo_screenheight()Canvas = TK.Canvasclass TurtleScreenBase(object):    """Provide the basic graphics functionality.       Interface between Tkinter and turtle.py.       To port turtle.py to some different graphics toolkit       a corresponding TurtleScreenBase class has to be implemented.    """    def _blankimage(self):        """return a blank image object        """        img = TK.PhotoImage(width=1, height=1, master=self.cv)        img.blank()        return img    def _image(self, filename):        """return an image object containing the        imagedata from a gif-file named filename.        """        return TK.PhotoImage(file=filename, master=self.cv)    def __init__(self, cv):        self.cv = cv        if isinstance(cv, ScrolledCanvas):            w = self.cv.canvwidth            h = self.cv.canvheight        else:  # expected: ordinary TK.Canvas            w = int(self.cv.cget("width"))            h = int(self.cv.cget("height"))            self.cv.config(scrollregion = (-w//2, -h//2, w//2, h//2 ))        self.canvwidth = w        self.canvheight = h        self.xscale = self.yscale = 1.0    def _createpoly(self):        """Create an invisible polygon item on canvas self.cv)        """        return self.cv.create_polygon((0, 0, 0, 0, 0, 0), fill="", outline="")    def _drawpoly(self, polyitem, coordlist, fill=None,                  outline=None, width=None, top=False):        """Configure polygonitem polyitem according to provided        arguments:        coordlist is sequence of coordinates        fill is filling color        outline is outline color        top is a boolean value, which specifies if polyitem        will be put on top of the canvas' displaylist so it        will not be covered by other items.        """        cl = []        for x, y in coordlist:            cl.append(x * self.xscale)            cl.append(-y * self.yscale)        self.cv.coords(polyitem, *cl)        if fill is not None:            self.cv.itemconfigure(polyitem, fill=fill)        if outline is not None:            self.cv.itemconfigure(polyitem, outline=outline)        if width is not None:            self.cv.itemconfigure(polyitem, width=width)        if top:            self.cv.tag_raise(polyitem)    def _createline(self):        """Create an invisible line item on canvas self.cv)        """        return self.cv.create_line(0, 0, 0, 0, fill="", width=2,                                   capstyle = TK.ROUND)    def _drawline(self, lineitem, coordlist=None,                  fill=None, width=None, top=False):        """Configure lineitem according to provided arguments:        coordlist is sequence of coordinates        fill is drawing color        width is width of drawn line.        top is a boolean value, which specifies if polyitem        will be put on top of the canvas' displaylist so it        will not be covered by other items.        """        if coordlist is not None:            cl = []            for x, y in coordlist:                cl.append(x * self.xscale)                cl.append(-y * self.yscale)            self.cv.coords(lineitem, *cl)        if fill is not None:            self.cv.itemconfigure(lineitem, fill=fill)        if width is not None:            self.cv.itemconfigure(lineitem, width=width)        if top:            self.cv.tag_raise(lineitem)    def _delete(self, item):        """Delete graphics item from canvas.        If item is"all" delete all graphics items.        """        self.cv.delete(item)    def _update(self):        """Redraw graphics items on canvas        """        self.cv.update()    def _delay(self, delay):        """Delay subsequent canvas actions for delay ms."""        self.cv.after(delay)    def _iscolorstring(self, color):        """Check if the string color is a legal Tkinter color string.        """        try:            rgb = self.cv.winfo_rgb(color)            ok = True        except TK.TclError:            ok = False        return ok    def _bgcolor(self, color=None):        """Set canvas' backgroundcolor if color is not None,        else return backgroundcolor."""        if color is not None:            self.cv.config(bg = color)            self._update()        else:            return self.cv.cget("bg")    def _write(self, pos, txt, align, font, pencolor):        """Write txt at pos in canvas with specified font        and color.        Return text item and x-coord of right bottom corner        of text's bounding box."""        x, y = pos        x = x * self.xscale        y = y * self.yscale        anchor = {"left":"sw", "center":"s", "right":"se" }        item = self.cv.create_text(x-1, -y, text = txt, anchor = anchor[align],                                        fill = pencolor, font = font)        x0, y0, x1, y1 = self.cv.bbox(item)        self.cv.update()        return item, x1-1##    def _dot(self, pos, size, color):##        """may be implemented for some other graphics toolkit"""    def _onclick(self, item, fun, num=1, add=None):        """Bind fun to mouse-click event on turtle.        fun must be a function with two arguments, the coordinates        of the clicked point on the canvas.        num, the number of the mouse-button defaults to 1        """        if fun is None:            self.cv.tag_unbind(item, "<Button-%s>" % num)        else:            def eventfun(event):                x, y = (self.cv.canvasx(event.x)/self.xscale,                        -self.cv.canvasy(event.y)/self.yscale)                fun(x, y)            self.cv.tag_bind(item, "<Button-%s>" % num, eventfun, add)    def _onrelease(self, item, fun, num=1, add=None):        """Bind fun to mouse-button-release event on turtle.        fun must be a function with two arguments, the coordinates        of the point on the canvas where mouse button is released.        num, the number of the mouse-button defaults to 1        If a turtle is clicked, first _onclick-event will be performed,        then _onscreensclick-event.        """        if fun is None:            self.cv.tag_unbind(item, "<Button%s-ButtonRelease>" % num)        else:            def eventfun(event):                x, y = (self.cv.canvasx(event.x)/self.xscale,                        -self.cv.canvasy(event.y)/self.yscale)                fun(x, y)            self.cv.tag_bind(item, "<Button%s-ButtonRelease>" % num,                             eventfun, add)    def _ondrag(self, item, fun, num=1, add=None):        """Bind fun to mouse-move-event (with pressed mouse button) on turtle.        fun must be a function with two arguments, the coordinates of the        actual mouse position on the canvas.        num, the number of the mouse-button defaults to 1        Every sequence of mouse-move-events on a turtle is preceded by a        mouse-click event on that turtle.        """        if fun is None:            self.cv.tag_unbind(item, "<Button%s-Motion>" % num)        else:            def eventfun(event):                try:                    x, y = (self.cv.canvasx(event.x)/self.xscale,                           -self.cv.canvasy(event.y)/self.yscale)                    fun(x, y)                except Exception:                    pass            self.cv.tag_bind(item, "<Button%s-Motion>" % num, eventfun, add)    def _onscreenclick(self, fun, num=1, add=None):        """Bind fun to mouse-click event on canvas.        fun must be a function with two arguments, the coordinates        of the clicked point on the canvas.        num, the number of the mouse-button defaults to 1        If a turtle is clicked, first _onclick-event will be performed,        then _onscreensclick-event.        """        if fun is None:            self.cv.unbind("<Button-%s>" % num)        else:            def eventfun(event):                x, y = (self.cv.canvasx(event.x)/self.xscale,                        -self.cv.canvasy(event.y)/self.yscale)                fun(x, y)            self.cv.bind("<Button-%s>" % num, eventfun, add)    def _onkeyrelease(self, fun, key):        """Bind fun to key-release event of key.        Canvas must have focus. See method listen        """        if fun is None:            self.cv.unbind("<KeyRelease-%s>" % key, None)        else:            def eventfun(event):                fun()            self.cv.bind("<KeyRelease-%s>" % key, eventfun)    def _onkeypress(self, fun, key=None):        """If key is given, bind fun to key-press event of key.        Otherwise bind fun to any key-press.        Canvas must have focus. See method listen.        """        if fun is None:            if key is None:                self.cv.unbind("<KeyPress>", None)            else:                self.cv.unbind("<KeyPress-%s>" % key, None)        else:            def eventfun(event):                fun()            if key is None:                self.cv.bind("<KeyPress>", eventfun)            else:                self.cv.bind("<KeyPress-%s>" % key, eventfun)    def _listen(self):        """Set focus on canvas (in order to collect key-events)        """        self.cv.focus_force()    def _ontimer(self, fun, t):        """Install a timer, which calls fun after t milliseconds.        """        if t == 0:            self.cv.after_idle(fun)        else:            self.cv.after(t, fun)    def _createimage(self, image):        """Create and return image item on canvas.        """        return self.cv.create_image(0, 0, image=image)    def _drawimage(self, item, pos, image):        """Configure image item as to draw image object        at position (x,y) on canvas)        """        x, y = pos        self.cv.coords(item, (x * self.xscale, -y * self.yscale))        self.cv.itemconfig(item, image=image)    def _setbgpic(self, item, image):        """Configure image item as to draw image object        at center of canvas. Set item to the first item        in the displaylist, so it will be drawn below        any other item ."""        self.cv.itemconfig(item, image=image)        self.cv.tag_lower(item)    def _type(self, item):        """Return 'line' or 'polygon' or 'image' depending on        type of item.        """        return self.cv.type(item)    def _pointlist(self, item):        """returns list of coordinate-pairs of points of item        Example (for insiders):        >>> from turtle import *        >>> getscreen()._pointlist(getturtle().turtle._item)        [(0.0, 9.9999999999999982), (0.0, -9.9999999999999982),        (9.9999999999999982, 0.0)]        >>> """        cl = self.cv.coords(item)        pl = [(cl[i], -cl[i+1]) for i in range(0, len(cl), 2)]        return  pl    def _setscrollregion(self, srx1, sry1, srx2, sry2):        self.cv.config(scrollregion=(srx1, sry1, srx2, sry2))    def _rescale(self, xscalefactor, yscalefactor):        items = self.cv.find_all()        for item in items:            coordinates = list(self.cv.coords(item))            newcoordlist = []            while coordinates:                x, y = coordinates[:2]                newcoordlist.append(x * xscalefactor)                newcoordlist.append(y * yscalefactor)                coordinates = coordinates[2:]            self.cv.coords(item, *newcoordlist)    def _resize(self, canvwidth=None, canvheight=None, bg=None):        """Resize the canvas the turtles are drawing on. Does        not alter the drawing window.        """        # needs amendment        if not isinstance(self.cv, ScrolledCanvas):            return self.canvwidth, self.canvheight        if canvwidth is canvheight is bg is None:            return self.cv.canvwidth, self.cv.canvheight        if canvwidth is not None:            self.canvwidth = canvwidth        if canvheight is not None:            self.canvheight = canvheight        self.cv.reset(canvwidth, canvheight, bg)    def _window_size(self):        """ Return the width and height of the turtle window.        """        width = self.cv.winfo_width()        if width <= 1:  # the window isn't managed by a geometry manager            width = self.cv['width']        height = self.cv.winfo_height()        if height <= 1: # the window isn't managed by a geometry manager            height = self.cv['height']        return width, height    def mainloop(self):        """Starts event loop - calling Tkinter's mainloop function.        No argument.        Must be last statement in a turtle graphics program.        Must NOT be used if a script is run from within IDLE in -n mode        (No subprocess) - for interactive use of turtle graphics.        Example (for a TurtleScreen instance named screen):        >>> screen.mainloop()        """        self.cv.tk.mainloop()    def textinput(self, title, prompt):        """Pop up a dialog window for input of a string.        Arguments: title is the title of the dialog window,        prompt is a text mostly describing what information to input.        Return the string input        If the dialog is canceled, return None.        Example (for a TurtleScreen instance named screen):        >>> screen.textinput("NIM", "Name of first player:")        """        return simpledialog.askstring(title, prompt, parent=self.cv)    def numinput(self, title, prompt, default=None, minval=None, maxval=None):        """Pop up a dialog window for input of a number.        Arguments: title is the title of the dialog window,        prompt is a text mostly describing what numerical information to input.        default: default value        minval: minimum value for input        maxval: maximum value for input        The number input must be in the range minval .. maxval if these are        given. If not, a hint is issued and the dialog remains open for        correction. Return the number input.        If the dialog is canceled,  return None.        Example (for a TurtleScreen instance named screen):        >>> screen.numinput("Poker", "Your stakes:", 1000, minval=10, maxval=10000)        """        return simpledialog.askfloat(title, prompt, initialvalue=default,                                     minvalue=minval, maxvalue=maxval,                                     parent=self.cv)#################################################################################                  End of Tkinter - interface                            #################################################################################class Terminator (Exception):    """Will be raised in TurtleScreen.update, if _RUNNING becomes False.    This stops execution of a turtle graphics script.    Main purpose: use in the Demo-Viewer turtle.Demo.py.    """    passclass TurtleGraphicsError(Exception):    """Some TurtleGraphics Error    """class Shape(object):    """Data structure modeling shapes.    attribute _type is one of "polygon", "image", "compound"    attribute _data is - depending on _type a poygon-tuple,    an image or a list constructed using the addcomponent method.    """    def __init__(self, type_, data=None):        self._type = type_        if type_ == "polygon":            if isinstance(data, list):                data = tuple(data)        elif type_ == "image":            if isinstance(data, str):                if data.lower().endswith(".gif") and isfile(data):                    data = TurtleScreen._image(data)                # else data assumed to be Photoimage        elif type_ == "compound":            data = []        else:            raise TurtleGraphicsError("There is no shape type %s" % type_)        self._data = data    def addcomponent(self, poly, fill, outline=None):        """Add component to a shape of type compound.        Arguments: poly is a polygon, i. e. a tuple of number pairs.        fill is the fillcolor of the component,        outline is the outline color of the component.        call (for a Shapeobject namend s):        --   s.addcomponent(((0,0), (10,10), (-10,10)), "red", "blue")        Example:        >>> poly = ((0,0),(10,-5),(0,10),(-10,-5))        >>> s = Shape("compound")        >>> s.addcomponent(poly, "red", "blue")        >>> # .. add more components and then use register_shape()        """        if self._type != "compound":            raise TurtleGraphicsError("Cannot add component to %s Shape"                                                                % self._type)        if outline is None:            outline = fill        self._data.append([poly, fill, outline])class Tbuffer(object):    """Ring buffer used as undobuffer for RawTurtle objects."""    def __init__(self, bufsize=10):        self.bufsize = bufsize        self.buffer = [[None]] * bufsize        self.ptr = -1        self.cumulate = False    def reset(self, bufsize=None):        if bufsize is None:            for i in range(self.bufsize):                self.buffer[i] = [None]        else:            self.bufsize = bufsize            self.buffer = [[None]] * bufsize        self.ptr = -1    def push(self, item):        if self.bufsize > 0:            if not self.cumulate:                self.ptr = (self.ptr + 1) % self.bufsize                self.buffer[self.ptr] = item            else:                self.buffer[self.ptr].append(item)    def pop(self):        if self.bufsize > 0:            item = self.buffer[self.ptr]            if item is None:                return None            else:                self.buffer[self.ptr] = [None]                self.ptr = (self.ptr - 1) % self.bufsize                return (item)    def nr_of_items(self):        return self.bufsize - self.buffer.count([None])    def __repr__(self):        return str(self.buffer) + " " + str(self.ptr)class TurtleScreen(TurtleScreenBase):    """Provides screen oriented methods like setbg etc.    Only relies upon the methods of TurtleScreenBase and NOT    upon components of the underlying graphics toolkit -    which is Tkinter in this case.    """    _RUNNING = True    def __init__(self, cv, mode=_CFG["mode"],                 colormode=_CFG["colormode"], delay=_CFG["delay"]):        TurtleScreenBase.__init__(self, cv)        self._shapes = {                   "arrow" : Shape("polygon", ((-10,0), (10,0), (0,10))),                  "turtle" : Shape("polygon", ((0,16), (-2,14), (-1,10), (-4,7),                              (-7,9), (-9,8), (-6,5), (-7,1), (-5,-3), (-8,-6),                              (-6,-8), (-4,-5), (0,-7), (4,-5), (6,-8), (8,-6),                              (5,-3), (7,1), (6,5), (9,8), (7,9), (4,7), (1,10),                              (2,14))),                  "circle" : Shape("polygon", ((10,0), (9.51,3.09), (8.09,5.88),                              (5.88,8.09), (3.09,9.51), (0,10), (-3.09,9.51),                              (-5.88,8.09), (-8.09,5.88), (-9.51,3.09), (-10,0),                              (-9.51,-3.09), (-8.09,-5.88), (-5.88,-8.09),                              (-3.09,-9.51), (-0.00,-10.00), (3.09,-9.51),                              (5.88,-8.09), (8.09,-5.88), (9.51,-3.09))),                  "square" : Shape("polygon", ((10,-10), (10,10), (-10,10),                              (-10,-10))),                "triangle" : Shape("polygon", ((10,-5.77), (0,11.55),                              (-10,-5.77))),                  "classic": Shape("polygon", ((0,0),(-5,-9),(0,-7),(5,-9))),                   "blank" : Shape("image", self._blankimage())                  }        self._bgpics = {"nopic" : ""}        self._mode = mode        self._delayvalue = delay        self._colormode = _CFG["colormode"]        self._keys = []        self.clear()        if sys.platform == 'darwin':            # Force Turtle window to the front on OS X. This is needed because            # the Turtle window will show behind the Terminal window when you            # start the demo from the command line.            rootwindow = cv.winfo_toplevel()            rootwindow.call('wm', 'attributes', '.', '-topmost', '1')            rootwindow.call('wm', 'attributes', '.', '-topmost', '0')    def clear(self):        """Delete all drawings and all turtles from the TurtleScreen.        No argument.        Reset empty TurtleScreen to its initial state: white background,        no backgroundimage, no eventbindings and tracing on.        Example (for a TurtleScreen instance named screen):        >>> screen.clear()        Note: this method is not available as function.        """        self._delayvalue = _CFG["delay"]        self._colormode = _CFG["colormode"]        self._delete("all")        self._bgpic = self._createimage("")        self._bgpicname = "nopic"        self._tracing = 1        self._updatecounter = 0        self._turtles = []        self.bgcolor("white")        for btn in 1, 2, 3:            self.onclick(None, btn)        self.onkeypress(None)        for key in self._keys[:]:            self.onkey(None, key)            self.onkeypress(None, key)        Turtle._pen = None    def mode(self, mode=None):        """Set turtle-mode ('standard', 'logo' or 'world') and perform reset.        Optional argument:        mode -- one of the strings 'standard', 'logo' or 'world'        Mode 'standard' is compatible with turtle.py.        Mode 'logo' is compatible with most Logo-Turtle-Graphics.        Mode 'world' uses userdefined 'worldcoordinates'. *Attention*: in        this mode angles appear distorted if x/y unit-ratio doesn't equal 1.        If mode is not given, return the current mode.             Mode      Initial turtle heading     positive angles         ------------|-------------------------|-------------------          'standard'    to the right (east)       counterclockwise            'logo'        upward    (north)         clockwise        Examples:        >>> mode('logo')   # resets turtle heading to north        >>> mode()        'logo'        """        if mode is None:            return self._mode        mode = mode.lower()        if mode not in ["standard", "logo", "world"]:            raise TurtleGraphicsError("No turtle-graphics-mode %s" % mode)        self._mode = mode        if mode in ["standard", "logo"]:            self._setscrollregion(-self.canvwidth//2, -self.canvheight//2,                                       self.canvwidth//2, self.canvheight//2)            self.xscale = self.yscale = 1.0        self.reset()    def setworldcoordinates(self, llx, lly, urx, ury):        """Set up a user defined coordinate-system.        Arguments:        llx -- a number, x-coordinate of lower left corner of canvas        lly -- a number, y-coordinate of lower left corner of canvas        urx -- a number, x-coordinate of upper right corner of canvas        ury -- a number, y-coordinate of upper right corner of canvas        Set up user coodinat-system and switch to mode 'world' if necessary.        This performs a screen.reset. If mode 'world' is already active,        all drawings are redrawn according to the new coordinates.        But ATTENTION: in user-defined coordinatesystems angles may appear        distorted. (see Screen.mode())        Example (for a TurtleScreen instance named screen):        >>> screen.setworldcoordinates(-10,-0.5,50,1.5)        >>> for _ in range(36):        ...     left(10)        ...     forward(0.5)        """        if self.mode() != "world":            self.mode("world")        xspan = float(urx - llx)        yspan = float(ury - lly)        wx, wy = self._window_size()        self.screensize(wx-20, wy-20)        oldxscale, oldyscale = self.xscale, self.yscale        self.xscale = self.canvwidth / xspan        self.yscale = self.canvheight / yspan        srx1 = llx * self.xscale        sry1 = -ury * self.yscale        srx2 = self.canvwidth + srx1        sry2 = self.canvheight + sry1        self._setscrollregion(srx1, sry1, srx2, sry2)        self._rescale(self.xscale/oldxscale, self.yscale/oldyscale)        self.update()    def register_shape(self, name, shape=None):        """Adds a turtle shape to TurtleScreen's shapelist.        Arguments:        (1) name is the name of a gif-file and shape is None.            Installs the corresponding image shape.            !! Image-shapes DO NOT rotate when turning the turtle,            !! so they do not display the heading of the turtle!        (2) name is an arbitrary string and shape is a tuple            of pairs of coordinates. Installs the corresponding            polygon shape        (3) name is an arbitrary string and shape is a            (compound) Shape object. Installs the corresponding            compound shape.        To use a shape, you have to issue the command shape(shapename).        call: register_shape("turtle.gif")        --or: register_shape("tri", ((0,0), (10,10), (-10,10)))        Example (for a TurtleScreen instance named screen):        >>> screen.register_shape("triangle", ((5,-3),(0,5),(-5,-3)))        """        if shape is None:            # image            if name.lower().endswith(".gif"):                shape = Shape("image", self._image(name))            else:                raise TurtleGraphicsError("Bad arguments for register_shape.
              "                                          + "Use  help(register_shape)" )        elif isinstance(shape, tuple):            shape = Shape("polygon", shape)        ## else shape assumed to be Shape-instance        self._shapes[name] = shape    def _colorstr(self, color):        """Return color string corresponding to args.        Argument may be a string or a tuple of three        numbers corresponding to actual colormode,        i.e. in the range 0<=n<=colormode.        If the argument doesn't represent a color,        an error is raised.        """        if len(color) == 1:            color = color[0]        if isinstance(color, str):            if self._iscolorstring(color) or color == "":                return color            else:                raise TurtleGraphicsError("bad color string: %s" % str(color))        try:            r, g, b = color        except (TypeError, ValueError):            raise TurtleGraphicsError("bad color arguments: %s" % str(color))        if self._colormode == 1.0:            r, g, b = [round(255.0*x) for x in (r, g, b)]        if not ((0 <= r <= 255) and (0 <= g <= 255) and (0 <= b <= 255)):            raise TurtleGraphicsError("bad color sequence: %s" % str(color))        return "#%02x%02x%02x" % (r, g, b)    def _color(self, cstr):        if not cstr.startswith("#"):            return cstr        if len(cstr) == 7:            cl = [int(cstr[i:i+2], 16) for i in (1, 3, 5)]        elif len(cstr) == 4:            cl = [16*int(cstr[h], 16) for h in cstr[1:]]        else:            raise TurtleGraphicsError("bad colorstring: %s" % cstr)        return tuple(c * self._colormode/255 for c in cl)    def colormode(self, cmode=None):        """Return the colormode or set it to 1.0 or 255.        Optional argument:        cmode -- one of the values 1.0 or 255        r, g, b values of colortriples have to be in range 0..cmode.        Example (for a TurtleScreen instance named screen):        >>> screen.colormode()        1.0        >>> screen.colormode(255)        >>> pencolor(240,160,80)        """        if cmode is None:            return self._colormode        if cmode == 1.0:            self._colormode = float(cmode)        elif cmode == 255:            self._colormode = int(cmode)    def reset(self):        """Reset all Turtles on the Screen to their initial state.        No argument.        Example (for a TurtleScreen instance named screen):        >>> screen.reset()        """        for turtle in self._turtles:            turtle._setmode(self._mode)            turtle.reset()    def turtles(self):        """Return the list of turtles on the screen.        Example (for a TurtleScreen instance named screen):        >>> screen.turtles()        [<turtle.Turtle object at 0x00E11FB0>]        """        return self._turtles    def bgcolor(self, *args):        """Set or return backgroundcolor of the TurtleScreen.        Arguments (if given): a color string or three numbers        in the range 0..colormode or a 3-tuple of such numbers.        Example (for a TurtleScreen instance named screen):        >>> screen.bgcolor("orange")        >>> screen.bgcolor()        'orange'        >>> screen.bgcolor(0.5,0,0.5)        >>> screen.bgcolor()        '#800080'        """        if args:            color = self._colorstr(args)        else:            color = None        color = self._bgcolor(color)        if color is not None:            color = self._color(color)        return color    def tracer(self, n=None, delay=None):        """Turns turtle animation on/off and set delay for update drawings.        Optional arguments:        n -- nonnegative  integer        delay -- nonnegative  integer        If n is given, only each n-th regular screen update is really performed.        (Can be used to accelerate the drawing of complex graphics.)        Second arguments sets delay value (see RawTurtle.delay())        Example (for a TurtleScreen instance named screen):        >>> screen.tracer(8, 25)        >>> dist = 2        >>> for i in range(200):        ...     fd(dist)        ...     rt(90)        ...     dist += 2        """        if n is None:            return self._tracing        self._tracing = int(n)        self._updatecounter = 0        if delay is not None:            self._delayvalue = int(delay)        if self._tracing:            self.update()    def delay(self, delay=None):        """ Return or set the drawing delay in milliseconds.        Optional argument:        delay -- positive integer        Example (for a TurtleScreen instance named screen):        >>> screen.delay(15)        >>> screen.delay()        15        """        if delay is None:            return self._delayvalue        self._delayvalue = int(delay)    def _incrementudc(self):        """Increment update counter."""        if not TurtleScreen._RUNNING:            TurtleScreen._RUNNING = True            raise Terminator        if self._tracing > 0:            self._updatecounter += 1            self._updatecounter %= self._tracing    def update(self):        """Perform a TurtleScreen update.        """        tracing = self._tracing        self._tracing = True        for t in self.turtles():            t._update_data()            t._drawturtle()        self._tracing = tracing        self._update()    def window_width(self):        """ Return the width of the turtle window.        Example (for a TurtleScreen instance named screen):        >>> screen.window_width()        640        """        return self._window_size()[0]    def window_height(self):        """ Return the height of the turtle window.        Example (for a TurtleScreen instance named screen):        >>> screen.window_height()        480        """        return self._window_size()[1]    def getcanvas(self):        """Return the Canvas of this TurtleScreen.        No argument.        Example (for a Screen instance named screen):        >>> cv = screen.getcanvas()        >>> cv        <turtle.ScrolledCanvas instance at 0x010742D8>        """        return self.cv    def getshapes(self):        """Return a list of names of all currently available turtle shapes.        No argument.        Example (for a TurtleScreen instance named screen):        >>> screen.getshapes()        ['arrow', 'blank', 'circle', ... , 'turtle']        """        return sorted(self._shapes.keys())    def onclick(self, fun, btn=1, add=None):        """Bind fun to mouse-click event on canvas.        Arguments:        fun -- a function with two arguments, the coordinates of the               clicked point on the canvas.        btn -- the number of the mouse-button, defaults to 1        Example (for a TurtleScreen instance named screen)        >>> screen.onclick(goto)        >>> # Subsequently clicking into the TurtleScreen will        >>> # make the turtle move to the clicked point.        >>> screen.onclick(None)        """        self._onscreenclick(fun, btn, add)    def onkey(self, fun, key):        """Bind fun to key-release event of key.        Arguments:        fun -- a function with no arguments        key -- a string: key (e.g. "a") or key-symbol (e.g. "space")        In order to be able to register key-events, TurtleScreen        must have focus. (See method listen.)        Example (for a TurtleScreen instance named screen):        >>> def f():        ...     fd(50)        ...     lt(60)        ...        >>> screen.onkey(f, "Up")        >>> screen.listen()        Subsequently the turtle can be moved by repeatedly pressing        the up-arrow key, consequently drawing a hexagon        """        if fun is None:            if key in self._keys:                self._keys.remove(key)        elif key not in self._keys:            self._keys.append(key)        self._onkeyrelease(fun, key)    def onkeypress(self, fun, key=None):        """Bind fun to key-press event of key if key is given,        or to any key-press-event if no key is given.        Arguments:        fun -- a function with no arguments        key -- a string: key (e.g. "a") or key-symbol (e.g. "space")        In order to be able to register key-events, TurtleScreen        must have focus. (See method listen.)        Example (for a TurtleScreen instance named screen        and a Turtle instance named turtle):        >>> def f():        ...     fd(50)        ...     lt(60)        ...        >>> screen.onkeypress(f, "Up")        >>> screen.listen()        Subsequently the turtle can be moved by repeatedly pressing        the up-arrow key, or by keeping pressed the up-arrow key.        consequently drawing a hexagon.        """        if fun is None:            if key in self._keys:                self._keys.remove(key)        elif key is not None and key not in self._keys:            self._keys.append(key)        self._onkeypress(fun, key)    def listen(self, xdummy=None, ydummy=None):        """Set focus on TurtleScreen (in order to collect key-events)        No arguments.        Dummy arguments are provided in order        to be able to pass listen to the onclick method.        Example (for a TurtleScreen instance named screen):        >>> screen.listen()        """        self._listen()    def ontimer(self, fun, t=0):        """Install a timer, which calls fun after t milliseconds.        Arguments:        fun -- a function with no arguments.        t -- a number >= 0        Example (for a TurtleScreen instance named screen):        >>> running = True        >>> def f():        ...     if running:        ...             fd(50)        ...             lt(60)        ...             screen.ontimer(f, 250)        ...        >>> f()   # makes the turtle marching around        >>> running = False        """        self._ontimer(fun, t)    def bgpic(self, picname=None):        """Set background image or return name of current backgroundimage.        Optional argument:        picname -- a string, name of a gif-file or "nopic".        If picname is a filename, set the corresponding image as background.        If picname is "nopic", delete backgroundimage, if present.        If picname is None, return the filename of the current backgroundimage.        Example (for a TurtleScreen instance named screen):        >>> screen.bgpic()        'nopic'        >>> screen.bgpic("landscape.gif")        >>> screen.bgpic()        'landscape.gif'        """        if picname is None:            return self._bgpicname        if picname not in self._bgpics:            self._bgpics[picname] = self._image(picname)        self._setbgpic(self._bgpic, self._bgpics[picname])        self._bgpicname = picname    def screensize(self, canvwidth=None, canvheight=None, bg=None):        """Resize the canvas the turtles are drawing on.        Optional arguments:        canvwidth -- positive integer, new width of canvas in pixels        canvheight --  positive integer, new height of canvas in pixels        bg -- colorstring or color-tuple, new backgroundcolor        If no arguments are given, return current (canvaswidth, canvasheight)        Do not alter the drawing window. To observe hidden parts of        the canvas use the scrollbars. (Can make visible those parts        of a drawing, which were outside the canvas before!)        Example (for a Turtle instance named turtle):        >>> turtle.screensize(2000,1500)        >>> # e.g. to search for an erroneously escaped turtle ;-)        """        return self._resize(canvwidth, canvheight, bg)    onscreenclick = onclick    resetscreen = reset    clearscreen = clear    addshape = register_shape    onkeyrelease = onkeyclass TNavigator(object):    """Navigation part of the RawTurtle.    Implements methods for turtle movement.    """    START_ORIENTATION = {        "standard": Vec2D(1.0, 0.0),        "world"   : Vec2D(1.0, 0.0),        "logo"    : Vec2D(0.0, 1.0)  }    DEFAULT_MODE = "standard"    DEFAULT_ANGLEOFFSET = 0    DEFAULT_ANGLEORIENT = 1    def __init__(self, mode=DEFAULT_MODE):        self._angleOffset = self.DEFAULT_ANGLEOFFSET        self._angleOrient = self.DEFAULT_ANGLEORIENT        self._mode = mode        self.undobuffer = None        self.degrees()        self._mode = None        self._setmode(mode)        TNavigator.reset(self)    def reset(self):        """reset turtle to its initial values        Will be overwritten by parent class        """        self._position = Vec2D(0.0, 0.0)        self._orient =  TNavigator.START_ORIENTATION[self._mode]    def _setmode(self, mode=None):        """Set turtle-mode to 'standard', 'world' or 'logo'.        """        if mode is None:            return self._mode        if mode not in ["standard", "logo", "world"]:            return        self._mode = mode        if mode in ["standard", "world"]:            self._angleOffset = 0            self._angleOrient = 1        else: # mode == "logo":            self._angleOffset = self._fullcircle/4.            self._angleOrient = -1    def _setDegreesPerAU(self, fullcircle):        """Helper function for degrees() and radians()"""        self._fullcircle = fullcircle        self._degreesPerAU = 360/fullcircle        if self._mode == "standard":            self._angleOffset = 0        else:            self._angleOffset = fullcircle/4.    def degrees(self, fullcircle=360.0):        """ Set angle measurement units to degrees.        Optional argument:        fullcircle -  a number        Set angle measurement units, i. e. set number        of 'degrees' for a full circle. Default value is        360 degrees.        Example (for a Turtle instance named turtle):        >>> turtle.left(90)        >>> turtle.heading()        90        Change angle measurement unit to grad (also known as gon,        grade, or gradian and equals 1/100-th of the right angle.)        >>> turtle.degrees(400.0)        >>> turtle.heading()        100        """        self._setDegreesPerAU(fullcircle)    def radians(self):        """ Set the angle measurement units to radians.        No arguments.        Example (for a Turtle instance named turtle):        >>> turtle.heading()        90        >>> turtle.radians()        >>> turtle.heading()        1.5707963267948966        """        self._setDegreesPerAU(2*math.pi)    def _go(self, distance):        """move turtle forward by specified distance"""        ende = self._position + self._orient * distance        self._goto(ende)    def _rotate(self, angle):        """Turn turtle counterclockwise by specified angle if angle > 0."""        angle *= self._degreesPerAU        self._orient = self._orient.rotate(angle)    def _goto(self, end):        """move turtle to position end."""        self._position = end    def forward(self, distance):        """Move the turtle forward by the specified distance.        Aliases: forward | fd        Argument:        distance -- a number (integer or float)        Move the turtle forward by the specified distance, in the direction        the turtle is headed.        Example (for a Turtle instance named turtle):        >>> turtle.position()        (0.00, 0.00)        >>> turtle.forward(25)        >>> turtle.position()        (25.00,0.00)        >>> turtle.forward(-75)        >>> turtle.position()        (-50.00,0.00)        """        self._go(distance)    def back(self, distance):        """Move the turtle backward by distance.        Aliases: back | backward | bk        Argument:        distance -- a number        Move the turtle backward by distance, opposite to the direction the        turtle is headed. Do not change the turtle's heading.        Example (for a Turtle instance named turtle):        >>> turtle.position()        (0.00, 0.00)        >>> turtle.backward(30)        >>> turtle.position()        (-30.00, 0.00)        """        self._go(-distance)    def right(self, angle):        """Turn turtle right by angle units.        Aliases: right | rt        Argument:        angle -- a number (integer or float)        Turn turtle right by angle units. (Units are by default degrees,        but can be set via the degrees() and radians() functions.)        Angle orientation depends on mode. (See this.)        Example (for a Turtle instance named turtle):        >>> turtle.heading()        22.0        >>> turtle.right(45)        >>> turtle.heading()        337.0        """        self._rotate(-angle)    def left(self, angle):        """Turn turtle left by angle units.        Aliases: left | lt        Argument:        angle -- a number (integer or float)        Turn turtle left by angle units. (Units are by default degrees,        but can be set via the degrees() and radians() functions.)        Angle orientation depends on mode. (See this.)        Example (for a Turtle instance named turtle):        >>> turtle.heading()        22.0        >>> turtle.left(45)        >>> turtle.heading()        67.0        """        self._rotate(angle)    def pos(self):        """Return the turtle's current location (x,y), as a Vec2D-vector.        Aliases: pos | position        No arguments.        Example (for a Turtle instance named turtle):        >>> turtle.pos()        (0.00, 240.00)        """        return self._position    def xcor(self):        """ Return the turtle's x coordinate.        No arguments.        Example (for a Turtle instance named turtle):        >>> reset()        >>> turtle.left(60)        >>> turtle.forward(100)        >>> print turtle.xcor()        50.0        """        return self._position[0]    def ycor(self):        """ Return the turtle's y coordinate        ---        No arguments.        Example (for a Turtle instance named turtle):        >>> reset()        >>> turtle.left(60)        >>> turtle.forward(100)        >>> print turtle.ycor()        86.6025403784        """        return self._position[1]    def goto(self, x, y=None):        """Move turtle to an absolute position.        Aliases: setpos | setposition | goto:        Arguments:        x -- a number      or     a pair/vector of numbers        y -- a number             None        call: goto(x, y)         # two coordinates        --or: goto((x, y))       # a pair (tuple) of coordinates        --or: goto(vec)          # e.g. as returned by pos()        Move turtle to an absolute position. If the pen is down,        a line will be drawn. The turtle's orientation does not change.        Example (for a Turtle instance named turtle):        >>> tp = turtle.pos()        >>> tp        (0.00, 0.00)        >>> turtle.setpos(60,30)        >>> turtle.pos()        (60.00,30.00)        >>> turtle.setpos((20,80))        >>> turtle.pos()        (20.00,80.00)        >>> turtle.setpos(tp)        >>> turtle.pos()        (0.00,0.00)        """        if y is None:            self._goto(Vec2D(*x))        else:            self._goto(Vec2D(x, y))    def home(self):        """Move turtle to the origin - coordinates (0,0).        No arguments.        Move turtle to the origin - coordinates (0,0) and set its        heading to its start-orientation (which depends on mode).        Example (for a Turtle instance named turtle):        >>> turtle.home()        """        self.goto(0, 0)        self.setheading(0)    def setx(self, x):        """Set the turtle's first coordinate to x        Argument:        x -- a number (integer or float)        Set the turtle's first coordinate to x, leave second coordinate        unchanged.        Example (for a Turtle instance named turtle):        >>> turtle.position()        (0.00, 240.00)        >>> turtle.setx(10)        >>> turtle.position()        (10.00, 240.00)        """        self._goto(Vec2D(x, self._position[1]))    def sety(self, y):        """Set the turtle's second coordinate to y        Argument:        y -- a number (integer or float)        Set the turtle's first coordinate to x, second coordinate remains        unchanged.        Example (for a Turtle instance named turtle):        >>> turtle.position()        (0.00, 40.00)        >>> turtle.sety(-10)        >>> turtle.position()        (0.00, -10.00)        """        self._goto(Vec2D(self._position[0], y))    def distance(self, x, y=None):        """Return the distance from the turtle to (x,y) in turtle step units.        Arguments:        x -- a number   or  a pair/vector of numbers   or   a turtle instance        y -- a number       None                            None        call: distance(x, y)         # two coordinates        --or: distance((x, y))       # a pair (tuple) of coordinates        --or: distance(vec)          # e.g. as returned by pos()        --or: distance(mypen)        # where mypen is another turtle        Example (for a Turtle instance named turtle):        >>> turtle.pos()        (0.00, 0.00)        >>> turtle.distance(30,40)        50.0        >>> pen = Turtle()        >>> pen.forward(77)        >>> turtle.distance(pen)        77.0        """        if y is not None:            pos = Vec2D(x, y)        if isinstance(x, Vec2D):            pos = x        elif isinstance(x, tuple):            pos = Vec2D(*x)        elif isinstance(x, TNavigator):            pos = x._position        return abs(pos - self._position)    def towards(self, x, y=None):        """Return the angle of the line from the turtle's position to (x, y).        Arguments:        x -- a number   or  a pair/vector of numbers   or   a turtle instance        y -- a number       None                            None        call: distance(x, y)         # two coordinates        --or: distance((x, y))       # a pair (tuple) of coordinates        --or: distance(vec)          # e.g. as returned by pos()        --or: distance(mypen)        # where mypen is another turtle        Return the angle, between the line from turtle-position to position        specified by x, y and the turtle's start orientation. (Depends on        modes - "standard" or "logo")        Example (for a Turtle instance named turtle):        >>> turtle.pos()        (10.00, 10.00)        >>> turtle.towards(0,0)        225.0        """        if y is not None:            pos = Vec2D(x, y)        if isinstance(x, Vec2D):            pos = x        elif isinstance(x, tuple):

              在 Python3 的丰富生态环境中,众多第三方库为开发者提供了强大的工具支持。

              然而,对于初学者而言,如何高效地找到并使用这些工具成为关键问题。

              传统学习方式效率低下,而 AI 的出现为这一问题提供了更优的解决方案。


              本文将重点介绍阿里云技术团队打造的智能编码助手 —— 通义灵码,它基于通义大模型,为 Python3 开发者提供了全方位的编程辅助功能。


              一、通义灵码简介

              通义灵码具备以下实用功能:

              • 代码续写和优化 :根据现有代码上下文,智能生成行级或函数级的代码建议,帮助程序员快速完成代码编写,并对代码进行优化,提高代码质量和执行效率。

              • 自然语言描述生成代码 :程序员可以通过自然语言描述需求,通义灵码能够将其转化为相应的代码,大大简化了代码编写过程,尤其适用于复杂功能的实现。
              • 注释生成和代码解释 :自动生成代码注释,方便程序员及团队成员更好地理解代码逻辑和功能;同时,能够对代码进行详细解释,包括分析代码片段的具体功能,并生成相应的图来帮助理解代码。
              • 单元测试生成 :根据代码自动生成单元测试用例,确保代码的可靠性和稳定性,提高测试效率。
              • 研发智能问答 :作为基础和核心功能,程序员可以通过与通义灵码的问答对话,获取所需的技术支持和解决方案,就像拥有一位智能的编程助手。
              • 代码问题修复 :能够识别代码中的潜在问题,并提供修复建议,帮助程序员及时解决代码错误和漏洞。


                市面上虽有诸多 AI 工具,如 DeepSeek、ChatGPT 等,也可作为智能编码助手,但通义千问的性能更优,且通义灵码专为编程相关语料设计,更懂编程行业!

                通义灵码支持多种开发环境,包括 JetBrains IDEs、Visual StudioCode、Visual Studio,以及远程开发场景(Remote SSH、Docker、WSL、Web IDE)。

                安装后登录账号即可开启智能编码之旅。

                Python3 开发工具众多,VS、VSCode 和 PyCharm 都是不错的选择,安装和使用方式类似,本文以 VSCode 为例进行介绍。


                二、安装指南

                确保已安装 VSCode 后,按照以下步骤进行插件安装:

                VSCode三端的插件安装方式基本一致,本文以 Windows 为例,介绍如何在VSCode中安装通义灵码插件。

                对于 VSCode 而言,通义灵码的使用非常简单,只需要在VSCode中按以下步骤安装插件即可:

                1. 打开 VSCode,点击左侧的扩展图标,进入插件市场。

                2. 在搜索框中输入 “TONGYI Lingma”,找到对应的插件。

                3. 点击 “安装” 按钮,VSCode 会自动下载并安装通义灵码插件。IMG_256

                4. 安装完成后,VSCode 左侧会新增一个通义灵码图标,点击即可进入插件界面。
                  IMG_258
                5. 首次使用时,需点击 “立即登录” 并同意用户协议,之后可选择账号密码、手机号、支付宝、阿里云、淘宝、钉钉等登录方式。IMG_259
                  登录后即可使用通义灵码的各项功能。


                三、功能演示

                (一)代码续写

                通义灵码提供行级和函数级的代码补全功能。在 IDE 编辑器区编写代码时,开启自动云端生成模式,它会根据当前代码文件及相关代码文件的上下文,自动生成代码建议。

                此时你可以使用快捷键采纳、废弃,或查看不同的代码建议。

                IMG_260

                同时,编码过程中也可通过快捷键 ​Alt​+​P​ 手动触发生成代码建议。

                可以使用以下快捷键进行操作:

                操作macOSWindows
                接受行间代码建议TabTab
                废弃行间代码建议escesc
                查看上一个行间推荐结果⌥(option) + [Alt+[
                查看下一个行间推荐结果⌥(option)+]Alt+]
                手动触发行间代码建议⌥(option)+PAlt+P


                (二)代码注释

                通义灵码可为选中的代码逐行添加注释,省去编写开发文档的困扰,方便其他开发者快速理解代码逻辑和功能。IMG_261


                (三)代码解释

                通义灵码的代码解释功能强大,AI 会根据你选择的代码作为上下文,深入分析代码片段的具体功能,并生成相应的图来帮助理解代码,这对于复杂算法或业务逻辑的代码理解非常有帮助。

                IMG_262


                (四)代码优化

                通义灵码能够审查代码并给出优化建议,甚至直接返回优化后的代码,帮助程序员提高代码质量和执行效率。

                例如,对于存在性能瓶颈的循环结构或算法实现,通义灵码可以提供更高效的替代方案。

                IMG_263

                IMG_264


                (五)生成测试代码

                Python3 在软件测试领域应用广泛,拥有众多第三方库支持功能测试和自动化测试,本身也提供了强大的单元测试工具(unittest 和 pytest)。

                然而,测试用例的设计至关重要且具有一定的难度。

                通义灵码可以自动生成测试代码,根据被测代码的功能和逻辑,智能生成相应的测试用例,覆盖各种输入情况和边界条件,大大减轻了测试人员的工作量,提高了测试的全面性和准确性。


                (六)智能问答

                Python 的第三方库极其丰富,但传统通过访问 pypi 找到需要的项目的方式,要求开发者知道项目用途。

                而在实际开发中,我们可能不知道用什么工具以及工具的使用方法。

                此时,通义灵码的智能问答功能就能提供巨大帮助。

                你可以向通义灵码提问关于 Python 库的使用、特定功能的实现方法、代码报错的解决办法等问题,它会基于其强大的知识库为你提供详细的解答和示例代码。

                IMG_265

                智能问答现在可以选择不同的大模型,如通义千问的大模型,也可以选择时下很火的 deepseek 大模型。

                不过,编程相关的通义系列的大模型更加专业,针对 Python3 编程问题的理解和回答更加精准。


                (七)会话创建和清理

                通义灵码的智能问答功能会将你之前提问的问题及给出的答案作为上下文进行解析。

                IMG_266

                这种模式虽能带来更好的提问体验,但有时也会弄巧成拙。因此,在必要时,请进行会话清理:

                • 清理会话:在对话框中输入 ​/clearContext​,然后点击确定即可。

                  IMG_267

                • 创建新会话:在智能问答的右上角有一个圆形 ​+​ 号按钮,点击即可创建新对话。

                  屏幕截图 2025-03-19 153250


                (八)代码小技巧

                通义灵码生成的代码一般都会在右上角有这四个小按钮,分别对应着插入、复制、新建和合并的功能:

                • 插入 :会把 AI 生成的代码替换到我们选中的代码位置,一般在代码注释和代码优化中应用。
                • 复制 :则是复制 AI 生成的代码,我们可以自己选择插入的位置。
                • 新建 :则是新建一个文件,把 AI 生成的代码放进去,一般而言生成测试代码会选择新建一个文件夹存放。
                • 合并 :则是把代码黏贴到文件中,比如黏贴到选中的代码后,一般我们在智能问答中得到我们需要的代码可以用合并。


                (九)AI程序员

                对于新手程序员而言,一个好的导师往往比一堆课本有用,但并非每个老手程序员都愿意帮你改代码。

                通义灵码的 AI 程序员功能可作为初学者的导师,陪伴你进行编程。

                IMG_268

                你可以像产品经理一样向 AI 提出需求,让 AI 帮你写代码,例如实现一个特定功能的函数、设计一个类的结构等,AI 会根据你的描述生成相应的代码,并解释代码的逻辑和实现细节,帮助你快速学习和成长。

                IMG_269

                通义灵码作为一款专为编程设计的智能编码助手,凭借其强大的功能和专业的性能,在 Python 开发领域为程序员提供了全方位的辅助支持,有效提高了开发效率和代码质量。

                随着 AI 技术的不断发展和模型的持续优化,通义灵码必将在未来的编程开发中发挥更加重要的作用,成为开发者不可或缺的得力助手。


                基础语法

                向用户显示输出

                print 函数用于显示或打印输出。

                print("Hello, World!")

                从用户获取输入

                input 函数用于从用户获取输入,输入内容默认为字符串类型。

                name = input("Enter your name: ")

                若需要其他数据类型的输入,需要进行类型转换。

                # 获取整数输入age = int(input("Enter your age: "))# 获取浮点数输入height = float(input("Enter your height: "))

                range 函数

                range 函数返回一个数字序列,例如,range(0, n) 生成从 0 到 n-1 的数字。

                # 生成 0 到 9 的数字序列numbers = list(range(10))print(numbers)  # 输出: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]# 生成 2 到 10 的偶数序列even_numbers = list(range(2, 11, 2))print(even_numbers)  # 输出: [2, 4, 6, 8, 10]

                注释

                注释用于提高代码的可读性,不会被编译器或解释器执行。

                单行注释

                # 这是一个单行注释

                多行注释

                """这是一个多行注释,可以跨越多行。"""

                转义序列

                转义序列是在字符串字面量或字符中使用时,不表示自身的字符序列,而是被翻译成另一个字符。

                换行符

                print("Hello
                World!")  # 输出: Hello
                World!(两行)

                反斜杠

                print("This is a backslash: \")  # 输出: This is a backslash: 

                单引号

                print("This is a single quote: '")  # 输出: This is a single quote: '

                制表符

                print("Name	Age	Country")  # 输出: Name	Age	Country

                退格符

                print("HelloWorld!")  # 输出: HelloWorld!(退格)

                八进制值

                print("110145154154157")  # 输出: Hello(八进制表示)

                十六进制值

                print("x48x65x6cx6cx6f")  # 输出: Hello(十六进制表示)

                回车符

                print("Hello
                World!")  # 输出: World!(回车,覆盖前面的内容)

                字符串

                Python 字符串是由字符组成的序列,可以通过索引单独访问每个字符。

                字符串创建

                可以使用单引号或双引号创建字符串。

                string1 = 'Hello'string2 = "World"

                索引

                字符串中每个字符的位置从 0 开始,依次递增。

                string = "Hello"print(string[0])  # 输出: Hprint(string[4])  # 输出: o

                切片

                切片用于从给定字符串中获取子字符串。

                string = "Hello, World!"print(string[0:5])  # 输出: Helloprint(string[7:])   # 输出: World!print(string[:5])   # 输出: Helloprint(string[::2])  # 输出: Hlo, Wr!

                字符串方法

                isalnum() 方法

                如果字符串中的所有字符都是字母数字,则返回 True,否则返回 False。

                print("Hello123".isalnum())  # 输出: Trueprint("Hello 123".isalnum()) # 输出: False

                isalpha() 方法

                如果字符串中的所有字符都是字母,则返回 True,否则返回 False。

                print("Hello".isalpha())  # 输出: Trueprint("Hello123".isalpha()) # 输出: False

                isdecimal() 方法

                如果字符串中的所有字符都是十进制数字,则返回 True,否则返回 False。

                print("12345".isdecimal())  # 输出: Trueprint("12.34".isdecimal())  # 输出: False

                isdigit() 方法

                如果字符串中的所有字符都是数字,则返回 True,否则返回 False。

                print("12345".isdigit())  # 输出: Trueprint("Hello123".isdigit()) # 输出: False

                islower() 方法

                如果字符串中的所有字符都是小写字母,则返回 True,否则返回 False。

                print("hello".islower())  # 输出: Trueprint("Hello".islower())  # 输出: False

                isspace() 方法

                如果字符串中的所有字符都是空白字符,则返回 True,否则返回 False。

                print("   ".isspace())  # 输出: Trueprint("Hello".isspace()) # 输出: False

                isupper() 方法

                如果字符串中的所有字符都是大写字母,则返回 True,否则返回 False。

                print("HELLO".isupper())  # 输出: Trueprint("Hello".isupper())  # 输出: False

                lower() 方法

                将字符串转换为小写。

                print("Hello".lower())  # 输出: hello

                upper() 方法

                将字符串转换为大写。

                print("hello".upper())  # 输出: HELLO

                strip() 方法

                移除字符串开头和结尾的空白字符。

                print("   Hello, World!   ".strip())  # 输出: Hello, World!

                列表

                Python 列表是用方括号括起来的逗号分隔值的集合,可以包含不同数据类型的元素。

                列表创建

                list1 = [1, 2, 3, 4, 5]list2 = ["apple", "banana", "cherry"]list3 = [1, "apple", 3.14, True]

                索引

                列表中每个元素的位置从 0 开始,依次递增。

                list = [10, 20, 30, 40, 50]print(list[0])  # 输出: 10print(list[4])  # 输出: 50

                列表方法

                index() 方法

                返回指定值的第一个元素的索引。

                list = [10, 20, 30, 40, 50]print(list.index(30))  # 输出: 2

                append() 方法

                在列表末尾添加一个元素。

                list = [10, 20, 30]list.append(40)print(list)  # 输出: [10, 20, 30, 40]

                extend() 方法

                将一个给定列表(或任何可迭代对象)的元素添加到当前列表的末尾。

                list1 = [10, 20, 30]list2 = [40, 50]list1.extend(list2)print(list1)  # 输出: [10, 20, 30, 40, 50]

                insert() 方法

                在指定位置添加一个元素。

                list = [10, 20, 40, 50]list.insert(2, 30)print(list)  # 输出: [10, 20, 30, 40, 50]

                pop() 方法

                移除指定位置的元素并返回它。

                list = [10, 20, 30, 40, 50]removed_element = list.pop(2)print(removed_element)  # 输出: 30print(list)             # 输出: [10, 20, 40, 50]

                remove() 方法

                移除列表中第一个出现的指定值。

                list = [10, 20, 30, 40, 50]list.remove(30)print(list)  # 输出: [10, 20, 40, 50]

                clear() 方法

                移除列表中的所有元素。

                list = [10, 20, 30]list.clear()print(list)  # 输出: []

                count() 方法

                返回具有指定值的元素数量。

                list = [10, 20, 10, 30, 10]print(list.count(10))  # 输出: 3

                reverse() 方法

                反转列表的顺序。

                list = [10, 20, 30, 40, 50]list.reverse()print(list)  # 输出: [50, 40, 30, 20, 10]

                sort() 方法

                对列表进行排序。

                list = [30, 10, 40, 20, 50]list.sort()print(list)  # 输出: [10, 20, 30, 40, 50]

                元组

                元组是用括号括起来的逗号分隔值的集合,可以包含不同数据类型的元素。

                元组创建

                tuple1 = (1, 2, 3, 4, 5)tuple2 = ("apple", "banana", "cherry")tuple3 = (1, "apple", 3.14, True)

                索引

                元组中每个元素的位置从 0 开始,依次递增。

                tuple = (10, 20, 30, 40, 50)print(tuple[0])  # 输出: 10print(tuple[4])  # 输出: 50

                元组方法

                count() 方法

                返回元组中指定值出现的次数。

                tuple = (10, 20, 10, 30, 10)print(tuple.count(10))  # 输出: 3

                index() 方法

                在元组中查找指定值并返回其位置。

                tuple = (10, 20, 30, 40, 50)print(tuple.index(30))  # 输出: 2

                集合

                集合是用花括号括起来的多个值的集合,是无序且不带索引的。

                集合创建

                方法 1

                set1 = {"apple", "banana", "cherry"}

                方法 2

                set2 = set(["apple", "banana", "cherry"])

                集合方法

                add() 方法

                向集合中添加一个元素。

                set = {"apple", "banana", "cherry"}set.add("orange")print(set)  # 输出: {'apple', 'banana', 'cherry', 'orange'}

                clear() 方法

                移除集合中的所有元素。

                set = {"apple", "banana", "cherry"}set.clear()print(set)  # 输出: set()

                discard() 方法

                从集合中移除指定元素。

                set = {"apple", "banana", "cherry"}set.discard("banana")print(set)  # 输出: {'apple', 'cherry'}

                intersection() 方法

                返回两个或更多集合的交集。

                set1 = {"apple", "banana", "cherry"}set2 = {"google", "banana", "apple"}print(set1.intersection(set2))  # 输出: {'apple', 'banana'}

                issubset() 方法

                检查一个集合是否是另一个集合的子集。

                set1 = {"apple", "banana"}set2 = {"apple", "banana", "cherry"}print(set1.issubset(set2))  # 输出: True

                pop() 方法

                从集合中移除一个元素。

                set = {"apple", "banana", "cherry"}removed_element = set.pop()print(removed_element)  # 输出: 'apple'(或另一个随机元素)print(set)              # 输出: {'banana', 'cherry'}(或另一个组合)

                remove() 方法

                从集合中移除指定元素。

                set = {"apple", "banana", "cherry"}set.remove("banana")print(set)  # 输出: {'apple', 'cherry'}

                union() 方法

                返回两个或更多集合的并集。

                set1 = {"apple", "banana", "cherry"}set2 = {"google", "banana", "apple"}print(set1.union(set2))  # 输出: {'apple', 'banana', 'cherry', 'google'}

                字典

                字典是无序的键值对集合,用花括号括起来,要求字典中的键是唯一的。

                字典创建

                dict1 = {"name": "John", "age": 30, "city": "New York"}

                空字典

                可以通过放置两个花括号来创建一个空白字典。

                empty_dict = {}

                向字典中添加元素

                dict = {"name": "John", "age": 30}dict["city"] = "New York"print(dict)  # 输出: {'name': 'John', 'age': 30, 'city': 'New York'}

                更新字典中的元素

                如果指定的键已经存在,则其值将被更新。

                dict = {"name": "John", "age": 30}dict["age"] = 35print(dict)  # 输出: {'name': 'John', 'age': 35}

                从字典中删除元素

                使用 del 关键字删除指定的键值对。

                dict = {"name": "John", "age": 30, "city": "New York"}del dict["age"]print(dict)  # 输出: {'name': 'John', 'city': 'New York'}

                字典方法

                len() 方法

                返回字典中元素(键值对)的数量。

                dict = {"name": "John", "age": 30, "city": "New York"}print(len(dict))  # 输出: 3

                clear() 方法

                移除字典中的所有元素。

                dict = {"name": "John", "age": 30, "city": "New York"}dict.clear()print(dict)  # 输出: {}

                get() 方法

                返回指定键的值。

                dict = {"name": "John", "age": 30, "city": "New York"}print(dict.get("name"))  # 输出: John

                items() 方法

                返回一个包含字典中每个键值对的元组的列表。

                dict = {"name": "John", "age": 30, "city": "New York"}print(dict.items())  # 输出: dict_items([('name', 'John'), ('age', 30), ('city', 'New York')])

                keys() 方法

                返回一个包含字典中键的列表。

                dict = {"name": "John", "age": 30, "city": "New York"}print(dict.keys())  # 输出: dict_keys(['name', 'age', 'city'])

                values() 方法

                返回一个包含字典中值的列表。

                dict = {"name": "John", "age": 30, "city": "New York"}print(dict.values())  # 输出: dict_values(['John', 30, 'New York'])

                update() 方法

                用指定的键值对更新字典。

                dict1 = {"name": "John", "age": 30}dict2 = {"city": "New York", "country": "USA"}dict1.update(dict2)print(dict1)  # 输出: {'name': 'John', 'age': 30, 'city': 'New York', 'country': 'USA'}

                缩进

                在 Python 中,缩进是指代码块使用空格或制表符进行缩进,以便解释器能够轻松执行 Python 代码。

                缩进应用于条件语句和循环控制语句。缩进指定了根据条件要执行的代码块。

                条件语句

                ifelifelse 语句是 Python 中的条件语句,它们实现了选择结构(决策结构)。

                if 语句

                age = 20if age >= 18:    print("You are an adult.")

                if-else 语句

                age = 15if age >= 18:    print("You are an adult.")else:    print("You are a minor.")

                if-elif 语句

                score = 75if score >= 90:    print("A")elif score >= 80:    print("B")elif score >= 70:    print("C")else:    print("D")

                嵌套 if-else 语句

                num = 10if num > 0:    if num % 2 == 0:        print("Positive and even")    else:        print("Positive and odd")else:    print("Non-positive")

                Python 中的循环

                循环或迭代语句会反复执行一个语句,直到控制表达式为假。

                for 循环

                Python 的 for 循环设计用于处理任何序列(如列表或字符串)中的项。

                fruits = ["apple", "banana", "cherry"]for fruit in fruits:    print(fruit)

                while 循环

                while 循环是一种条件循环,只要条件为真,就会重复执行内部的指令。

                count = 0while count < 5:    print(count)    count += 1

                break 语句

                break 语句允许程序跳过代码的一部分。break 语句终止它所在的循环。

                for num in range(10):    if num == 5:        break    print(num)  # 输出: 0, 1, 2, 3, 4

                continue 语句

                continue 语句跳过循环的其余部分,并导致下一次迭代发生。

                for num in range(10):    if num % 2 == 0:        continue    print(num)  # 输出: 1, 3, 5, 7, 9

                函数

                函数是一段执行特定任务的代码块。你可以将参数传递给函数。它有助于使我们的代码更加有组织和易于管理。

                函数定义

                在定义函数之前使用 def 关键字。

                def greet(name):    print(f"Hello, {name}!")

                函数调用

                每当在程序中需要该代码块时,只需调用该函数的名称。如果在定义函数时传递了参数,那么在调用函数时也需要传递参数。

                greet("John")  # 输出: Hello, John!

                Python 函数中的 return 语句

                函数的 return 语句将指定的值或数据项返回给调用者。

                def add(a, b):    return a + bresult = add(3, 5)print(result)  # 输出: 8

                Python 函数中的参数

                参数是定义和调用函数时括号内传递的值。

                def greet(name, age):    print(f"Hello, {name}! You are {age} years old.")greet("John", 30)  # 输出: Hello, John! You are 30 years old.

                文件处理

                文件处理是指读取或写入文件中的数据。Python 提供了一些函数,允许我们操作文件中的数据。

                open() 函数

                file = open("example.txt", "r")

                模式

                1. r - 从文件中读取内容
                2. w - 向文件中写入内容
                3. a - 将内容追加到文件中
                4. r+ - 读取和写入数据到文件中。文件中的先前数据将被覆盖。
                5. w+ - 写入和读取数据。它将覆盖现有数据。
                6. a+ - 追加和从文件中读取数据。它不会覆盖现有数据。

                close() 函数

                file = open("example.txt", "r")# 操作文件file.close()

                read() 函数

                read 函数包含不同的方法:read()readline()readlines()

                • read() 返回文件中的所有内容。
                • readline() 返回文件中的一行。
                • readlines() 返回一个包含文件中各行的列表。
                file = open("example.txt", "r")content = file.read()print(content)file.close()

                write() 函数

                此函数将字符串序列写入文件。

                file = open("example.txt", "w")file.write("Hello, World!")file.close()

                异常处理

                异常是导致程序流程中断的不寻常情况。

                try 和 except

                这是 Python 中的基本 try-catch 块。当 try 块抛出错误时,控制权转到 except 块。

                try:    result = 10 / 0except ZeroDivisionError:    print("Cannot divide by zero.")

                else

                如果 try 块没有引发任何异常,并且代码成功运行,则执行 else 块。

                try:    result = 10 / 2except ZeroDivisionError:    print("Cannot divide by zero.")else:    print(f"Result: {result}")

                finally

                无论 try 块的代码是否成功运行,还是 except 块的代码被执行,finally 块的代码都将被执行。finally 块的代码将强制执行。

                try:    result = 10 / 2except ZeroDivisionError:    print("Cannot divide by zero.")finally:    print("This will always execute.")

                面向对象编程(OOP)

                这是一种主要关注使用对象和类的编程方法。对象可以是任何现实世界的实体。

                在 Python 中编写类的语法。

                class MyClass:    def __init__(self, name):        self.name = name    def greet(self):        print(f"Hello, {self.name}!")

                创建对象

                可以通过以下方式实例化对象:

                obj = MyClass("John")obj.greet()  # 输出: Hello, John!

                self 参数

                self 参数是类中任何函数的第一个参数。它可以有不同的名称,但在类中定义任何函数时必须有此参数,因为它用于访问类的其他数据成员。

                带有构造函数的类

                构造函数是类的特殊函数,用于初始化对象。

                class Person:    def __init__(self, name, age):        self.name = name        self.age = age

                Python 中的继承

                通过使用继承,我们可以创建一个类,该类使用另一个类的所有属性和行为。新类被称为派生类或子类,而被获取属性的类被称为基类或父类。

                它提供了代码的可重用性。

                继承的类型

                • 单继承
                • 多继承
                • 多级继承
                • 层次继承

                filter 函数

                filter 函数允许处理可迭代对象并提取满足给定条件的项。

                numbers = [1, 2, 3, 4, 5]even_numbers = list(filter(lambda x: x % 2 == 0, numbers))print(even_numbers)  # 输出: [2, 4]

                issubclass 函数

                用于查找一个类是否是指定类的子类。

                class Parent:    passclass Child(Parent):    passprint(issubclass(Child, Parent))  # 输出: True

                迭代器和生成器

                以下是 Python 编程语言的一些高级主题,如迭代器和生成器。

                迭代器

                用于创建可迭代对象的迭代器。

                numbers = [1, 2, 3, 4, 5]iterator = iter(numbers)print(next(iterator))  # 输出: 1print(next(iterator))  # 输出: 2

                生成器

                用于动态生成值。

                def count_up_to(n):    count = 1    while count <= n:        yield count        count += 1counter = count_up_to(5)print(next(counter))  # 输出: 1print(next(counter))  # 输出: 2

                装饰器

                装饰器用于修改函数或类的行为。它们通常在要装饰的函数定义之前调用。

                property 装饰器(getter)

                class Person:    def __init__(self, name):        self._name = name    @property    def name(self):        return self._name

                setter 装饰器

                用于设置属性 'name'。

                class Person:    def __init__(self, name):        self._name = name    @property    def name(self):        return self._name    @name.setter    def name(self, value):        self._name = value

                deleter 装饰器

                用于删除属性 'name'。

                class Person:    def __init__(self, name):        self._name = name    @property    def name(self):        return self._name    @name.deleter    def name(self):        del self._name