python入门到放弃

1.python基础知识

1.0 计算机组成原理和python基础知识

一,计算机基础

	1、计算机硬件组成
		1.1 一个程序的运行与三大核心硬件(cpu、内存、硬盘)的关系 (*****)
        
	2、操作系统 
		2.1 计算机体系的三层结构 (*****)
		2.2 平台与跨平台的概念 (*****)
        
	3、扫盲(***)
		cpu相关(x86-64代表的意义)
		存储器相关(IO问题)
		操作系统启动流程

1.1 计算机组成原理

二,计算机组成

1. 什么是计算机
		计算机俗称“电脑”,包含人对计算机的终极期望,能够真的像人脑一样去工作
    
    计算机(computer)俗称电脑,是现代一种用于高速计算的电子机器,可以进行数值计算,又可以进行逻辑判断,还具有存储记忆功能,且能够按照程序的运行,自动、高速处理数据,通俗理解就是一个存储和计算数据的电子设备。

计算机是20世纪最先进的科学技术发明之一。

2、为何要有计算机
	为了执行人类的程序,从而把人类解放出来

	大前提:计算机所有的组成都是模仿人的某一功能或器官

3、计算机的组成

计算机是由什么组成
	一个完整的计算机系统,是由硬件系统和软件系统两大部分组成的。
 
3-1. 硬件系统:
主要分为主机和外设两部分,是指那些构成计算机系统的物理实体,它们主要由各种各样的电子器件和机电装置组成。   
 
    运算器: 负责数据的算术运算和逻辑运算,即数据的加工处理。

	控制器: 是整个计算机的中枢神经,分析程序规定的控制信息,并根据程序要求进行控制,协调计算机各部分组件工作及内存与外设的访问等。

运算器和控制器统称中央处理器(即CPU)

	存储器: 实现记忆功能的部件,用来存储程序、数据和各种信号、命令等信息,并在需要时提供这些信息。

	输入设备: 实现将程序、原始数据、文字、字符、控制命令或现场采集的数据等信息输入到计算机。

	输出设备: 实现将计算机处理后生成的中间结果或最后结果(各种数据符号及文字或各种控制信号等信息)输出出来。
    
    
    
    
		控制器:
			作用:是计算机的指挥系统,负责控制计算机所有其他组件如何工作的
			类比:控制器=》人类的大脑

		运算器:
			作用:运算包括数学运算与逻辑运算
			类比:运算=》人类的大脑

			控制器+运算器=》cpu===》人类的大脑

		存储器/IO设备
			作用:是计算机的记忆功能,负责数据的存取
			分类:
				内存(基于电工作):存取数据都快,断电数据丢失,只能临时存取数据
				外存(硬盘,基于磁工作):存取速度都慢,断电数据也不丢,可以永久保存数据

			类比:
				内存===》人类的大脑的记忆功能
				外存===》人的笔记本

		输入设备input
			如键盘、鼠标
		输出设备output
			如显示器、打印机

            
 3-2. 软件系统:
	主要分为系统软件和应用软件,是指计算机运行所需的各种各样的计算机程序。

	系统软件的任务是既要保证计算机硬件的正常工作,又要使计算机硬件的性能得到充分发挥,并且为计算机用户提供一个比较直观、方便和友好的使用界面。

操作系统:是一种方便用户管理和控制计算机软硬件资源的系统软件,同时也是一个大型的软件系统,其功能复杂,体系庞大,在整个计算机系统中具有承上启下的地位。我们操作计算机实际上是通过操作系统来进行的,它是所有软件的基础和核心。

	语言处理程序:也称为编译程序,作用是把程序员用某种编程语言(如Python)所编写的程序,翻译成计算机可执行的机器语言。机器语言也被称为机器码,是可以通过CPU进行分析和执行的指令集。           
            
            
            
            
4、一个程序的运行与三大核心硬件的关系
	人--------------编程语言------------->计算机
        程序如下:
        1、去包子店                 
        2、付钱
        3、把包子送回来
		总结:
			程序最先是存放于硬盘之上
			程序的运行一定事先把程序的代码加载到内存
			然后cpu从内存中读取指令执行           

计算机是如何处理程序的?

1.用户打开程序,程序开始执行;
2.操作系统将程序内容和相关数据送入计算机的内存;
3.CPU根据程序内容从内存中读取指令;
4.CPU分析、处理指令,并为取下一条指令做准备;
5.取下一条指令并分析、处理,如此重复操作,直至执行完程序中全部指令,6.最后将计算的结果放入指令指定的存储器地址中。

编程语言是什么?

是用来定义 计算机程序 的形式语言。我们通过编程语言来编写程序代码,再通过语言处理程序执行向计算机发送指令,让计算机完成对应的工作。

简单来说,编程语言就是人类和计算机进行交流的语言。

操作系统

​ 1、引入

用户/应用程序(暴风影音、腾讯qq、快播、哇嘎)
操作系统:控制程序(windows、linux)
p计算机硬件

​ 2、操作系统概念

操作系统是一个协调、管理、控制计算机硬件资源与应用软件资源的一个控制程序
作用:
	1、控制计算机硬件的基本运行 
	2、把使用硬件的复杂操作封装成简单的功能,给上层的应用程序使用

	例如:文件就是操作系统提供给应用程序/用户操作硬盘的一种功能

3、程序的区分

计算机硬件是死的,计算机硬件的运行都受软件控制,所以说,软件相当于计算机的灵魂
具体来说软件分为两种:
1、应用软件:应用程序相关逻辑
2、系统软件:控制底层硬件的

4、计算机系统三层结构

应用程序
操作系统
计算机硬件

5、平台

		计算机硬件+操作系统=》平台

		软件的跨平台性指的是:一款软件可以任意平台上运行,是衡量软件质量高低的一个非常重要的指标

1、我们为何将内存称之为主存

计算机的内部存储器又称为主存储器,一般简称为内存。

2、x86-64代表的含义?简述cpu的向下兼容性

X86和X64都是PC处理器,
    向下兼容(downward compatibility),又称向后兼容(backward compatibility)、回溯兼容,在计算机中指在一个程序和/或库更新到较新版本后,用旧版本程序创建的文档或系统仍能被正常操作或使用(包括写入),或在旧版本库的基础上开发的程序仍能正常编译运行的情况。
在文件系统中,ext4文件系统的设计就是向后兼容的,ext3的文件系统可以被当作ext4文件系统挂载。

1.2 编程语言和python

1、Python发展背景

1989年,为了打发圣诞节假期,龟叔开始写Python语言的编译器。Python这个名字,来自龟叔所挚爱的电视剧Monty Python's Flying Circus。他希望这个新的叫做Python的语言,能符合他的理想:创造一种C和shell之间,功能全面,易学易用,可拓展的语言。

2、Python语言的诞生

1.1991年,第一个Python编译器诞生。
2.Python语法很多来自C,但又受到ABC语言的强烈影响。
3.Python从一开始就特别在意可拓展性。
4.最初的Python完全由龟叔本人开发。
5.计算机硬件越来越强大,Python又容易使用,所以许多人开始转向Python。
6.Python以及其标准库的功能强大。这些是整个社区的贡献。
7.到今天,Python的框架已经确立。Python语言以对象为核心组织代码,支持多种编程范式,采用动态类型,自动进行内存回收。Python支持解释运行,并能调用C库进行拓展。Python有强大的标准库。由于标准库的体系已经稳定,所以Python的生态系统开始拓展到第三方包。这些包,如Django、web.py、wxpython、numpy、matplotlib、PIL,将Python升级成了物种丰富的热带雨林。
8.Python崇尚优美、清晰、简单,是一个优秀并广泛使用的语言。
9.在Python的开发过程中,社区起到了重要的作用。
10.Python从其他语言中学到了很多,无论是已经进入历史的ABC,还是依然在使用的C和Perl,以及许多没有列出的其他 语言。

3、关键点常识

Python的发音与拼写
Python的作者是Guido van Rossum(龟叔)
Python正式诞生于1991年
Python的解释器如今有多个语言实现,我们常用的是CPython(官方版本的C语言实现),其他还有Jython(可以运行在Java平台)、IronPython(可以运行在.NET和Mono平台)、PyPy(Python实现的,支持JIT即时编译)
Python目前有两个版本,Python2和Python3
Life is shot, you need Python. 人生苦短,我用Python。

4、python优缺点

优点:

简单、易学、免费、开源、高层语言、可移植性、解释型语言、Python既支持面向过程的编程也支持面向对象的编程。与其他主要的语言如C++和Java相比,Python以一种非常强大又简单的方式实现面向对象编程。可扩展性强、丰富的库、Python标准库确实很庞大。规范的代码、Python采用强制缩进的方式使得代码具有极佳的可读性。

缺点:

Python语言非常完善,没有明显的短板和缺点,唯一的缺点就是执行效率慢,这个是解释型语言所通有的,同时这个缺点也将被计算机越来越强大的性能所弥补。

python 是一门编程语言

什么是编程语言?什么语言?为什么要有编程语言?

编程语言的本质就是一门语言
语言就是一种事物与另外一种事物沟通的表达方式/工具
    人--------------人类的语言------------>奴隶
	人--------------编程语言------------->计算机

什么编程?为什么要编程?

编程就是人把自己想计算机做的事,也就是自己的思维逻辑,用编程语言表达出来
编程的目的就是让计算机按照人类的思维逻辑去工作,从而解放人力

应用场景

	Web应用开发,操作系统管理、服务器运维的自动化脚本,网络爬虫,Python有大量的HTTP请求处理库和HTML解析库,并且有成熟高效的爬虫框架Scrapy和分布式解决方案scrapy-redis,在爬虫的应用方面非常广泛。,科学计算,NumPy、SciPy、Pandas、Matplotlib可以让Python程序员编写科学计算程序。桌面软件,PyQt、PySide、wxPython、PyGTK是Python快速开发桌面应用程序的利器.服务器软件(网络软件),游戏,构思实现,产品早期原型和迭代,Google、NASA、Facebook都在内部大量地使用Python。

1.3 常用的软件安装

一.Typora安装

首先我们先不直接讲解Python的知识,我们先用两天的时间讲解一下程序员必备的软件和使用.

在我们没有讲解之前的时候你们记录笔记就是使用word,记事本,云笔记等等,但是从今天开始我们要更换软件,记录笔记使用Typora软件,为什么要使用Typora的软件呢,是因为我们程序员不只是写代码这一件事,我们还需要给我们编写的代码抒写README文档,这个文档是说明你的程序如何使用的,README编写使用的就是Markdown语法,有人就有疑问Markdown和Typora软件有什么关系吗?

Typora这个软件就是使用Markdown进行编辑的,并且这个软件比较小

肯定还有人说别的软件也支持markdown语法的啊,是的但是Typora比较小

因为你们后期要成为一个专业的程序员,就要能够熟练使用markdown语法

我们要从现在开始习惯使用Markdown所以要求你们以后记录笔记的时候使用Typora软件,现在我们就先对这个软件进行安装.

点击右侧链接 https://typora.io/ 进行下载

找到页面中的 Download 进行下载,如下图:

image-20190628102231901

点击下边的箭头,效果如下图:

image-20190628102330277

找到图中的 Download 点击,效果图如下:

image-20190628102713524

Windows系统安装:

image-20190630182757371

针对自己电脑的位数进行安装,现在大部分的电脑都是64位的,我的是64位我选择64位进行下载

image-20190630183238126

这是下载的安装程序,我们现在双击这个图标

image-20190630183415479

选中的是要安装的路径,建议修改成C:\Typora然后选择Next

image-20190630183656056

Create a desktop shortcut 这个是在桌面上创建一个快捷图标,选择图中箭头所值的位置进行安装

image-20190630183800621

下图是安装中:

image-20190630183848657

当出现下图的就表示安装成功了,我们只需要点击一下箭头所指的位置就可以了

image-20190630184051819

苹果系统安装:

image-20190630183029737

苹果电脑直接选择这个就开始下载安装包

image-20190630184453645

找到安装的程序进行双击,双击后的效果如下图:

image-20190630184614948

软件就安装成功了,现在打开我们安装的软件,我带着大家把咱们以后记笔记的样式写一下.

在电脑的C盘或则D盘创建一个文件夹 -- 然后文件夹的名字叫做 Python学习笔记我们进入Python学习笔记中然后创建一个文件 Python学习手册 都创建好后就记住我们以后的笔记全部都存放在这个Python学习手册中,怎么编写笔记呢? 我们来学习一下Markdown的使用

二.Markdown语法

''' # 一级标题 '''

''' ## 二级标题 '''

''' ### 三级标题 '''

''' #### 四级标题 '''

''' ##### 五级标题 '''

文字加粗

''' 你好 斜体 '''

转义*

删除线

标题这个部分我们一般都是用到五级标题,有的时候我们需要列一些内容,就需要使用到序号,我们看看序号怎么使用

''' 1.+ Tab键 ''' 这样就是一个有序序号,当编辑完这一行的时候换行后序号自动增加

刚刚我们说的是有序的序号,现在来看看无序的序号

''' -, +,* Tab键 ''' 这样就是一个无序序号

如果我们想要在某一行的下面继续写内容,如图:

image-20190628104634412

就按下键盘的Tab键,然后继续编辑,说我编辑完了,想要回到第一章同级的位置找到键盘的Tab和Shift键同时按下,或者多按几次回车

我们是程序员,记录的笔记中不可能全是文字,一定会有代码,代码直接粘贴到这里不易查看,我们学习一下怎么存放代码

''' ```python ''' 然后回车的时候就出现一下的内容

存放代码块

我们直接在里边写代码就行了

现在我们知道了怎么编写文字,怎么编写代码,但是这两个完全不能满足我们的需求啊,我想弄个图片怎么办啊,很是简单图片我们直接粘贴过来就行了,但是有个需要注意的地方,我们设置一下图片都存在哪个地方,这样方便我们查找.

设置完图片的存放位置,我们有时候需要写一个表格来记录一些内容, …….

Typora这个软件的强大之处不仅仅能够写内容还可以导出pdf,word等格式

这个软件我们就安装好了

三.Python环境安装

你们有没有人来的时候刚买的电脑,打比方我们要去中关村买一个电脑,卖电脑的小哥就会问你要什么配置的电脑啊,小哥说的配置是什么呢?

image-20190701155558772

配置就是图中的cpu,主板,内存,硬盘等等,

cpu相当于我们人类的大脑是进行运算和逻辑处理的

内存是存储临时数据的,我们在word和typora软件中编写的内容就是存储在内存当中 存储在内存中断电就会消失这样数据存储就有问题 需要一个能够永久存储数据的东西

硬盘就是永久存储数据的东西,这个硬盘就是我们常说的C盘D盘 一般存放的都是音频,文本,片儿啥的

固态硬盘也是硬盘就是速度快一些

小哥帮咱们把一台电脑组装好了,现在这个电脑能够运行吗? 不能吧我们只是把硬件都配置好了,我们是不是还需要安装操作系统

我们平时安装的都是win7和win10,其实还有Mac,Linux这些系统

我们安装完操作系统后想要社交聊天的是不是需要安装陌陌,微信啥的啊,微信和陌陌叫做应用程序,我们使用应用程序的时候其实就会通过操作系统控制计算机硬件执行的流程.

操作系统的作用就是:承上启下,承上是安装的软件,启下是控制硬件工作

操作系统也是别人开发一种特殊的软件.下图是计算机硬件和操作系统以及应用程序的关系图:

image-20190701195517913

程序员想要控制计算机帮助我们工作,就像公司中有一个日本人一个韩国人你想让日本人去帮助你工作,你是不是应该说日本话,让日本人听懂后在去帮咱们工作啊.同理如果想让韩国人帮我们工作,我们也需要说韩国话去命令别人. 程序员想让计算机帮我们做一些事情,我们就需要使用计算机能够识别的东西来控制计算机,计算机能够识别的就是编程语言,目前大概有500多种.我们只需要选择一个就能够使计算机帮助我们工作.这么多语言中我们应该怎么选择呢?

四. 编程语言分类

编程语言中有很多种角度来分类,我们就通过编译型和解释型的角度来有什么区别

为什么要从这两个角度来看呢,是因为我们写的编程语言能够让计算机认识中间还需要一个翻译的过程.这个翻译就是我们过会要安装的软件

编译型: 将人类能够认识的代码全部编写完, 然后交由翻译器一次性进行翻译 解释型: 将人类能够认识的代码一边编写代码,一边进行翻译

编译型:

优点:执行速度快,一次性翻译后交于cpu去运行

缺点:开发效率低,如果在编写代码时有错,修改后需要重新翻译

解释型:

优点:开发效率高,打比方一个淘宝网站使用编译型语言来开发需要1年左右,但是使用解释型语言来开发只需要6,7个月

缺点:执行速度慢,需要翻译多次

Python属于解释型

现在Python语言逐渐使用广泛是因为什么?

五. Python简介

image-20190619205811650吉多.范罗苏姆(龟叔)1989年圣诞期间为了打发时间创建的一门语言

龟叔在创建这门语言的时候崇尚的宗旨就是优美,清晰,简单.怎么个优美,清晰,简单法

我们用c语言和python来对比一下

c语言写法
#include <stdio.h>
int main(){
    int n = 5;
    if(n > 3)
    {
        printf("c语言学习比较难\n");}
    else if (n < 10)
    {
        printf("c语言需要考虑硬件分配");}
    else
    {
        printf("定义变量还需要声明,没写完一个还需要写一个;号");
    }
    return 10;
}

我们看完了c语言的写法,在来看看python的写法

python写法
n = 5
if n > 3:
    print("python学习简单")
elif n < 10:
    print("Python完全不需要考虑硬件分配")
else:
    print("我不管,Python就是最简单的")

通过对比发现python的代码看着比较优美,清晰,简单.这些还不够python在全球编程语言中排行第三,并且持续上升

image-20190620004913057

python能够成为全球编程排行榜第三是因为Python具有以下优点:

Python优点

  1. Python的定位是“优雅”、“明确”、“简单”,所以Python程序看上去总是简单易懂,初学者学Python,不但入门容易,而且将来深入下去,可以编写那些非常非常复杂的程序。
  2. 开发效率非常高,Python有非常强大的第三方库,基本上你想通过计算机实现任何功能,Python官方库里都有相应的模块进行支持,直接下载调用后,在基础库的基础上再进行开发,大大降低开发周期,避免重复造轮子。
  3. 高级语言————当你用Python语言编写程序的时候,你无需考虑诸如如何管理你的程序使用的内存一类的底层细节
  4. 可移植性————由于它的开源本质,Python已经被移植在许多平台上(经过改动使它能够工作在不同平台上)。如果你小心地避免使用依赖于系统的特性,那么你的所有Python程序无需修改就几乎可以在市场上所有的系统平台上运行
  5. 可扩展性————如果你需要你的一段关键代码运行得更快或者希望某些算法不公开,你可以把你的部分程序用C或C++编写,然后在你的Python程序中使用它们。
  6. 可嵌入性————你可以把Python嵌入你的C/C++程序,从而向你的程序用户提供脚本功能。

Python具有这么多优点的前提下Python能够从事的领域也很多

Python应用领域

  • 云计算: 云计算最火的语言, 典型应用OpenStack
  • WEB开发: 众多优秀的WEB框架,众多大型网站均为Python开发,Youtube, Dropbox, 豆瓣。。。典型WEB框架有Django
  • 科学运算、人工智能: 典型库NumPy, SciPy, Matplotlib, Enthought librarys,pandas
  • 系统运维: 运维人员必备语言
  • 爬虫:通过代码来模拟人类进行页面访问,对数据进行批量的采集
  • 金融:量化交易,金融分析,在金融工程领域,Python不但在用,且用的最多,而且重要性逐年提高。原因:作为动态语言的Python,语言结构清晰简单,库丰富,成熟稳定,科学计算和统计分析都很牛逼,生产效率远远高于c,c++,java,尤其擅长策略回测
  • 图形GUI: PyQT, WxPython,TkInter,Turtle

2

我们现在知道了Python的优点,Python能做什么,现在应该来看看Python都在哪用

Python在哪些公司被使用

  • 谷歌:Google App Engine 、code.google.com 、Google earth 、谷歌爬虫、
  • Google广告等项目都在大量使用Python开发
  • CIA: 美国中情局网站就是用Python开发的
  • NASA: 美国航天局(NASA)大量使用Python进行数据分析和运算
  • YouTube:世界上最大的视频网站YouTube就是用Python开发的
  • Dropbox:美国最大的在线云存储网站,全部用Python实现,每天网站处理10亿个文件的上传和下载
  • Instagram:美国最大的图片分享社交网站,每天超过3千万张照片被分享,全部用python开发
  • Facebook:大量的基础库均通过Python实现的
  • Redhat: 世界上最流行的Linux发行版本中的yum包管理工具就是用python开发的
  • 豆瓣: 公司几乎所有的业务均是通过Python开发的
  • 知乎: 国内最大的问答社区,通过Python开发(国外Quora)
  • 春雨医生:国内知名的在线医疗网站是用Python开发的
  • 除上面之外,还有搜狐、金山、腾讯、盛大、网易、百度、阿里、淘宝 、360、新浪等公司都在使用Python完成各种各样的任务

现在我们知道python的优势后,我们学习python那个版本啊? 为什么要学习python3版本的啊,我们来看看原因

Python的历史

  • 1989年,为了打发圣诞节假期,Guido开始写Python语言的编译器。Python这个名字,来自Guido所挚爱的电视剧Monty Python’s Flying Circus。他希望这个新的叫做Python的语言,能符合他的理想:创造一种C和shell之间,功能全面,易学易用,可拓展的语言。
  • 1991年,第一个Python编译器诞生。它是用C语言实现的,并能够调用C语言的库文件。从一出生,Python已经具有了:类,函数,异常处理,包含表和词典在内的核心数据类型,以及模块为基础的拓展系统。
  • Granddaddy of Python web frameworks, Zope 1 was released in 1999
  • Python 1.0 - January 1994 增加了 lambda, map, filter and reduce.
  • Python 2.0 - October 16, 2000,加入了内存回收机制,构成了现在Python语言框架的基础
  • Python 2.4 - November 30, 2004, 同年目前最流行的WEB框架Django 诞生
  • Python 2.5 - September 19, 2006
  • Python 2.6 - October 1, 2008
  • Python 2.7 - July 3, 2010
  • In November 2014, it was announced that Python 2.7 would be supported until 2020, and reaffirmed that there would be no 2.8 release as users were expected to move to Python 3.4+ as soon as possible
  • Python 3.0 - December 3, 2008
  • Python 3.1 - June 27, 2009
  • Python 3.2 - February 20, 2011
  • Python 3.3 - September 29, 2012
  • Python 3.4 - March 16, 2014
  • Python 3.5 - September 13, 2015
  • Python 3.6 - December 16,2016

Python的种类

python还有种类,不就一个python吗? 你们说的一个是编写规则,我说的种类是解释器的分类,Python下边有以下解释器

  • Cpython

  Python的官方版本,使用C语言实现,使用最为广泛,CPython实现会将源文件(py文件)

转换成字节码文件(pyc文件),然后运行在Python虚拟机上。

  • Jyhton

  Python的Java实现,Jython会将Python代码动态编译成Java字节码,然后在JVM上运行。

  • IronPython

     Python的C#实现,IronPython将Python代码编译成C#字节码,然后在CLR上运行。(与Jython类似)

  • PyPy(特殊)

  Python实现的Python,将Python的字节码字节码再编译成机器码。

image-20190619212451193

说了这么多内容,感觉好厉害已近迫不及待的想要动手去试试了,我不得不说,客官还需要在稍等一下.我们需要安装一下Python解释器

六.Python环境安装

6.1打开官网:http://www.python.org 点击Downloads下载,如下图

img

6.2下拉页面,选择对应版本:Python3.6.3,如下图

img

向下查找,找到Python 3.6.3

6.3 根据系统选择对应的安装包,如下图

img

根据当前系统的选择对用的,红色的是windows32位,绿色的是windows64位

6.4下载完成,如下图

img

下载完成后找到下载的目录,然后用鼠标左键双击

6.5 安装

img

6.6 执行下一步

img

6.7 勾选安装

img

6.8 安装进度

img

6.9 安装成功

img

6.10 验证是否配置成功

打开电脑的终端(黑窗口),输入 python回车进去python解释器,返回的结果入下图:

img

6.11 退出终端中的python

在终端中 >>> 输入exit() 如下图:

img

6.12 最后在安装一下Python2.7,大家跟着我一起将python2和python3配置一下,添加环境变量

image-20190701172605071

6.13 点击上图的高级系统设置,然后出现以下图片:

image-20190701172919179

6.14 点击完环境变量后会出现下图:

image-20190701173158688

6.15 我们选择Path然后点击编辑

image-20190701173407801

在最后的位置添加我们Python解释器的路径,我们Python解释器的路径是当时安装时选择的D:\Program Files(x86)\Python36-32

我们就将这个路劲添加到变量值中,注意在添加的路径前面加上一个;

路径中不能出现中文 ;分号一定要使用英文的

添加完后点击确定,然后继续确定,在确定

配置好我们开始写第一个Python程序

七. 第一个Python程序

我们打开typora软件,不要尝试word,文本编辑器.他们自身会有问题,我们统一使用typora然后编辑

print("hello world!")

注意: 括号,引号都使用英文的输入法

然后保存,找到存放文件的位置,打开终端,在终端中输入

image-20191011151718582

确认一下输入没有问题就敲一下回车, print是输出打印的意思 , 要是看到了

hello world! 就说明成功了,我们尝试的打印一下中文

发现改完中文后不是我们想要的内容,这是因为咱们没有指定中文用什么编码来显示

现在我们添加一下文件头

#!/usr/bin/env
# -*-coding:utf-8 -*-

将这两句写到文件最开头的位置,然后保存在去执行,windows上的电脑会出现不认识的字符.这是因为windows系统的编码是gbk

我们现在在黑窗口运行的文件,这种方式叫做脚本,很早的程序员都在这里进行开发

在这里开发如果有问题不能及时发现,并且关键字没有提示.考虑到大部分都是小白我们使用有提示的方式编程,降低一些难度

八.Pycharm安装

8.1.1 下载Pycahrm

首先要下载Pycharm这个软件,官网的下载地址是: http://www.jetbrains.com/pycharm/download/#section=windows

1548326046866

选择左边的点击进行下载,左边的是专业版右边是社区版

8.1.2 下载中

1548326046866

出现这个页面就是正在下载,稍微喝杯茶等等

8.1.3 找到文件

1548326046866

8.1.4 安装

1548326046866

选择Next 点击

8.1.5 选择要安装到那个目录

1548326046866

8.1.6 选择配置

1548326046866

我是64位机器,我选择了64,如果是32的就选择32 [不管64还是32剩下的都选择]

8.1.7 点击安装

1548326046866

8.1.8 安装中

1548326046866

8.1.9 安装成功

1548326046866

出现这个界面的直接点击Finish关闭就可以了. 我们现在切换到桌面

8.1.10 使用Pycharm

1548325864646

找到这个图标然后双击

8.1.11 首次使用Pychram

1548326046866

8.1.12 用户许可证

1548326092371

8.1.13 激活Pycharm

激活详情http://idea.lanyus.com/页面 1548326302535

点击选择的内容生成激活码,然后将激活码复制到code选项中

Pycharm激活码链接

1548326228498

8.1.14 个性化设置

1548326213158

这个直接关闭就可以了

8.1.15 启动成功

1548326451573

如果你的激活码没问题的话,会在个性化,主题设置完毕之后,经过短暂的加载(加载速度取决于电脑性能)进入如图页面,到这一步,PyCharm安装完成了

8.1.16 创建文件

1548326588019

8.1.17 PyCharm选择解释器

File -- Settings -- Project -- Project Interpreter,这里会显示当前系统默认的解释器,如果要添加别的解释器,点击工具图标,Add local -- Existing environment,点击三点图标,在打开的本地文件目录中选择解释器文件的.exe文件。就行了,如果你没有选择, PyCharm会自动选择当前环境默认的解释器

8.1.18 PyCharm创建py文件

1548327074139

鼠标放到大纲然后右键鼠标,出现一个New然后鼠标向右滑动选择python file点击左键

1548327173538

直接写文件的名字就可以了,写完后回车就搞定了.

5 启动成功

如果你的激活码没问题的话,会在个性化,主题设置完毕之后,经过短暂的加载(加载速度取决于电脑性能)进入如图页面,到这一步,PyCharm安装完成了

8.1.16 创建文件

8.1.17 PyCharm选择解释器

File -- Settings -- Project -- Project Interpreter,这里会显示当前系统默认的解释器,如果要添加别的解释器,点击工具图标,Add local -- Existing environment,点击三点图标,在打开的本地文件目录中选择解释器文件的.exe文件。就行了,如果你没有选择, PyCharm会自动选择当前环境默认的解释器

8.1.18 PyCharm创建py文件

鼠标放到大纲然后右键鼠标,出现一个New然后鼠标向右滑动选择python file点击左键

直接写文件的名字就可以了,写完后回车就搞定了.

1.4 开发第一个python程序

	1、编程语言介绍
		分类:
			机器语言
			汇编语言
			高级语言(编译型、解释型号)

		总结:
			#1、执行效率:机器语言>汇编语言>高级语言(编译型>解释型)

			#2、开发效率:机器语言<汇编语言<高级语言(编译型<解释型)

			#3、跨平台性:解释型具有极强的跨平台型

	2、python介绍
		python语言:指的是pyton的语法风格
		python解释器:专门用来识别python这门语言的语法并解释执行的

	3、解释器多版本共存
		设置环境变量
			windows
				win10
				win7

			linux:
				vim /etc/profile
					PATH=$PATH:/usr/local/python38:/usr/local/python38
					export PATH
			mac:
				同linux

	4、运行python程序的两种方式
		1、交互式
			即时得到程序的运行结果,多用于调试
		2、脚本的方式
			把程序写到文件里(约定俗称文件名后缀为.py),然后用python解释器解释执行其中的内容

			python3.8 python程序文件的路径


	5、一个python应用程序的运行的三个步骤(******)
		python3.8 C:\a\b\c.py  执行python程序经历三个步骤
			1、先启动python3.8解释器,此时相当于启动了一个文本编辑器
			2、解释器会发送系统调用,把c.py的内容从硬盘读入内存,此时c.py中的内容
				全部为普通字符,没有任何语法意义
			3、解释器开始解释执行刚刚读入内存的c.py的代码,开始识别python语法

		对比文本编辑器读取C:\a\b\c.py文件内容也经历了三个步骤
			1、先启动文本编辑器
			2、文本编辑器会发送系统调用,把c.py的内容从硬盘读入内存
			3、文本编辑会将刚刚读入内存的内容控制输出到屏幕上,让用户看到结果


		总结:
			二者在前两个阶段做的事情完全一致
			唯一不同的就是第三个阶段对读入内存的python代码的处理方式不同

	7、IDE集成开发环境pycharm
		mac平台pycharm使用参考视频讲解
		windows平台pycharm使用参考博客https://zhuanlan.zhihu.com/p/108676916
			windows平台下相关配置
				选择pycharm对话框左上角File,然后点击settings,接下来的配置同mac平台

1.5 注释

	1、注释
		1、注释是对关键代码的解释说明
			单行注释:#
                # 这是一行xxx的代码
                print("hello")  # 这是一行xxx的代码

			多行注释:''''''  """"""
                """
                笔记
                """
		2、被注释的代码不会被执行

1.6 变量及类型

一,什么是变量

变量就是可以变化的量,量指的是事物的状态,比如人的年龄,性别,游戏角色的等级,金钱等等

二,为什么要有变量?

为了让计算机能够像人一样去记忆事物的某种状态,并且状态是可以发生变化的
详细地说:
程序执行的本质状态的变化,变的是程序执行的直接体现,所以我们需要有一种机制能够反应或者说是保存下来

三,如何用变量

1. 变量的基本使用
原则: 先定义,后引用
name = "harry"   # 定义-》存
print(name)     # 引用 -》取

age = 18
print(age)

2. 内存管理:垃圾回收机制
垃圾:当一个变量值被绑定的变量名的个数为0时,该变量值无法被访问到,称之为垃圾
应用计数增加
x = 10 # 10的引用计数为1
y = x # 10的引用计数为2
z = x # 10的引用计数为3

# 引用计数减少
del x  # 解除变量名x与值10的绑定关系,10的引用计数变为2
# print(y)
del y  # 10的引用计数变为1
# print(z)
z = 12345  # # 10的引用计数变为0
# print(z)

python 中的del 用法

python都是引用,而python有GC机制,所以,del语句作用在变量上,而不是数据对象上
if __name__ == '__main__':  
    a = 1       # 对象 1 被 变量a引用,对象1的引用计数器为1
    b = a       # 对象1 被变量b引用,对象1的引用计数器加1
    c = a       # 1对象1 被变量c引用,对象1的引用计数器加1
    del a     # 删除变量a,解除a对1的引用
    del b     # 删除变量b,解除b对1的引用
    print(c)  # 最终变量c仍然引用1
    
del删除的是变量,而不是数据。
if __name__ == '__main__':  
    li = [1, 2, 3, 4, 5]
    # 列表本身不包含数据1,2,3,4,5,而是包含变量:li[0] li[1] li[2] li[3] li[4]   
    first = li[0]     # 拷贝列表,也不会有数据对象的复制,而是创建新的变量引用  
    del li[0]
    print(li)      # 输出[2, 3, 4, 5]  
    print(first)   # 输出 1 

3、变量有三大组成部分
I:变量名=》是指向等号右侧值的内存地址的,用来访问等号右侧的值
II:赋值符号:将变量值的内存地址绑定给变量名
III:变量值:代表记录的事物的状态

4、变量名的命名的规则
原则:变量名的命名应该见名知意
4.1. 变量名只能是 字母、数字或下划线的任意组合
4.2. 变量名的第一个字符不能是数字
4.3. 关键字不能声明为变量名,常用关键字如下
['and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'exec', 'finally', 'for', 'from','global', 'if', 'import', 'in', 'is', 'lambda', 'not', 'or', 'pass', 'print', 'raise', 'return', 'try', 'while', 'with', 'yield']
age=18
print='Harry'

ps:不要用拼音,不要用中文,在见名知意的前提下尽可能短
mingzi='Harry'
名字='Harry'
print(名字)

5、变量名的命名风格
5.1 纯小写加下划线的方式(在python中,关于变量名的命名推荐使用这种方式)
age_of_alex = 73
print(age_of_alex)
5.2 驼峰体
AgeOfAlex = 73
print(AgeOfAlex)

6、变量值三个重要的特征
name='Harry'
id:反映的是变量值的内存地址,内存地址不同id则不同
print(id(name))
type:不同类型的值用来表示记录不同的状态
print(type(name))
value:值本身
print(name)

6.2 is与==
is:比较左右两个值身份id是否相等
==:比较左右两个值他们的值是否相等
'''
id不同的情况下,值有可能相同,即两块不同的内存空间里可以存相同的值
id相同的情况下,值一定相同,x is y成立,x == y也必然成立
>>> 
>>> x='info:Egon:18'
>>> y='info:Egon:18'
>>> print(x,y)
info:Egon:18 info:Egon:18
>>> print(id(x),id(y))
4565819264 4566192176
>>> 
>>> 
>>> 
>>> x == y
True
>>> x is y
False
'''

# 了解:小整数池[-5,256]
# 从python解释器启动那一刻开始,就会在内存中事先申请
# 好一系列内存空间存放好常用的整数
'''
>>> m=10
>>> n=10
>>> id(m)
4562619328
>>> id(n)
4562619328
>>> 
>>> res=4+6
>>> res
10
>>> id(res)
4562619328
'''

'''
>>> x=-5
>>> y=-5
>>> x is y
True
>>> x=-6
>>> y=-6
>>> x is y
False
'''

'''
>>> x='aaa'
>>> y='aaa'
>>> 
>>> 
>>> id(x)
4566200880
>>> id(y)
4566200880
'''

'''
x=-6
y=-6
print(id(x))
print(id(y))
print(x is y)
'''

# 7、常量:不变的量
# 注意:python语法中没有常量的概念,但是在程序的开发过程中会涉及到常量的概念
AGE_OF_ALEX = 73  # 小写字母全为大写代表常量,这只是一种约定、规范
AGE_OF_ALEX = 74
print(AGE_OF_ALEX)

二,基本数据类型

1.数字类型

1.1 整形int 

作用: 记录年龄,身份证号,个数等等

定义:
age = 18
print(type(age))

浮点型float
作用:记录薪资、身高、体重
定义
salary = 3.3
height = 1.87
weight = 70.3
print(type(height))
数字类型的其他使用
level = 1
level = level + 1
print(level)
print(10 * 3)

print(10 + 3.3)  # int与float之间可以相加
age = 19
print(age > 18)
# 2、字符串类型str
# 作用:记录描述性质的状态,名字、一段话
# 定义:用引号('',"",''' ''',""" """,)包含的一串字符
info = '''
天下只有两种人。比如一串葡萄到手,一种人挑最好的先吃,
另一种人把最好的留到最后吃。
照例第一种人应该乐观,因为他每吃一颗都是吃剩的葡萄里最好的;
第二种人应该悲观,因为他每吃一颗都是吃剩的葡萄里最坏的。
不过事实却适得其反,缘故是第二种人还有希望,第一种人只有回忆。
'''
print(type(info))
name = "Harry"
print(name)
x = 18
print(type(x))
x = '18'  # 由数字组成的字符串,是字符串类型,不是int类型
print(type(x))

'name'='Harry' # 语法错误,等号左边是变量名,变量名的命名不能有引号

# xxx # 代表访问变量名字
'xxx'  # 代表的是值

x = 10
y = x

# 其他使用:
# 字符串的嵌套,注意:外层用单引号,内存应该用双引号,反之亦然
print("my name is 'Harry'")
print('my name is \'Harry\'')

# 字符串之间可以相加,但仅限于str与str之间进行,
# 代表字符串的拼接,了解即可,不推荐使用,因为str之间的
# 相加效率极低
print('my name is '+'Harry')
print('='*20)
print('hello world')
print('='*20)

# 3、列表:索引对应值,索引从0开始,0代表第一个
# 作用:按位置记录多个值(同一个人的多个爱好、同一个班级的所有学校姓名、同一个人12个月的薪资),并且可以按照索引取指定位置的值
# 定义:在[]内用逗号分隔开多个任意类型的值,一个值称之为一个元素
#   0     1     2       3              4
l = [10, 3.1, 'aaa', ['bbb', 'ccc'], 'ddd']
print(l)

print(l[1])
print(l[2])
print(l[3])
print(l[3][1])

print(l[4])
print(l[-1])


hobbies = 'read music play'
print(hobbies)
hobbies = ['read', 'music', 'play']
print(hobbies[1])

# 其他的用途:
students_info =[
    ['tony', 18, ['jack', ]],
    ['jason', 18, ['play', 'sleep']]
]
# 取出第一个学生的第一个爱好
print(students_info[0][2][0])


# 4、索引反映的是顺序、位置,对值没有描述性的功能
#          0    1     2     3
info = ['harry', 18, 'male', 19]
print(type(info))
print(info[0])
print(info[1])
print(info[2])


# 字典类型:key对应值,其中key通常为字符串类型,所以key对值可以有描述性的功能
# 作用:用来存多个值,每个值都有唯一一个key与其对应,key对值有描述性功能
# 定义:在{}内用逗号分开各多个key:value
d = {'a': 1, 'b': 2}
print(type(d))
print(d['a'])
print(d["b"])

info = {
    "name": 'harry',
    "age": 18,
    "gender": 'male',
    "salary": 19
}
print(info["salary"])
print(info["name"])

# 其他用途:
# students_info=[
#     第1个信息,
#     第2个信息,
#     第3个信息,
# ]

students_info = [
    {"name": 'harry1', 'age1': 19, 'gender': 'male'},
    {"name": 'harry2', 'age1': 19, 'gender': 'male'},
    {"name": 'harry3', 'age1': 19, 'gender': 'male'},
]

print(students_info[1]['gender'])

# 5 布尔bool
# 6.1 作用
# 用来记录真假这两种状态
#
# 6.2 定义
is_ok = True
is_NG = False
print(type(is_NG))

x = 1
y = 0

students = [
    {'name': 'harry', 'gender': 'male'},
    {'name': 'alex', 'gender': 'female'},
]


# 6.3 其他使用
# 通常用来当作判断的条件,我们将在if判断中用到它

# 总结:如何选择合适的类型来记录状态
# 1、选取的类型是否可以明确标识事物的状态
# 2、存不是目的,存的目的是为了日后取出来用,并且方便的用
# 3、把自己想象成一台计算机,如果我是计算机,
#    我会如何以何种形式把事物的状态记到脑子里
#    然后再去python中找相应的数据类型来让计算机像自己一样去记下事物的状态

1.7 标识符和关键字

1.标识符

开发人员在程序中自定义的一些符合和名称
标识符是自己定义的,如变量名,函数名等

2.标识符的规则

标识符由字母,下划线和数组组成,且数组不能开头
python中的标识符是区分大小写  例如: Andy

3.命名规则

1.模块
模块尽量使用小写命名,首字母保持小写,尽量不要用下划线(除非多个单词,且数量不多的情况)
import decoder
import html_parser
2.类名
类名使用驼峰体,首字母大写,私有类可用一个下划线开头
class Farm():
  pass
class _Student(Farm):
  pass
将相关的类和顶级函数放在同一个模块里。
3.函数
函数名一律小写,如果多个单词,用下划线隔开
def run():
  pass
def run_with():
  pass
私有函数在函数前加一个下划线_

class Person():
  def _private_fun(s):
    pass
4.变量名
变量名尽量小写,如有多个单词,用下划线隔开
if __name__ == "__main__":
  count = 0 
  school_name = ""

常量采用全大写,如有多个单词,使用下划线隔开
MAX_CLIENT = 100
5.常量
常量使用以下划线分隔的大写命名
MAX_CLIENT = 100

关键字

什么是关键字:
python一些具有特殊功能的标识符,这就是所谓的关键字
关键字,是python已经使用的,所以不允许开发者自己自定义和关键字相同的名字和标识符

查看关键字:

['and', 'as', 'assert', 'break', 'class',
 'continue','def', 'del', 'elif', 'else', 'except', 'exec', 'finally',
'for', 'from','global', 'if', 'import', 'in', 'is', 'lambda',
'not', 'or', 'pass', 'print', 'raise', 'return', 'try', 'while', 'with', 'yield']
False: 布尔类型的值,表示假,与True相反

True: 布尔类型的值,表示假,与False相反

None: None比较特殊,表示什么都没有,它有自己的数据类型 NoneType

and:用于表达式运算,逻辑与操作

as:用于类型转换

assert: 断言,用于判断变量或者条件表达式的值是否为真

break:中断循环语句的执行

class:用于定义类

continue :跳出本次循环,继续执行下一次循环

def 用于定义函数或方法

elif 条件语句,与 if,else结合使用

else 条件语句,与if,elif结合使用,也可以用于异常和循环语句

except except包含捕获异常后的操作代码块,与try,finally结合使用

finally 用于异常语句,出现异常后,始终要执行finally包含的代码块。与try,except结合使用

for: for 循环语句

from:用于导入模块,与import结合使用

global: 定义全局变量

if:条件语句,与else,elif结合使用

import:用于导入模块,与from结合使用

in 判断变量是否在序列中

is 判断变量是否为某个类的实例

lambda:定义匿名函数

nonlocal:用于标识外部作用域的变量

not:用于表达式运算,逻辑非操作

or 用于表达式运算,逻辑或操作

pass 空的类,方法或函数的占位符

raise:异常抛出操作

return :用于从函数返回计算结果

try: try包含可能会出现异常的语句,与 except finally结合使用

while while循环语句

with 简化python的语句

yield 用于函数依次返回值

1.8 输出,输入

输出

  1. 普通的输出
# 打印提示
print('hello world')
print('萨瓦迪卡---泰语,你好的意思')
  1. 格式化输出

2.1. 格式化操作的目的

比如有以下代码:

pirnt("我今年10岁")
pirnt("我今年11岁")
pirnt("我今年12岁")
    ...

2.2 什么是格式化

看如下代码:

age = 10
print("我今年%d岁" % age)

age += 1
print("我今年%d岁" % age)

age += 1
print("我今年%d岁" % age)

...

在程序中,看到了%这样的操作符,这就是Python中格式化输出。

age = 18
name = "xiaohua"
print("我的姓名是%s, 年龄是%d" % (name, age))

2.3. 常用的格式符号

下面是完整的,它可以与%符号使用列表:

格式符号 转换
%c 字符
%s 字符串
%d 有符号十进制整数
%u 无符号十进制整数
%o 八进制整数
%x 十六进制整数(小写字母0x)
%X 十六进制整数(大写字母0X)
%f 浮点数
%e 科学计数法(小写'e')
%E 科学计数法(大写“E”)
%g %f和%e 的简写
%G %f和%E的简写
  1. 换行输出

在输出的时候,如果有\n那么,此时\n后的内容会在另外一行显示

    print("1234567890-------") # 会在一行显示

    print("1234567890\n-------") # 一行显示1234567890,另外一行显示-------
  1. 练一练
  • 定义字符串变量 name ,输出 我的名字叫 ⼩明,请多多关照!

  • 定义整数变量 student_no ,输出 我的学号是 000001

  • 定义⼩数 price 、 weight 、 money ,输出 苹果单价 9.00 元/⽄,购买了 5.00 ⽄,需要⽀付 45.00 元

  • 定义⼀个⼩数 scale ,输出 数据⽐例是 10.00%

    print("我的名字叫 %s,请多多关照!" % name)
    print("我的学号是 %06d" % student_no)
    print("苹果单价 %.02f 元/⽄,购买 %.02f ⽄,需要⽀付 %.02f 元" % (price, weight, money))
    print("数据⽐例是 %.02f%%" % (scale * 100))
    
  • 编写代码完成以下名片的显示

        ==========我的名片==========
        姓名: itheima   
        QQ:xxxxxxx
        手机号:185xxxxxx
        公司地址:北京市xxxx
        ===========================
    

输入

接收用户输入的数据使用 input() 函数

input()接受表达式输入,并把表达式的结果赋值给等号左边的变量,input函数返回的类型是字符串

1.9 运算符

运算符

python支持以下几种运算符

  1. 算术运算符

下面以a=10 ,b=20为例进行计算

运算符 描述 实例
+ 两个对象相加 a + b 输出结果 30
- 得到负数或是一个数减去另一个数 a - b 输出结果 -10
* 两个数相乘或是返回一个被重复若干次的字符串 a * b 输出结果 200
/ b / a 输出结果 2
// 取整除 返回商的整数部分 9//2 输出结果 4 , 9.0//2.0 输出结果 4.0
% 取余 返回除法的余数 b % a 输出结果 0
** 指数 a**b 为10的20次方, 输出结果 100000000000000000000

注意:混合运算时,优先级顺序为: ** 高于 * / % // 高于 + - ,为了避免歧义,建议使用 () 来处理运算符优先级。

并且,不同类型的数字在进行混合运算时,整数将会转换成浮点数进行运算。

>>> 10 + 5.5 * 2
21.0
>>> 10 + (5.5 * 2)
21.0
  1. 赋值运算符
运算符 描述 实例
= 赋值运算符 把 = 号右边的结果 赋给 左边的变量,如 num = 1 + 2 * 3,结果num的值为7
# 单个变量赋值
>>> num = 10
>>> num
10

# 多个变量赋值
>>> num1, num2, f1, str1 = 100, 200, 3.14, "hello"
>>> num1
100
>>> num2
200
>>> f1
3.14
>>> str1
"hello"
  • 复合赋值运算符
运算符 描述 实例
+= 加法赋值运算符 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

1.10数据类型转换

常用的数据类型转换

类型转换操作 说明
int(x [,base ]) 将x转换为一个整数
float(x ) 将x转换为一个浮点数
complex(real [,imag ]) 创建一个复数,real为实部,imag为虚部
str(x ) 将对象 x 转换为字符串
eval(str ) 将字符串转成原始数据类型
tuple(s ) 将序列 s 转换为一个元组
list(s ) 将序列 s 转换为一个列表
chr(x ) 将一个整数转换为一个字符
ord(x ) 将一个字符转换为它的ASCII整数值
hex(x ) 将一个整数转换为一个十六进制字符串
oct(x ) 将一个整数转换为一个八进制字符串
bin(x ) 将一个整数转换为一个二进制字符串

举例

# int(): 将数据转换为 int 类型
str1 = "10"
# int() 默认按10进制转换后显示
num1 = int(str1)
print(num1)

# int() 处理浮点数,只留下整数部分,舍弃小数部分(并不是四舍五入操作)
num2 = int(5.74)
print(num2)

# float() 将数据转化为浮点数
str2 = "3.14"
f1 = float(str2)
print(type(f1))  # <class 'float'>

f2 = float(10)
print(f2)  # 10.0

# complex() 创建复数: 第一个参数是复数的实部,第二个参数是复数的虚部
c1 = 10 + 4j
c2 = complex(10, 4)

print(c1)  # (10+4j)

print(c2)  # 等同与c1    # (10+4j)


# str() : 转换为 字符串类型
num1 = 10
f1 = 3.14

print(type(str(num1)))  # <class 'str'>

print(type(str(f1)))  # <class 'str'>


# repr(): 转换为表达式字符串
num1 = 10
print(type(repr(num1)))  # <class 'str'>


# eval(): 将字符串形式的数据,转换为原本的类型
str1 = "3.14"
print(type(eval(str1)))  # <class 'float'>


str2 = "[10, 20, 30]"
long = eval(str2)
print(type(long))  # <class 'list'>

# chr: 将一个整数转换为对应的 Unicode 字符
s = chr(1065)
print(s)   # Щ

# ord :将一个字符转换为对应的字符编码数字
n = ord("A")
print(n)  # 65

# bin: 将一个整数转换为二进制
print(bin(1024))  # 0b 开头表示二进制数 # 0b10000000000

# oct:将一个整数转换为八进制
print(oct(1024))  # 0o 开头表示八进制数  # 0o2000

# hex: 将一个整数转换为十六进制
print(hex(1024))  # 0x 开头表示十六进制  v

附录:常用字符与ASCII码对照表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UAtwaua4-1622692135007)(file:///E:/python/python%E5%AD%A6%E4%B9%A0%E5%85%A8%E5%A5%97%E8%AF%BE%E4%BB%B6/Python%E5%9F%BA%E7%A1%80%E8%AE%B2%E4%B9%89/file/Images/ASCII%E7%A0%81%E5%AF%B9%E7%85%A7%E8%A1%A8.jpg)]

1.11总结

垃圾回收机制

# 垃圾回收机制详解(了解)
# 1、引用计数
x = 10  # 直接引用
print(id(x))
y = x
z = x
l = ['a', 'b', x]  # 间接引用
print(id(l[2]))  #
d = {'mmm': x}  # 间接引用
print(id(d['mmm']))


x = 10
l = ['a','  b',x]  # l=['a'的内存地址,'b'的内存地址,10的内存地址]

x = 123
print(l[2])


x1 = 10
x2 = [10, ]

l = ['a', 'b',10]


# 2、标记清除:用来解决循环引用带来的内存泄露问题
# 循环引用=>导致内存泄露
l1 = [111, ]
l2 = [222, ]

l1.append(l2) # l1=[值111的内存地址,l2列表的内存地址]
l2.append(l1) # l2=[值222的内存地址,l1列表的内存地址]

print(id(l1[1]))
print(id(l2))

print(id(l2[1]))
print(id(l1))

print(l2)
print(l1[1])

del l1
del l2

# 3、分代回收:用来降低引用计数的扫描频率,提升垃圾回收的效率

二,与用户交互

# 1、接收用户的输入
# 在Python3:input会将用户输入的所有内容都存成字符串类型
username = input("请输入您的账号:")  # "harry"
print(username, type(username))

age = input("请输入的你的年龄: ")  # age="18"
print(age, type(age))

age = int(age)  # int只能将纯数字的字符串转成整型
print(age > 16)

int("12345")
int("1234.5")
int("1234abc5")


# 在python2中:
# raw_input():用法与python3的input一模一样
# input(): 要求用户必须输入一个明确的数据类型,输入的是什么类型,就存成什么类型
# >>> age=input(">>>>>>>>>>>>>>>>>>>>>: ")
# >>>>>>>>>>>>>>>>>>>>>: 18
# >>> age,type(age)
# (18, <type 'int'>)
# >>>
# >>> x=input(">>>>>>>>>>>>>>>>>>>>>: ")
# >>>>>>>>>>>>>>>>>>>>>: 1.3
# >>> x,type(x)
# (1.3, <type 'float'>)
# >>>
# >>> x=input(">>>>>>>>>>>>>>>>>>>>>: ")
# >>>>>>>>>>>>>>>>>>>>>: [1,2,3]
# >>> x,type(x)
# ([1, 2, 3], <type 'list'>)
# >>>


# 2。字符串的格式化输出
# 2.1 %
# 值按照位置与%s一一对应,少一个不行,多一个也不行
res = "my name is %s my age is %s" %('harry', "18")
res = "my name is %s my age is %s" %("18", 'harry')
res = "my name is %s" %"harry"
print(res)

# 以字典的形式传值,打破位置的限制
res = "我的名字是 %(name)s 我的年龄是 %(age)s" % {"age": "18", "name": 'harry'}
print(res)

# %s可以接收任意类型
print('my age is %s' % 18)
print('my age is %s' % [1, 23])
print('my age is %s' % {'a': 333})
print('my age is %d' % 18)  # %d只能接收int

# 2.2 str.format:兼容性好
# 按照位置传值
res = '我的名字是 {} 我的年龄是 {}'.format('harry', 18)
print(res)
res = '我的名字是 {0}{0}{0} 我的年龄是 {1}{1}'.format('harry', 18)
print(res)

# 打破位置的限制,按照key=value传值
res = "我的名字是 {name} 我的年龄是 {age}".format(age=18, name='harry')
print(res)

# 2.4 填充与格式化
# 先取到值,然后在冒号后设定填充格式:[填充字符][对齐方式][宽度]
# *<10:左对齐,总共10个字符,不够的用*号填充
print('{0:*<10}'.format('开始执行')) # 开始执行******

# *>10:右对齐,总共10个字符,不够的用*号填充
print('{0:*>10}'.format('开始执行')) # ******开始执行

# *^10:居中显示,总共10个字符,不够的用*号填充
print('{0:*^10}'.format('开始执行')) # ***开始执行***
# 2.5 精度与进制

print('{salary:.3f}'.format(salary=1232132.12351))  #精确到小数点后3位,四舍五入,结果为:1232132.124
print('{0:b}'.format(123))  # 转成二进制,结果为:1111011
print('{0:o}'.format(9))  # 转成八进制,结果为:11
print('{0:x}'.format(15))  # 转成十六进制,结果为:f
print('{0:,}'.format(99812939393931))  # 千分位格式化,结果为:99,812,939,393,931



# 2.3 f:python3.5以后才推出
x = input('your name: ')
y = input('your age: ')
res = f'我的名字是{x} 我的年龄是{y}'
print(res)

十,运算符

一, 运算符

# 1、算数运算符
print(10 + 3.1)
print(10 + 3)
print(10 / 3)  # 结果带小数
print(10 // 3)  # 只保留整数部分
print(10 % 3)  # 取模、取余数
print(10 ** 3)  # 取模、取余数
# 2、比较运算符: >、>=、<、<=、==、!=
print(10 > 3)
print(10 == 10)

print(10 >= 10)
print(10 >= 3)

name = input('your name: ')
print(name == 'harry')


# 3、赋值运算符
# 3.1 =:变量的赋值
# 3.2 增量赋值:
age = 18
age += 1  # age=age + 1
print(age)

age *= 3
age /= 3
age %= 3
age **= 3  # age=age**3

# 3.3 链式赋值
x = 10
y = x
z = y
z = y = x = 10  # 链式赋值
print(x, y, z)
print(id(x), id(y), id(z))

# 3.4 交叉赋值
m = 10
n = 20
print(m, n)
# 交换值
# temp = m
# m = n
# n = temp
# print(m, n)

m, n = n, m # 交叉赋值
print(m, n)

# 3.5 解压赋值
salaries = [111, 222, 333, 444, 555]
# 把五个月的工资取出来分别赋值给不同的变量名
mon0 = salaries[0]
mon1 = salaries[1]
mon2 = salaries[2]
mon3 = salaries[3]
mon4 = salaries[4]

# 解压赋值
mon0, mon1, mon2, mon3, mon4 = salaries
print(mon0)
print(mon1)
print(mon2)
print(mon3)
print(mon4)

mon0, mon1, mon2, mon3 = salaries  # 对应的变量名少一个不行
mon0, mon1, mon2, mon3, mon4, mon5 = salaries # 对应的变量名多一个也不行

# 引入*,可以帮助我们取两头的值,无法取中间的值
# 取前三个值
x, y, z, *_ = salaries = [111, 222, 333, 444, 555]  # *会将没有对应关系的值存成列表然后赋值给紧跟其后的那个变量名,此处为_
print(x, y, z)
print(_)

# 取后三个值
*_, x, y, z = salaries =[111,222,333,444,555]
print(x,y,z)

x,*_,y,z=salaries=[111,222,333,444,555]
print(x,y,z)

salaries=[111,222,333,444,555]
_,*middle,_=salaries
print(middle)

# 解压字典默认解压出来的是字典的key
x, y, z = dic = {'a': 1, 'b': 2, 'c': 3}
print(x, y, z)

二,小测试

  1、什么是变量?为何要有变量?
    
    变量就是可以变化的量,量指的是事物的状态,比如人的年龄,性别,游戏角色的等级,金钱等等
    
  2、变量的三大组成部分是?每部分的作用是什么?
        先定义后引用
            xxx=10
            print(xxx)
            
 3、变量名的命名原则、规范、风格
    name="harry"

    age_of_egon=18
    AgeOfEgon=18

4、变量值的三个特征是什么?
    id(18):id是值在内存中的身份证号
    type(18)
    18
5、is与==的区别
    is:判断的是id,id是变量值的身份,所以is称之为身份运算符
    ==:判断的是值

6、id相同值是否可以相同?
       id相同值一定相同
7、id不同值是否可以相同?
       id不同值可以相同

        value1 == value2
        value1 is value2
8、用变量的定义说明int、float、str、list、dict、bool类型用于记录何种状态,每种类型
    至少写出三个示例,如下所示
        # int型
        age = 10
        level = 3
        year = 1990
        
        
        
        
 list与dict:
        相同点:都能存多个值,称之为容器类型
        不同点:
            list是用索引对应值,索引反映的是位置/顺序
            dict是用key对应值,其中key通常为字符串类型,而str类型具有描述性功能
                 所以key对值可以有描述性功能

            msg = "egon 10"
            l=['egon',10]
            info={'name':'egon','age':10}
            info['name']

            info={0:'egon',1:10}
内容
    1、垃圾回收机制详解(了解)
        引用计数
        标记清除
        分代回收
2、与用户交互
    接收用户输入
        # python3中
            input
        # python2.7(了解)
            input
            raw_input
    格式化输出
        %
        str.format
        f''

3、基本运算符
    算数运算符
    赋值运算符
        =
        增量赋值
        链式赋值
        交叉赋值
        解压赋值
    比较运算符
    逻辑运算符
        not、and、or
        区分优先级:not > and > or

        了解:
            短路运算
    成员运算符
        in
    身份运算符
        is

3、流程控制之if判断
    if 条件:
        代码块
    elif 条件:
        代码块
    。。。
    else:
        代码块
        

三,可变不可变类型

# 1、可变不可变类型

可变类型: 值改变,id不变,证明改变的是原值, 证明原值是可以被改变的
不可变类型: 值改变,id也变了,证明是产生新的值,压根没有改变原值,证明原值不可被修改的
# 2、验证
# 2.1 int是不可变类型
x = 10
print(id(x))
x = 11  # 产生新值
print(id(x))

# 2.2 float是不可变类型
x = 3.1
print(id(x))
x = 3.2
print(id(x))

# 2.3 str是不可变类型
x = "abc"
print(id(x))
x = 'gggg'
print(id(x))

# 小结:int、float、str都被设计成了不可分割的整体,不能够被改变

# 2.4 list是可变类型
l = ['aaa', 'bbb', 'ccc']
print(id(l))
l[0] = 'AAA'
print(l)
print(id(l))

# 2.5 dict
dic = {'k1': 111, 'k2': 222}
print(id(dic))
dic['k1'] = 3333333333
print(dic)
print(id(dic))



# 2.6 bool不可变
# 关于字典补充:
# 定义:{}内用逗号分隔开多key:value,
#           其中value可以是任意类型
#           但是key必须是不可变类型

dic1 = {
    'k1': 111,
    'k2': 3.1,
    'k3': [333, ],
    'k4': {'name':'egon'}
}

dic2 = {
    2222: 111,
    3.3: 3.1,
    'k3': [333, ],
    'k4': {'name':'egon'}
}

四,条件

# 2、什么是条件?什么可以当做条件?为何要要用条件?
# 第一大类:显式布尔值
# 2.1 条件可以是:比较运算符
age = 18
print(age > 16)  # 条件判断之后会得到一个布尔值

# 2.1 条件可以是:True、False
is_beautiful = True
print(is_beautiful)


# 第二大类:隐式布尔值,所有的值都可以当成条件去用
# 其中0、None、空(空字符串、空列表、空字典)=》代表的布尔值为False,其余都为真



五,逻辑运算符

# 一:not、and、or的基本使用
# not:就是把紧跟其后的那个条件结果取反
# ps:not与紧跟其后的那个条件是一个不可分割的整体

print(not 16 > 13)
print(not True)
print(not False)
print(not 10)
print(not 0)
print(not None)
print(not '')

# and:逻辑与,and用来链接左右两个条件,两个条件同时为True,最终结果才为真
print(True and 10 > 3)

print(True and 10 > 3 and 10 and 0)  # 条件全为真,最终结果才为True

print( 10 > 3 and 10 and 0 and 1 > 3 and 4 == 4 and 3 != 3)  # 偷懒原则

# or:逻辑或,or用来链接左右两个条件,两个条件但凡有一个为True,最终结果就为True,
#            两个条件都为False的情况下,最终结果才为False
print(3 > 2 or 0)
print(3 > 4 or False or 3 != 2 or 3 > 2 or True)  # 偷懒原则

# 二:优先级not>and>or
# ps:
# 如果单独就只是一串and链接,或者说单独就只是一串or链接,按照从左到右的顺讯依次运算即可(偷懒原则)
# 如果是混用,则需要考虑优先级了

res=3>4 and not 4>3 or 1==3 and 'x' == 'x' or 3 >3
print(res)

#       False                 False              False
res=(3>4 and (not 4>3)) or (1==3 and 'x' == 'x') or 3 >3
print(res)


res=3>4 and ((not 4>3) or 1==3) and ('x' == 'x' or 3 >3)
print(res)

六,成员运算与身份运算

# 1、成员运算符
print("harry" in "hello harry")  # 判断一个字符串是否存在于一个大字符串中
print("e" in "hello harry")  # 判断一个字符串是否存在于一个大字符串中

print(111 in [111, 222, 33])  # 判断元素是否存在于列表

# 判断key是否存在于字典
print(111 in {"k1": 111, 'k2': 222})
print("k1" in {"k1": 111, 'k2': 222})

# not in
print("harry" not in "hello harry")  # 推荐使用
print(not"harry" in "hello harry")  # 逻辑同上,但语义不明确,不推荐

# 2、身份运算符
# is # 判断的是id是否相等

七,流程控制之if判断

# if 条件:
#     代码1
#     代码2
#     代码3
print(4)
print(5)
'''
语法1:
if 条件:
    代码1
    代码2
    代码3

'''
print(1)
print(2)
print(3)

age = 18
is_beautiful = True
star = '白羊座'
if age > 16 and age < 20 and is_beautiful and star == '白羊座':
    print('我喜欢,我们在一起吧。。。')

print('其他代码.............')



'''
语法2:
if 条件:
    代码1
    代码2
    代码3
else:
    代码1
    代码2
    代码3
'''

# age = 60
# is_beautiful = True
# star = '水平座'
#
# if age > 16 and age < 20 and is_beautiful and star == '水平座':
#     print('我喜欢,我们在一起吧。。。')
# else:
#     print('阿姨好,我逗你玩呢,深藏功与名')
#
# print('其他代码.............')


'''
语法3:
if 条件1:
    代码1
    代码2
    代码3
elif 条件2:
    代码1
    代码2
    代码3
elif 条件2:
    代码1
    代码2
    代码3
'''
# score=73
# if score >= 90:
#     print('优秀')
# elif score >= 80 and score < 90:
#     print('良好')
# elif score >= 70 and score < 80:
#     print('普通')

# 改进
# score = input('请输入您的成绩:') # score="18"
# score=int(score)
#
# if score >= 90:
#     print('优秀')
# elif score >= 80:
#     print('良好')
# elif score >= 70:
#     print('普通')


'''
语法3:
if 条件1:
    代码1
    代码2
    代码3
elif 条件2:
    代码1
    代码2
    代码3
elif 条件2:
    代码1
    代码2
    代码3
...
else:
    代码1
    代码2
    代码3
'''
# score = input('请输入您的成绩:') # score="18"
# score=int(score)
#
# if score >= 90:
#     print('优秀')
# elif score >= 80:
#     print('良好')
# elif score >= 70:
#     print('普通')
# else:
#     print('很差,小垃圾')
#
# print('=====>')


'''
if嵌套if
'''
age = 17
is_beautiful = True
star = '水平座'

if 16 < age < 20 and is_beautiful and star == '水平座':
    print('开始表白。。。。。')
    is_successful = True
    if is_successful:
        print('两个从此过上没羞没臊的生活。。。')
else:
    print('阿姨好,我逗你玩呢,深藏功与名')

print('其他代码.............')




八,流程控制语序之while循环

# 1、循环的语法与基本使用
'''
print(1)
while 条件:
     代码1
     代码2
     代码3
print(3)
'''

# count=0
# while count < 5: # 5 < 5
#     print(count) # 0,1,2,3,4
#     count+=1 # 5
#
# print('顶级代码----->')


# 2、死循环与效率问题
# count=0
# while count < 5: # 5 < 5
#     print(count) # 0,1,2,3,4

# while True:
#     name=input('your name >>>> ')
#     print(name)

# 纯计算无io的死讯会导致致命的效率问题
# while True:
#     1+1

# while 1:
#     print('xxxx')

# 3、循环的应用
username = 'egon'
password = '123'

# 两个问题:
# 1、重复代码
# 2、输对了应该不用再重复
# while True:
#     inp_name=input('请输入您的账号:')
#     inp_pwd=input('请输入您的密码:')
#
#     if inp_name  == username and inp_pwd == password:
#         print('登录成功')
#     else:
#         print('账号名或密码错误')


# 4、退出循环的两种方式
# 方式一:将条件改为False,等到下次循环判断条件时才会生效
# tag=True
# while tag:
#     inp_name=input('请输入您的账号:')
#     inp_pwd=input('请输入您的密码:')
#
#     if inp_name  == username and inp_pwd == password:
#         print('登录成功')
#         tag = False # 之后的代码还会运行,下次循环判断条件时才生效
#     else:
#         print('账号名或密码错误')
#
#     # print('====end====')

# 方式二:break,只要运行到break就会立刻终止本层循环
# while True:
#     inp_name=input('请输入您的账号:')
#     inp_pwd=input('请输入您的密码:')
#
#     if inp_name  == username and inp_pwd == password:
#         print('登录成功')
#         break # 立刻终止本层循环
#     else:
#         print('账号名或密码错误')
#
#     # print('====end====')


# 7、while循环嵌套与结束
'''
tag=True
while tag:
    while tag:
        while tag:
            tag=False


# 每一层都必须配一个break
while True:
    while True:
        while True:
            break
        break
    break
'''
## break的方式
# while True:
#     inp_name=input('请输入您的账号:')
#     inp_pwd=input('请输入您的密码:')
#
#     if inp_name  == username and inp_pwd == password:
#         print('登录成功')
#         while True:
#             cmd=input("输入命令>: ")
#             if cmd == 'q':
#                 break
#             print('命令{x}正在运行'.format(x=cmd))
#         break # 立刻终止本层循环
#     else:
#         print('账号名或密码错误')
#
#     # print('====end====')

# # 改变条件的方式
# tag=True
# while tag:
#     inp_name=input('请输入您的账号:')
#     inp_pwd=input('请输入您的密码:')
#
#     if inp_name  == username and inp_pwd == password:
#         print('登录成功')
#         while tag:
#             cmd=input("输入命令>: ")
#             if cmd == 'q':
#                 tag=False
#             else:
#                 print('命令{x}正在运行'.format(x=cmd))
#     else:
#         print('账号名或密码错误')


# 8、while +continue:结束本次循环,直接进入下一次
# 强调:在continue之后添加同级代码毫无意义,因为永远无法运行
# count=0
# while count < 6:
#     if count == 4:
#         count+=1
#         continue
#         # count+=1 # 错误
#     print(count)
#     count+=1

# 9、while +else:针对break
# count=0
# while count < 6:
#     if count == 4:
#         count+=1
#         continue
#     print(count)
#     count+=1
# else:
#     print('else包含的代码会在while循环结束后,并且while循环是在没有被break打断的情况下正常结束的,才不会运行')

# count=0
# while count < 6:
#     if count == 4:
#         break
#     print(count)
#     count+=1
# else:
#     print('======>')


# 应用案列:
# 版本1:
# count=0
# tag=True
# while tag:
#     if count == 3:
#         print('输错三次退出')
#         break
#     inp_name=input('请输入您的账号:')
#     inp_pwd=input('请输入您的密码:')
#
#     if inp_name  == username and inp_pwd == password:
#         print('登录成功')
#         while tag:
#             cmd=input("输入命令>: ")
#             if cmd == 'q':
#                 tag=False
#             else:
#                 print('命令{x}正在运行'.format(x=cmd))
#     else:
#         print('账号名或密码错误')
#         count+=1

# 版本2:优化
count = 0
while count < 3:
    inp_name = input('请输入您的账号:')
    inp_pwd = input('请输入您的密码:')

    if inp_name == username and inp_pwd == password:
        print('登录成功')
        while True:
            cmd = input("输入命令>: ")
            if cmd == 'q':  # 整个程序结束,退出所有while循环
                break
            else:
                print('命令{x}正在运行'.format(x=cmd))
        break
    else:
        print('账号名或密码错误')
        count += 1
else:
    print('输错3次,退出')


九,稳固知新代码

l = [111, 222, 333]
l2 = l  # 把l的内存地址给l2

l[0] = 'balabla'
print(l)

print(l2)

l2[1] = 4444444444444
print(l2)
print(l)


del l2



# 格式化输出
print('my name is %s age is %s' % ('Harry', 18))
print('成功的概率 %s%% ' % (97,))



# """
name: {}
age: {}
sex: {}
""".format('Harry',18,'male')

# """
# name:{x}
# age:{y}
# sex:{z}
""".format(z='male',x='Harry',y=18)

# format新增(了解):
print('{x}=============='.format(x='开始执行')) # 开始执行******
print('{x:=<10}'.format(x='开始执行')) # 开始执行******
print('{x:=>10}'.format(x='开始执行')) # 开始执行******
print('{x:=^10}'.format(x='开始执行')) # 开始执行******

# 四舍五入
print('{salary:.3f}'.format(salary=1232132.12351))  #精确到小数点后3位,四舍五入,结果为:1232132.124


x='Harry'
y=18
res=f'name:{x} age {y}'
print(res)


x='Harry'
y=18
res=f'name:{{{x}}} age {y}'
print(res)

# 了解f的新用法:{}内的字符串可以被当做表达式运行
res=f'{10+3}'
print(res)

f'{print("aaaa")}'

十一 深浅拷贝

list1 =[
    'harry',
    'lxx',
    [1,2]
]

# 1、二者分隔不开,list改list2也跟着该,因为指向的就是同一个地址
list2 = list1  # 这不叫copy
list1[0] = 'EGON'
print(list2)

# 2、需求:
# 1、拷贝一下原列表产生一个新的列表
# 2、想让两个列表完全独立开,并且针对的是改操作的独立而不是读操作


# 3、如何copy列表
# 3.1 浅copy:是把原列表第一层的内存地址不加区分完全copy一份给新列表
list1 = [
    'harry',
    'lxx',
    [1, 2]
]

list3 = list1.copy()
print(list3)
print(id(list1))
print(id(list3))

print(id(list1[0]), id(list1[1]), id(list1[2]))
print(id(list3[0]), id(list3[1]), id(list3[2]))

# 实验1:对于不可变类型的赋值,都是产生了新值,让原列表的索引指向新的
# 内存地址,并不会影响新列表
list1[0] = 'EGON'
list1[1] = 'LXX'
list1[2] = 123

# 实验2:但对于可变类型,我们可以改变可变类型中包含的值,但内存地址不变
# 即原列表的索引指向仍然指向原来的内存地址,于是新列表也跟着一起受
# 影响,如下
list1[2][0] = 111
list1[2][1] = 222
print(list1)
print(list3)

# 综合实验1和实验2可以得出,要想copy得到的新列表与原列表的改操作完全独立开
# 必须有一种可以区分开可变类型与不可变类型的copy机制,这就是深copy

# 3.2 深copy
import copy
list1 = [
    'harry',
    'lxx',
    [1, 2]
]

list3 = copy.deepcopy(list1)

print(id(list1))
print(id(list3))
print(list3)

#          不可变        不可变        可变
print(id(list1[0]), id(list1[1]), id(list1[2]))
print(id(list3[0]), id(list3[1]), id(list3[2]))
'''
4497919088 4498367856 4498449216
4497919088 4498367856 4498595328
'''
# print(list3)
# print(id(list1[2][0]),id(list1[2][1]))
# print(id(list3[2][0]),id(list3[2][1]))

list1[0] = 'EGON'
list1[1] = 'LXX'

list1[2][0] = 111
list1[2][1] = 222
print(list1)
print(list3)

小测试

作业(必做题):
1. 使用while循环输出1 2 3 4 5 6     8 9 10
2. 求1-100的所有数的和
3. 输出 1-100 内的所有奇数
4. 输出 1-100 内的所有偶数
5. 求1-2+3-4+5 ... 99的所有数的和
6. 用户登陆(三次机会重试)
7:猜年龄游戏
    要求:
    允许用户最多尝试3次,3次都没猜对的话,就直接退出,如果猜对了,打印恭喜信息并退出

8:猜年龄游戏升级版
要求:
    允许用户最多尝试3次
    每尝试3次后,如果还没猜对,就问用户是否还想继续玩,如果回答Y或y, 就继续让其猜3次,以此往复,如果回答N或n,就退出程序
    如何猜对了,就直接退出


2.判断语句和循环语句

2.1 判断语句介绍

如果某些条件满足,才能做某件事情;条件不满足时,则不能做

2.2 if语句的基本格式

if判断语句

  1. if判断语句基本格式介绍
  • if语句是用来进行判断的,其使用格式如下:
    if 要判断的条件:
        条件成立时,要做的事情
  • demo1:(demo的中文意思:演示、案例)
    age = 30

    print("------if判断开始------")

    if age >= 18:
        print("我已经成年了")

    print("------if判断结束------")
  • 运行结果:
    ------if判断开始------
    我已经成年了
    ------if判断结束------
  • demo2:
    age = 16

    print("------if判断开始------")

    if age >= 18:
        print("我已经成年了")

    print("------if判断结束------")
  • 运行结果:
    ------if判断开始------
    ------if判断结束------

小总结:

  • 以上2个demo仅仅是age变量的值不一样,导致结果却不同;能够看得出if判断语句的作用:就是当满足一定条件时才会执行代码块语句,否则就不执行代码块语句。

  • 注意:代码的缩进为一个tab键,或者4个空格

2.2比较运算符

if判断语句

  1. if判断语句基本格式介绍
  • if语句是用来进行判断的,其使用格式如下:
    if 要判断的条件:
        条件成立时,要做的事情
  • demo1:(demo的中文意思:演示、案例)
    age = 30

    print("------if判断开始------")

    if age >= 18:
        print("我已经成年了")

    print("------if判断结束------")
  • 运行结果:
    ------if判断开始------
    我已经成年了
    ------if判断结束------
  • demo2:
    age = 16

    print("------if判断开始------")

    if age >= 18:
        print("我已经成年了")

    print("------if判断结束------")
  • 运行结果:
    ------if判断开始------
    ------if判断结束------

小总结:

  • 以上2个demo仅仅是age变量的值不一样,导致结果却不同;能够看得出if判断语句的作用:就是当满足一定条件时才会执行代码块语句,否则就不执行代码块语句。
  • 注意:代码的缩进为一个tab键,或者4个空格

2.3比较运算符

  1. 比较(即关系,条件)运算符

python中的比较运算符如下表

运算符 描述 示例
== 检查两个操作数的值是否相等,如果是则条件变为真。 如a=3,b=3,则(a == b) 为 True
!= 检查两个操作数的值是否相等,如果值不相等,则条件变为真。 如a=1,b=3,则(a != b) 为 True
> 检查左操作数的值是否大于右操作数的值,如果是,则条件成立。 如a=7,b=3,则(a > b) 为 True
< 检查左操作数的值是否小于右操作数的值,如果是,则条件成立。 如a=7,b=3,则(a < b) 为 False
>= 检查左操作数的值是否大于或等于右操作数的值,如果是,则条件成立。 如a=3,b=3,则(a >= b) 为 True
<= 检查左操作数的值是否小于或等于右操作数的值,如果是,则条件成立。 如a=3,b=3,则(a <= b) 为 True
# 关系运算符
 
# == 等于:表示左右两个操作数是否相等,如果相等则整个表达式的值为 True;不相等则为False
num1 = 15
num2 = 20
print(num1 == num2)  # False

# != 不等于
print(num1 != num2)  # True

# > 大于
print(num1 > num2)  # False

# < 小于
print(num1 < num2)  # True

# >= 大于等于: num1 大于 或者 等于 num2 ,条件都成立
print(num1 >= num2)   # False

# <= 小于等于: num1 小于 或者 等于 num2 ,条件都成立
print(num1 <= num2)  # True

if num1 >= num2:
    print("条件成立!")
  1. 逻辑运算符
运算符 逻辑表达式 描述 实例
and x and y 布尔"与":如果 x 为 False,x and y 返回 False,否则它返回 y 的值。 True and False, 返回 False。
or x or y 布尔"或":如果 x 是 True,它返回 True,否则它返回 y 的值。 False or True, 返回 True。
not not x 布尔"非":如果 x 为 True,返回 False 。如果 x 为 False,它返回 True。 not True 返回 False, not False 返回 True
# 逻辑运算符
# and : 左右表达式都为True,整个表达式结果才为 True
if (1 == 1) and (10 > 3):
    print("条件成立!")  # 条件成立!
 
# or : 左右表达式有一个为True,整个表达式结果就为 True
if (1 == 2) or (10 > 3):
    print("条件成立!")  # 条件成立!

# not:将右边表达式的逻辑结果取反,True 变为False,False变为True
if not (1 == 2):
    print("条件成立!")  # 条件成立!

2.4 if...else..语句格式

if-else

想一想:在使用if的时候,它只能做到满足条件时要做的事情。那万一需要在不满足条件的时候,做某些事,该怎么办呢?

答:使用 if-else

  1. if-else的使用格式
    if 条件:
        满足条件时要做的事情1
        满足条件时要做的事情2
        满足条件时要做的事情3
        ...(省略)...
    else:
        不满足条件时要做的事情1
        不满足条件时要做的事情2
        不满足条件时要做的事情3
        ...(省略)...

demo1

    chePiao = 1 # 用1代表有车票,0代表没有车票
    if chePiao == 1:
        print("有车票,可以上火车")
        print("终于可以见到Ta了,美滋滋~~~")
    else:
        print("没有车票,不能上车")
        print("亲爱的,那就下次见了")

结果1:有车票的情况

    有车票,可以上火车
    终于可以见到Ta了,美滋滋~~~

结果2:没有车票的情况

    没有车票,不能上车
    亲爱的,那就下次见了

2.5. if...elif...else...语句格式

if...elif...else...语句格式

  • 想一想:

    if能完成当xxx时做事情

    if-else能完成当xxx时做事情1,否则做事情2

    如果有这样一种情况:当xxx1满足时做事情1;当xxx1不满足、xxx2满足时做事情2;当xxx2不满足、xxx3满足时做事情3,那该怎么实现呢?

  • 答:

    elif

  1. elif的功能

elif的使用格式如下:

    if xxx1:
        事情1
    elif xxx2:
        事情2
    elif xxx3:
        事情3

说明:

  • 当xxx1满足时,执行事情1,然后整个if结束
  • 当xxx1不满足时,那么判断xxx2,如果xxx2满足,则执行事情2,然后整个if结束
  • 当xxx1不满足时,xxx2也不满足,如果xxx3满足,则执行事情3,然后整个if结束

demo:

    score = 77

    if score>=90 and score<=100:
        print('本次考试,等级为A')
    elif score>=80 and score<90:
        print('本次考试,等级为B')
    elif score>=70 and score<80:
        print('本次考试,等级为C')
    elif score>=60 and score<70:
        print('本次考试,等级为D')
    elif score>=0 and score<60:
        print('本次考试,等级为E')
  1. 注意点
  • 可以和else一起使用

       if 性别为男性:
           输出男性的体重
           ...
       elif 性别为女性:
           输出女性的体重
           ...
       else:
           第三种性别的体重
           ...
    

    说明:

    • 当 “性别为男性” 满足时,执行 “输出男性的体重”的相关代码
    • 当 “性别为男性” 不满足时,如果 “性别为女性”满足,则执行 “输出女性的体重”的相关代码
    • 当 “性别为男性” 不满足,“性别为女性”也不满足,那么久默认执行else后面的代码,即 “第三种性别的体重”相关代码

elif必须和if一起使用,否则出错

else 一般用在最后,即所有条件都不满足时使用

  1. if 实现三目运算操作

a if a > b else b

如果 a > b的条件成立,三目运算的结果是a,否则就是b

2.6 if语句的嵌套

if嵌套

通过学习if的基本用法,已经知道了

  • 当需要满足条件去做事情的这种情况需要使用if
  • 当满足条件时做事情A,不满足条件做事情B的这种情况使用if-else

想一想:

坐火车或者地铁的实际情况是:先进行安检如果安检通过才会判断是否有车票,或者是先检查是否有车票之后才会进行安检,即实际的情况某个判断是再另外一个判断成立的基础上进行的,这样的情况该怎样解决呢?

答:

if嵌套

  1. if嵌套的格式
    if 条件1:

        满足条件1 做的事情1
        满足条件1 做的事情2

        if 条件2:
            满足条件2 做的事情1
            满足条件2 做的事情2
  • 说明
    • 外层的if判断,也可以是if-else
    • 内层的if判断,也可以是if-else
    • 根据实际开发的情况,进行选择
  1. if嵌套的应用

demo:

ticket = 1     # 用1代表有车票,0代表没有车票
knife_length = 9     # 刀子的长度,单位为cm

if ticket == 1:
    print("有车票,可以进站")
    if knife_length < 10:
        print("通过安检")
        print("终于可以见到Ta了,美滋滋~~~")
    else:
        print("没有通过安检")
        print("刀子的长度超过规定,等待警察处理...")
else:
    print("没有车票,不能进站")
    print("亲爱的,那就下次见了")

结果1:ticket = 1;knife_length = 9

    有车票,可以进站
    通过安检
    终于可以见到Ta了,美滋滋~~~

结果2:ticket = 1;knife_length = 20

    有车票,可以进站
    没有通过安检
    刀子的长度超过规定,等待警察处理...

结果3:ticket = 0;knife_length = 9

    没有车票,不能进站
    亲爱的,那就下次见了

结果4:ticket = 0;knife_length = 20

    没有车票,不能进站
    亲爱的,那就下次见了

应用:猜拳游戏

  1. 强化 多个条件 的 逻辑运算

  2. 体会 import 导⼊模块(“⼯具包”)的使⽤

  3. 需求

1. 从控制台输⼊要出的拳 —— ⽯头(1)/剪⼑(2)/布(3)
2. 电脑 随机 出拳 —— 先假定电脑只会出⽯头,完成整体代码功能
3. ⽐较胜负
  1. 参考代码:
import random

player = input('请输入:剪刀(0)  石头(1)  布(2):')

player = int(player)

# 产生随机整数:0、1、2 中的某一个
computer = random.randint(0,2)

# 用来进行测试
#print('player=%d,computer=%d',(player,computer))

if ((player == 0) and (computer == 2)) or ((player ==1) and (computer == 0)) or ((player == 2) and (computer == 1)):
    print('获胜,哈哈,你太厉害了')
elif player == computer:
    print('平局,要不再来一局')
else:
    print('输了,不要走,洗洗手接着来,决战到天亮')

随机数的处理

  • 在 Python 中,要使⽤随机数,⾸先需要导⼊ 随机数 的 模块 —— “⼯具包”

    import random
    
  • 导⼊模块后,可以直接在 模块名称 后⾯敲⼀个 . 然后按 Tab 键,会提示该模块中包含的所有函数

  • random.randint(a, b) ,返回 [a, b] 之间的整数,包含 a 和 b

2.7 循环语句的介绍

  1. 生活中的循环场景

跑道

  1. 软件开发中循环的使用场景

跟女神告白,说一万遍"渣女,分手吧"

    print("不爱了,分手吧")
    print("不爱了,分手吧")
    print("不爱了,分手吧")
    ...(还有99997遍)...

使用循环语句一句话搞定

    i = 0
    while i < 10000:
        print("不爱了,分手吧")
        i += 1
  1. 小总结
  • while和if的用法基本类似,区别在于:if 条件成立,则执行一次; while 条件成立,则重复执行,直到条件不成立为止。
  • 一般情况下,需要多次重复执行的代码,都可以用循环的方式来完成
  • 循环不是必须要使用的,但是为了提高代码的重复使用率,所以有经验的开发者都会采用循环

2.8 while循环

  1. while循环的格式
    while 条件:
        条件满足时,做的事情1
        条件满足时,做的事情2
        条件满足时,做的事情3
        ...(省略)...
  1. 练习题:循环打印5次
    i = 0
    while i < 5:
        print("当前是第%d次执行循环" % (i + 1))
        print("i=%d" % i)
        i+=1
  1. 结果:
    当前是第1次执行循环
    i=0
    当前是第2次执行循环
    i=1
    当前是第3次执行循环
    i=2
    当前是第4次执行循环
    i=3
    当前是第5次执行循环
    i=4
  1. 死循环

由于程序员的原因,忘记 在循环内部 修改循环的判断条件,导致循环持续执⾏,程序⽆法终⽌!

2.9 while循环应用

  1. 计算1~100的累积和(包含1和100)

参考代码如下:

#encoding=utf-8

i = 1
sum = 0
while i <= 100:
    sum = sum + i
    i += 1

print("1~100的累积和为:%d" % sum)
  1. 计算1~100之间偶数的累积和(包含1和100)

参考代码如下:

#encoding=utf-8

i = 1
sum = 0
while i <= 100:
    if i % 2 == 0:
        sum = sum + i
    i+=1

print("1~100的累积和为:%d" % sum)

while循环嵌套

  • 类似if的嵌套,while嵌套就是:while里面还有while
  1. while嵌套的格式
    while 条件1:

        条件1满足时,做的事情1
        条件1满足时,做的事情2
        条件1满足时,做的事情3
        ...(省略)...

        while 条件2:
            条件2满足时,做的事情1
            条件2满足时,做的事情2
            条件2满足时,做的事情3
            ...(省略)...
  1. while嵌套应用

要求:打印如下图形:

* * * * * 
* * * * * 
* * * * * 
* * * * * 
* * * * *

参考代码:

i = 1
while i <= 5:
    j = 1
    while j <= 5:
        print("*", end=" ")
        j += 1
    print()

    i += 1

3.练习题:打印三角形

要求:打印如下图形:

* 
* * 
* * * 
* * * *  
* * * * *

参考代码:

i = 1
while i <= 5:
    j = 1
    while j <= i:
        print("*", end=" ")
        j += 1
    print()

    i += 1
  1. 练习题: 猜拳游戏(while版)

使用while循环语句实现猜拳游戏.

2.10 for循环

for循环

像while循环一样,for可以完成循环的功能。

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

for循环的格式

for 临时变量 in 列表或者字符串等可迭代对象:
    循环满足条件时执行的代码

demo1

name = 'harry'

for x in name:
    print(x)

运行结果如下:

h
a
r
r
y

demo2

>>> for x in name:
        print(x)
        if x == 'l':
            print("Hello world!")

运行结果如下:

h
e
l
Hello world!
l
Hello world!
o

demo3

# range(5) 在python就业班中进行讲解会牵扯到迭代器的知识,
# 作为刚开始学习python的我们,此阶段仅仅知道range(5)表示可以循环5次即可
for i in range(5):
    print(i)

'''
效果等同于 while 循环的:

i = 0
while i < 5:
    print(i)
    i += 1
'''

运行结果如下:

0
1
2
3
4

2.10 break和continue

  1. break

1.1 for循环

  • 普通的循环示例如下:
name = 'harry'

for x in name:
    print('----')
    print(x)
else:
    print("==for循环过程中,如果没有执行break退出,则执行本语句==")

运行结果:

----
h
----
a
----
r
----
r
----
y
==for循环过程中,如果没有执行break退出,则执行本语句==
  • 带有break的循环示例如下:
name = 'harry'

for x in name:
    print('----')
    if x == 'y':
        break
    print(x)
else:
    print("==for循环过程中,如果没有执行break退出,则执行本语句==")

运行结果:

----
h
----
a
----
r
----
r
----

2.11 while循环

  • 普通的循环示例如下:
i = 0

while i<5:
    i = i+1
    print('----')
    print(i)
else:
    print("==while循环过程中,如果没有执行break退出,则执行本语句==")

运行结果:

----
1
----
2
----
3
----
4
----
5
==while循环过程中,如果没有break则执行==
  • 带有break的循环示例如下:
i = 0

while i<5:
    i = i+1
    print('----')
    if i==3:
        break
    print(i)
else:
    print("==while循环过程中,如果没有执行break退出,则执行本语句==")

运行结果:

----
1
----
2
----

总结:

  • break的作用:立刻结束break所在的循环
  1. continue

2.1. for循环

  • 带有continue的循环示例如下:
name = 'harry'

for x in name:
    print('----')
    if x == 'a': 
        continue
    print(x)
else:
    print("==while循环过程中,如果没有break则执行==")

运行结果:

----
h
----
----
r
----
r
----
y
==while循环过程中,如果没有break则执行==

2.2 while循环

  • 带有continue的循环示例如下:
i = 0

while i<5:
    i = i+1
    print('----')
    if i==3:
        continue
    print(i)

运行结果:

----
1
----
2
----
----
4
----
5

小结:

  • continue的作用:用来结束本次循环,紧接着执行下一次的循环
  1. 注意点
  • break/continue只能用在循环中,除此以外不能单独使用
  • break/continue在嵌套循环中,只对最近的一层循环起作用

3.容器类型

字符串,列表,元组,字典,集合

3.1字符串介绍

字符串介绍

  1. python中字符串的格式

如下定义的变量a,存储的是数字类型的值

    a = 100

如下定义的变量b,存储的是字符串类型的值

    b = "hello"
    或者
    b = 'hello'
    或者
    b = '''hello'''
    或者
    b = """hello"""

小总结:

  • 单引号或者双引号或者三引号中的数据,就是字符串

3.2 字符串输出输入

3.2.1 字符串输出

1.格式化操作符

name = 'harry'
position = 'python工程师'
address = '北京市'

print('--------------------------------------------------')
print("姓名:%s" % name)
print("职位:%s" % position)
print("公司地址:%s" % address)
print('--------------------------------------------------')

结果:

--------------------------------------------------
姓名:harry
职位:python工程师
公司地址:上海市
--------------------------------------------------

2.f-strings

f-strings 提供一种简洁易读的方式, 可以在字符串中包含 Python 表达式. f-strings 以字母 'f' 或 'F' 为前缀, 格式化字符串使用一对单引号、双引号、三单引号、三双引号. 格式化字符串中

name = 'Harry'
age = 18
format_string1 = f'我的名字是 {name}, 我的年龄是 {age}'
format_string2 = f"我的名字是 {name}, 我的年龄是 {age}"
format_string3 = F'''我的名字是 {name}, 我的年龄是 {age}'''
format_string4 = F"""我的名字是 {name}, 我的年龄是 {age}"""
format_string5 = f'3 + 5 = {3 + 5}'
a = 10
b = 20
format_string6 = f'3 + 5 = {a + b}'
# 两个花括号会被替换为一个花括号, 注意{{}} 不表示表达式
format_string7 = F'我的名字是 {{name}}, 我的年龄是 {{age}}'

print(format_string1)
print(format_string2)
print(format_string3)
print(format_string4)
print(format_string5)
print(format_string6)
print(format_string7)

结果:

我的名字是 Harry, 我的年龄是 18
我的名字是 Harry, 我的年龄是 18
我的名字是 Harry, 我的年龄是 18
我的名字是 Harry, 我的年龄是 18
3 + 5 = 8
3 + 5 = 30
我的名字是 {name}, 我的年龄是 {age}

3.2.2 字符串输入

python 在input的时候,通过它能够完成从键盘获取数据,然后保存到指定的变量中;

注意:input获取的数据,都以字符串的方式进行保存,即使输入的是数字,那么也是以字符串方式保存

demo:

userName = input('请输入用户名:')
print("用户名为:%s" % userName)

password = input('请输入密码:')
print("密码为:%s" % password)

结果:(根据输入的不同结果也不同)

请输入用户名:Harry
用户名为:Harry
请输入密码:123456
密码为:123456

3.3 下标和切片

  1. 下标索引

所谓“下标”,就是编号,就好比超市中的存储柜的编号,通过这个编号就能找到相应的存储空间

  • 字符串中"下标"的使用

    列表与元组支持下标索引好理解,字符串实际上就是字符的数组,所以也支持下标索引。

    如果有字符串:name = 'abcdef',在内存中的实际存储如下:

    如果想取出部分字符,那么可以通过下标的方法,(注意python中下标从 0 开始)

       name = 'abcdef'
       print(name[0])
       print(name[1])
       print(name[2])
    

    运行结果:

    a
    b
    c
    
  1. 切片

切片是指对操作的对象截取其中一部分的操作。字符串、列表、元组都支持切片操作。

切片的语法:[起始:结束:步长]

注意:选取的区间从"起始"位开始,到"结束"位的前一位结束(不包含结束位本身),步长表示选取间隔。

我们以字符串为例讲解。

如果取出一部分,则可以在中括号[]中,使用:

     name = 'abcdef'

     print(name[0:3]) # 取 下标0~2 的字符
        
  运行结果:
    
----------------------------------------
abc  
     name = 'abcdef'

     print(name[0:5]) # 取 下标为0~4 的字符
        
  运行结果:
    
----------------------------------------
abcde      
     name = 'abcdef'

     print(name[3:5]) # 取 下标为3、4 的字符
        
        
  运行结果:
    
----------------------------------------
de
     name = 'abcdef'

     print(name[2:]) # 取 下标为2开始到最后的字符
  -------------------------------------------
  运行结果:
        cdef
     name = 'abcdef'

     print(name[1:-1]) # 取 下标为1开始 到 最后第2个  之间的字符
        
          运行结果:
        ---------------------------------
        ebcd
a = "abcdef"
print(a[:3])   # 'abc'

print(a[::2])  # 'ace'

print(a[5:1:2])  # # ''

print(a[1:5:2])  # 'bd'


print(a[::-2])  # 'fdb'


print(a[5:1:-2])  # 'fd'

给定一个字符串aStr, 请反转字符串

# 索引是通过下标取某一个元素
# 切片是通过下标去某一段元素

s = 'Hello World!'

print(s[4])

print(s)

print(s[:])  # 取出所有元素(没有起始位和结束位之分),默认步长为1

print(s[1:])  # 从下标为1开始,取出 后面所有的元素(没有结束位)

print(s[:5])   # 从起始位置开始,取到 下标为5的前一个元素(不包括结束位本身)

print(s[:-1])  # 从起始位置开始,取到 倒数第一个元素(不包括结束位本身)

print(s[-4:-1])  # 从倒数第4个元素开始,取到 倒数第1个元素(不包括结束位本身)

print(s[1:5:2])  # 从下标为1开始,取到下标为5的前一个元素,步长为2(不包括结束位本身)

# python 字符串快速逆置
print(s[::-1])  # 从后向前,按步长为1进行取值

3.4 字符串常见操作

如有字符串info = 'abca',以下是常见的操作

  1. find

find() 方法检测字符串中是否包含子字符串 str ,如果指定 beg(开始) 和 end(结束) 范围,则检查是否包含在指定范围内,如果指定范围内如果包含指定索引值,返回的是索引值在字符串中的起始位置。如果不包含索引值,返回-1。

info = 'abca'
print(info.find('a'))      # 从下标0开始,查找在字符串里第一个出现的子串,返回结果:0

print(info.find('a', 1))   # 从下标1开始,查找在字符串里第一个出现的子串:返回结果3

print(info.find('3'))      # 查找不到返回-1
  1. index

Python index() 方法检测字符串中是否包含子字符串 str ,如果指定 beg(开始) 和 end(结束) 范围,则检查是否包含在指定范围内,该方法与 python find()方法一样,只不过如果str不在 string中会报一个异常。

info = 'abca'
print(info.index('a'))
print(info.index('a', 1))

print(info.index(3))
---------------------------------------
Traceback (most recent call last):
  File "D:/guiderobot_python/pathfinder/apps/offline_master/__init__.py", line 4, in <module>
    print(info.index(3))
TypeError: must be str, not int
0
3
  1. count

返回 str在start和end之间 在 mystr里面出现的次数

mystr.count(str, start=0, end=len(mystr))
info = 'abca'
print(info.count('a'))
print(info.count('a', 1))
print(info.count('b'))
------------------------------
2
1
1

  1. replace

把 mystr 中的 str1 替换成 str2,如果 count 指定,则替换不超过 count 次.

mystr.replace(str1, str2,  mystr.count(str1))
  1. split

以 str 为分隔符切片 mystr,如果 maxsplit有指定值,则仅分隔 maxsplit 个子字符串

mystr.split(str=" ", 2)    
  1. capitalize

把字符串的第一个字符大写

mystr.capitalize()
  1. title

把字符串的每个单词首字母大写

>>> a = "hello itcast"
>>> a.title()
'Hello Itcast'
  1. startswith

检查字符串是否是以 hello 开头, 是则返回 True,否则返回 False

mystr.startswith(hello)
  1. endswith

检查字符串是否以obj结束,如果是返回True,否则返回 False.

mystr.endswith(obj)
  1. lower

转换 mystr 中所有大写字符为小写

mystr.lower()        
  1. upper

转换 mystr 中的小写字母为大写

mystr.upper()    
  1. lstrip

删除 mystr 左边的空白字符

mystr.lstrip()
  1. rstrip

删除 mystr 字符串末尾的空白字符

mystr.rstrip()    
  1. strip

删除mystr字符串两端的空白字符

>>> a = "\n\t itcast \t\n"
>>> a.strip()
'itcast'
  1. rfind

类似于 find()函数,不过是从右边开始查找.

mystr.rfind(str, start=0,end=len(mystr) )
  1. rindex

类似于 index(),不过是从右边开始.

mystr.rindex( str, start=0,end=len(mystr))
  1. partition

把mystr以str分割成三部分,str前,str和str后

mystr.partition(str)
  1. rpartition

类似于 partition()函数,不过是从右边开始.

mystr.rpartition(str)
  1. splitlines

按照行分隔,返回一个包含各行作为元素的列表

mystr.splitlines()  
  1. isalpha

如果 mystr 所有字符都是字母 则返回 True,否则返回 False

mystr.isalpha()  
  1. isdigit

如果 mystr 只包含数字则返回 True 否则返回 False.

mystr.isdigit() 
  1. isalnum

如果 mystr 所有字符都是字母或数字则返回 True,否则返回 False

mystr.isalnum()  
  1. isspace

如果 mystr 中只包含空格,则返回 True,否则返回 False.

mystr.isspace()   
  1. join

str 中每个元素后面拼接上mystr,构造出一个新的字符串

mystr.join(str)

3.5 列表介绍

  1. 列表的格式

变量A的类型为列表

    namesList = ['xiaoWang','xiaoZhang','xiaoHua']

比C语言的数组强大的地方在于列表中的元素可以是不同类型的

    testList = [1, 'a']
  1. 打印列表

demo:

    namesList = ['xiaoWang','xiaoZhang','xiaoHua']
    print(namesList[0])
    print(namesList[1])
    print(namesList[2])

结果:

    xiaoWang
    xiaoZhang
    xiaoHua

3.6 列表循环遍历

列表的循环遍历

  1. 使用for循环

为了更有效率的输出列表的每个数据,可以使用循环来完成

demo:

    namesList = ['xiaoWang','xiaoZhang','xiaoHua']
    for name in namesList:
        print(name)

结果:

    xiaoWang
    xiaoZhang
    xiaoHua
  1. 使用while循环

为了更有效率的输出列表的每个数据,可以使用循环来完成

demo:

    namesList = ['xiaoWang','xiaoZhang','xiaoHua']

    length = len(namesList)

    i = 0

    while i<length:
        print(namesList[i])
        i+=1

结果:

    xiaoWang
    xiaoZhang
    xiaoHua

3.7 列表相关操作

列表的相关操作

列表中存放的数据是可以进行修改的,比如"增"、"删"、"改"、"查"

  1. 添加元素("增"append, extend, insert)

append

通过append可以向列表添加元素

demo:

# 定义变量A,默认有3个元素
A = ['1', '2', '3']

print("-----添加之前,列表A的数据-----")
for tempName in A:
    print(tempName)

# 提示、并添加元素
temp = input('请输入要添加的学生姓名:')
A.append(temp)

print("-----添加之后,列表A的数据-----")
for tempName in A:
    print(tempName)

结果:

-----添加之前,列表A的数据-----
1
2
3
请输入要添加的学生姓名:4
-----添加之后,列表A的数据-----
1
2
3
4

Process finished with exit code 0

extend

通过extend可以将另一个集合中的元素逐一添加到列表中

a = [1, 2]
b = [3, 4]
a.append(b)  # [1, 2, [3, 4]]
print(a)

a.extend(b)
print(a)  # [1, 2, [3, 4], 3, 4]

insert

insert(index, object) 在指定位置index前插入元素object

a = [0, 1, 2]

a.insert(4, 9)  # 在地4位插入数字9

print(a)   # [0, 1, 2, 9]
  1. 修改元素("改")

修改元素的时候,要通过下标来确定要修改的是哪个元素,然后才能进行修改

demo:

    #定义变量A,默认有3个元素
    A = ['xiaoWang','xiaoZhang','xiaoHua']

    print("-----修改之前,列表A的数据-----")
    for tempName in A:
        print(tempName)

    #修改元素
    A[1] = 'xiaoLu'

    print("-----修改之后,列表A的数据-----")
    for tempName in A:
        print(tempName)

结果:

    -----修改之前,列表A的数据-----
    xiaoWang
    xiaoZhang
    xiaoHua
    -----修改之后,列表A的数据-----
    xiaoWang
    xiaoLu
    xiaoHua
  1. 查找元素("查"in, not in, index, count)

所谓的查找,就是看看指定的元素是否存在

in, not in

python中查找的常用方法为:

  • in(存在),如果存在那么结果为true,否则为false
  • not in(不存在),如果不存在那么结果为true,否则false

demo

    #待查找的列表
    nameList = ['xiaoWang','xiaoZhang','xiaoHua']

    #获取用户要查找的名字
    findName = input('请输入要查找的姓名:')

    #查找是否存在
    if findName in nameList:
        print('在字典中找到了相同的名字')
    else:
        print('没有找到')

结果1:(找到)

结果2:(没有找到)

说明:

in的方法只要会用了,那么not in也是同样的用法,只不过not in判断的是不存在

index, count

index和count与字符串中的用法相同

a = ['a', 'b', 'c', 'a', 'b']
a.index('a', 1, 3) # 注意是左闭右开区间
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: 'a' is not in list
a.index('a', 1, 4)  # 3
a.count('b')  # 2
a.count('d')  # 0

4.删除元素(del, pop, remove)

类比现实生活中,如果某位同学调班了,那么就应该把这个条走后的学生的姓名删除掉;在开发中经常会用到删除这种功能。

列表元素的常用删除方法有:

  • del:根据下标进行删除
  • pop:删除最后一个元素
  • remove:根据元素的值进行删除

demo:(del)

    movieName = ['加勒比海盗','骇客帝国','第一滴血','指环王','霍比特人','速度与激情']

    print('------删除之前------')
    for tempName in movieName:
        print(tempName)

    del movieName[2]

    print('------删除之后------')
    for tempName in movieName:
        print(tempName)

结果:

    ------删除之前------
    加勒比海盗
    骇客帝国
    第一滴血
    指环王
    霍比特人
    速度与激情
    ------删除之后------
    加勒比海盗
    骇客帝国
    指环王
    霍比特人
    速度与激情

demo:(pop)

    movieName = ['加勒比海盗','骇客帝国','第一滴血','指环王','霍比特人','速度与激情']

    print('------删除之前------')
    for tempName in movieName:
        print(tempName)

    movieName.pop()

    print('------删除之后------')
    for tempName in movieName:
        print(tempName)

结果:

    ------删除之前------
    加勒比海盗
    骇客帝国
    第一滴血
    指环王
    霍比特人
    速度与激情
    ------删除之后------
    加勒比海盗
    骇客帝国
    第一滴血
    指环王
    霍比特人

demo:(remove)

    movieName = ['加勒比海盗','骇客帝国','第一滴血','指环王','霍比特人','速度与激情']

    print('------删除之前------')
    for tempName in movieName:
        print(tempName)

    movieName.remove('指环王')

    print('------删除之后------')
    for tempName in movieName:
        print(tempName)

结果:

    ------删除之前------
    加勒比海盗
    骇客帝国
    第一滴血
    指环王
    霍比特人
    速度与激情
    ------删除之后------
    加勒比海盗
    骇客帝国
    第一滴血
    霍比特人
    速度与激情
  1. 排序(sort, reverse)

sort方法是将list按特定顺序重新排列,默认为由小到大,参数reverse=True可改为倒序,由大到小。

reverse方法是将list逆置。

a = [1, 4, 2, 3]
a.reverse()
print(a)  # [3, 2, 4, 1]
a.sort()
print(a)  # [1, 2, 3, 4]
a.sort(reverse=True)
print(a)  # [4, 3, 2, 1]

3.8 列表嵌套

  1. 列表嵌套

类似while循环的嵌套,列表也是支持嵌套的

一个列表中的元素又是一个列表,那么这就是列表的嵌套

schoolNames = [
    ['北京大学', '清华大学'],
    ['南开大学', '天津大学', '天津师范大学'],
    ['山东大学', '中国海洋大学']
]
  1. 应用

一个学校,有3个办公室,现在有8位老师等待工位的分配,请编写程序,完成随机的分配

#encoding=utf-8

import random

# 定义一个列表用来保存3个办公室
offices = [[],[],[]]

# 定义一个列表用来存储8位老师的名字
names = ['A','B','C','D','E','F','G','H']

i = 0
for name in names:
    index = random.randint(0,2)    
    offices[index].append(name)

i = 1
for tempNames in offices:
    print('办公室%d的人数为:%d'%(i,len(tempNames)))
    i+=1
    for name in tempNames:
        print("%s"%name,end='')
    print("\n")
    print("-"*20)

运行结果如下:

办公室1的人数为:5
ABDEH

--------------------
办公室2的人数为:1
F

--------------------
办公室3的人数为:2
CG

--------------------

Process finished with exit code 0

3.9 元组

Python的元组与列表类似,不同之处在于元组的元素不能修改。元组使用小括号,列表使用方括号。

aTuple = ('et', 77, 99.9)
print(aTuple)  # ('et', 77, 99.9)

说明: python中不允许修改元组的数据,包括不能删除其中的元素。

count, index

index和count与字符串和列表中的用法相同

a = ('a', 'b', 'c', 'a', 'b')
a.index('a', 1, 3) # 注意是左闭右开区间
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: tuple.index(x): x not in tuple
a.index('a', 1, 4) # 3
a.count('b') # 2
a.count('d') # 0

1.对于容器型数据类型list,无论谁都可以对其增删改查,那么有一些重要的数据放在list中是不安全的,所以需要一种容器类的数据类型存放重要的数据,创建之初只能查看而不能增删改,这种数据类型就是元祖。

元祖:俗称不可变的列表,又被成为只读列表,元祖也是python的基本数据类型之一,

用小括号括起来,里面可以放任何数据类型的数据,查询可以,循环也可以,切片也可以.但就是不能改.在python中关键字是tuple

tu = ('我','怎么','这么','可爱')

tu1 = tu[0]  # 记性下标
print(tu1)

for i in tu:
    print(i)  # 进行for循环

tu2 = tu[0:3]
print(tu2)  # 进行切片

结果:
Traceback (most recent call last):
  File "D:/python_object/path2/test.py", line 1286, in <module>
    tu[0] = '你'
NameError: name 'tu' is not defined

关于不可变, 注意: 这里元组的不可变的意思是子元素不可变. 而子元素内部的子元素是可以变, 这取决于子元素是否是可变对象.

元组中如果只有一个元素. 一定要添加一个逗号, 否则就不是元组

tup = ("harry")
print(type(tup))  # type是查看数据类型

# 结果: # <class:str>
tu = ('harry',)
print(type(tu))  #type是查看数据类型

# 结果: <class:tuple>

这个知识点如何使用

1.可遍历

2.可切片

3.有len,count,index方法

2.1 元祖嵌套  

tu = ('今天姐姐不在家','姐夫和小姨子在客厅聊天',('姐夫问小姨子税后多少钱','小姨子低声说道说和姐夫还提钱'))
tu1 = tu[0]
tu2 = tu[1]
tu3 = tu[2][0]
tu4 = tu[2][1]

print(tu1)
print(tu2)
print(tu3)
print(tu4)
结果:
今天姐姐不在家
姐夫和小姨子在客厅聊天
姐夫问小姨子税后多少钱
小姨子低声说道说和姐夫还提钱

在哪里使用

就是将一些非常重要的不可让人改动的数据放在元祖中,只供查看。写项目的时候会有配置文件,配置文件中的不想让人修改的单个变量使用常量,如果是多个不想让人修改的就是用元组来存储

二.range

翻译过来就是范围,那我们我来先看下.

range(0,5,1)

参数第一个是范围的起始位置
参数第二个是范围的结束位置
参数第三个是步长
print(range(0,5))
# 结果:
range(0, 5)  #一个范围
# 我们可以通过list方法来转换这个范围来查看一下
l = list(range(0,5))
print(l)

# 结果:
[0, 1, 2, 3, 4]
l = list(range(0,5,2))
print(l)
# 结果:
[0, 2, 4]   # 这个结果就会发现和我之前用步长获取的内容是相似的,是的他就是步长

 

3.10 字典

字典的介绍

想一想:

如果有列表

nameList = ['xiaoZhang', 'xiaoWang', 'xiaoLi'];

需要对"xiaoWang"这个名字写错了,通过代码修改:

nameList[1] = 'xiaoxiaoWang'

如果列表的顺序发生了变化,如下

nameList = ['xiaoWang', 'xiaoZhang',  'xiaoLi'];

此时就需要修改下标,才能完成名字的修改

nameList[0] = 'xiaoxiaoWang'

有没有方法,既能存储多个数据,还能在访问元素的很方便就能够定位到需要的那个元素呢?

答:

字典

另一个场景:

学生信息列表,每个学生信息包括学号、姓名、年龄等,如何从中找到某个学生的信息?

>>> studens = [[1001, "王bao强", 24], [1002, "马rong", 23], [1005, "宋x",24], ...]
  1. 软件开发中的字典

变量info为字典类型:

info = {'name':'班长', 'id':100, 'sex':'f', 'address':'地球亚洲中国北京'}

说明:

  • 字典和列表一样,也能够存储多个数据
  • 列表中找某个元素时,是根据下标进行的
  • 字典中找某个元素时,是根据'名字'(就是冒号:前面的那个值,例如上面代码中的'name'、'id'、'sex')
  • 字典的每个元素由2部分组成,键:值。例如 'name':'班长' ,'name'为键,'班长'为值
  1. 根据键访问值
info = {'name':'班长', 'id':100, 'sex':'f', 'address':'地球亚洲中国北京'}

print(info['name'])
print(info['address'])

结果:

班长
地球亚洲中国北京

若访问不存在的键,则会报错:

info['age']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'age'

在我们不确定字典中是否存在某个键而又想获取其值时,可以使用get方法,还可以设置默认值:

age = info.get('age')
age #'age'键不存在,所以age为None
type(age)
<type 'NoneType'>
age = info.get('age', 18) # 若info中不存在'age'这个键,就返回默认值18
age
18

3.11 字典常见操作

字典的常见操作1

  1. 查看元素

除了使用key查找数据,还可以使用get来获取数据

demo:

    info = {'name':'吴彦祖','age':18}

    print(info['age']) # 获取年龄

    # print(info['sex']) # 获取不存在的key,会发生异常

    print(info.get('sex')) # 获取不存在的key,获取到空的内容,不会出现异常
  1. 修改元素

字典的每个元素中的数据是可以修改的,只要通过key找到,即可修改

demo:

    info = {'name':'班长', 'id':100, 'sex':'f', 'address':'地球亚洲中国北京'}

    newId = input('请输入新的学号')

    info['id'] = int(newId)

    print('修改之后的id为%d:'%info['id'])

结果:

请输入新的学号1
修改之后的id为1:
  1. 添加元素

demo:访问不存在的元素

    info = {'name':'班长', 'sex':'f', 'address':'地球亚洲中国北京'}

    print('id为:%d'%info['id'])

如果在使用 变量名['键'] = 数据 时,这个“键”在字典中,不存在,那么就会新增这个元素

demo:添加新的元素

    info = {'name':'班长', 'sex':'f', 'address':'地球亚洲中国北京'}

    # print('id为:%d'%info['id'])#程序会终端运行,因为访问了不存在的键

    newId = input('请输入新的学号')

    info['id'] = newId

    print('添加之后的id为:%d'%info['id'])

结果:

    请输入新的学号188
    添加之后的id为: 188
  1. 删除元素

对字典进行删除操作,有一下几种:

  • del
  • clear()

demo:del删除指定的元素

    info = {'name':'班长', 'sex':'f', 'address':'地球亚洲中国北京'}

    print('删除前,%s'%info['name'])

    del info['name']

    print('删除后,%s'%info['name'])

demo:del删除整个字典

    info = {'name':'monitor', 'sex':'f', 'address':'China'}

    print('删除前,%s'%info)

    del info

    print('删除后,%s'%info)

demo:clear清空整个字典

    info = {'name':'monitor', 'sex':'f', 'address':'China'}

    print('清空前,%s'%info)

    info.clear()

    print('清空后,%s'%info)

字典的常见操作2

  1. len()

测量字典中,键值对的个数

  1. keys

返回一个包含字典所有KEY的列表

  1. values

返回一个包含字典所有value的列表

  1. items

返回一个包含所有(键,值)元祖的列表

3.12 字典遍历

遍历

通过for ... in ... 我们可以遍历字符串、列表、元组、字典等

注意python语法的缩进

  1. 字符串遍历
>>> a_str = "hello itcast"
>>> for char in a_str:
...     print(char,end=' ')
...
h e l l o   i t c a s t
  1. 列表遍历
>>> a_list = [1, 2, 3, 4, 5]
>>> for num in a_list:
...     print(num,end=' ')
...
1 2 3 4 5
  1. 元组遍历
>>> a_turple = (1, 2, 3, 4, 5)
>>> for num in a_turple:
...     print(num,end=" ")
1 2 3 4 5
  1. 字典遍历

4.1. 遍历字典的key(键)

4.2. 遍历字典的value(值)

4.3. 遍历字典的项(元素)

4.4. 遍历字典的key-value(键值对)

实现带下标索引的遍历

>>> chars = ['a', 'b', 'c', 'd']
>>> i = 0
>>> for chr in chars:
...     print("%d %s"%(i, chr))
...     i += 1
...
0 a
1 b
2 c
3 d
  1. enumerate()

enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。

>>> chars = ['a', 'b', 'c', 'd']
>>> for i, chr in enumerate(chars):
...     print i, chr
...
0 a
1 b
2 c
3 d

3.13 有序字典

有序字典:OrderDict

我们先看一段代码, 此代码运行在 Python3.5 版本中:

# 创建无序字典
my_dict = dict()
# 向字典中添加元素
my_dict['one'] = 1
my_dict['two'] = 2
my_dict['three'] = 3
my_dict['four'] = 4
print(my_dict)

输出结果(不固定):

{'three': 3, 'two': 2, 'four': 4, 'one': 1}

输出结果并不是按照我们创建字典、添加元素的顺序输出, 这是由于 dict 是无序的. 如果我们想最终打印输出的顺序和我们操作时的顺序保持一致, 我们就需要使用有序字典:

from collections import OrderedDict

# 创建有序字典
my_dict = OrderedDict()
# 向字典中添加元素
my_dict['one'] = 1
my_dict['two'] = 2
my_dict['three'] = 3
my_dict['four'] = 4
print(my_dict)

输出结果:

OrderedDict([('one', 1), ('two', 2), ('three', 3), ('four', 4)])

在 Python3.6 版本中, dict 字典已经经过优化, 变为有序字典. 并且字典所占用的内存占用减少了20%到25%.

第一段代码在 Python3.6 运行下, 输出结果如下:

{'one': 1, 'two': 2, 'three': 3, 'four': 4}

3.14 公共方法

  1. 运算符
运算符 Python 表达式 结果 描述 支持的数据类型
+ [1, 2] + [3, 4] [1, 2, 3, 4] 合并 字符串、列表、元组
* ['Hi!'] * 4 ['Hi!', 'Hi!', 'Hi!', 'Hi!'] 复制 字符串、列表、元组
in 3 in (1, 2, 3) True 元素是否存在 字符串、列表、元组、字典
not in 4 not in (1, 2, 3) True 元素是否不存在 字符串、列表、元组、字典
>>> "hello " + "itcast"
'hello itcast'
>>> [1, 2] + [3, 4]
[1, 2, 3, 4]
>>> ('a', 'b') + ('c', 'd')
('a', 'b', 'c', 'd')
>>> 'ab' * 4
'ababab'
>>> [1, 2] * 4
[1, 2, 1, 2, 1, 2, 1, 2]
>>> ('a', 'b') * 4
('a', 'b', 'a', 'b', 'a', 'b', 'a', 'b')

in

>>> 'itc' in 'hello itcast'
True
>>> 3 in [1, 2]
False
>>> 4 in (1, 2, 3, 4)
True
>>> "name" in {"name":"Delron", "age":24}
True

注意,in在对字典操作时,判断的是字典的键

  1. python内置函数

Python包含了以下内置函数

序号 函数 描述
1 len(item) 计算容器中元素个数
2 max(item) 返回容器中元素最大值
3 min(item) 返回容器中元素最小值
4 del(item) 删除变量

len

>>> len("hello itcast")
12
>>> len([1, 2, 3, 4])
4
>>> len((3,4))
2
>>> len({"a":1, "b":2})
2

注意:len在操作字典数据时,返回的是键值对个数。

max

>>> max("hello itcast")
't'
>>> max([1,4,522,3,4])
522
>>> max({"a":1, "b":2})
'b'
>>> max({"a":10, "b":2})
'b'
>>> max({"c":10, "b":2})
'c'

del

del有两种用法,一种是del加空格,另一种是del()

>>> a = 1
>>> a
1
>>> del a
>>> a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> a = ['a', 'b']
>>> del a[0]
>>> a
['b']
>>> del(a)
>>> a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
  1. 多维列表/元祖访问的示例
>>> tuple1 = [(2,3),(4,5)]
>>> tuple1[0]
(2, 3)
>>> tuple1[0][0]
2
>>> tuple1[0][2]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: tuple index out of range


>>> tuple1[0][1]
3
>>> tuple1[2][2]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range


>>> tuple2 = tuple1+[(3)]
>>> tuple2
[(2, 3), (4, 5), 3]
>>> tuple2[2]
3
>>> tuple2[2][0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not subscriptable

4. 函数

4.1. 函数介绍

函数就是一个具有独立功能的代码块,可以提高代码的复用性

1、什么是函数
    函数就相当于具备某一功能的工具
    函数的使用必须遵循一个原则:
        先定义
        后调用
2、为何要用函数
    1、组织结构不清晰,可读性差
    2、代码冗余
    3、可维护性、扩展性差

3、如何用函数
        先定义
            三种定义方式
        后调用
            三种调用方式

        返回值
            三种返回值的形式

python中,采用下面的语法定义函数:

def 函数名(参数):
    # 内部代码
    return 表达式

例如:

def summer(lis):
    """
    这里是函数的说明文档,doc的位置
    :param lis: 参数列表的说明
    :return: 返回值的说明
    """
    total = 0
    for i in lis:
        total += i
    return total

二,函数定义语法介绍

# 一、先定义
# 定义的语法
'''
def 函数名(参数1,参数2,...):
    """文档描述"""
    函数体
    return 值
'''

注意:

在定义函数的过程中

1. 函数代码块以def关键词开头,一个空格之后接函数标识符名称和圆括号(),再接个冒号。

2.任何传入的参数必须放在圆括号中间。

3.函数的第一行语句后可以选择性地使用文档字符串—用于存放函数说明。

4.函数内容以冒号起始,并且缩进。

5.使用return结束函数。默认返回None。

6.return语句依然在函数体内部,不能回退缩进。直到函数的所有代码写完,才回退缩进,表示函数体结束。


return语句:

一旦函数执行过程遇到return语句,那么之后函数体内的所有代码都会被忽略,直接跳出函数体。

def func():
    pass
    return
    # 此时,后面的代码其实是永远无法执行的。
    # 但从语法和词法层面,这些没有错误。
    print(1)
    abs(-1)
    pass

三,函数的定义与调用

无参函数

 示范1
 def bar(): # bar=函数的内存地址
     print('from bar')

 def foo():
     # print(bar)
     bar()
     print('from foo')

 foo()



 示范2
 def foo():
     # print(bar)
     bar()
     print('from foo')

 def bar():  # bar=函数的内存地址
     print('from bar')

 foo()

 示范3
 def foo():
     # print(bar)
     bar()
     print('from foo')

 foo()

 def bar():  # bar=函数的内存地址
     print('from bar')


 形式二:有参函数
 def func(x,y): # x=1  y=2
     print(x,y)
 func(1,2)

 形式三:空函数,函数体代码为pass
def func(x, y):
    pass

四,定义函数的三种形式

 三种定义方式各用在何处
 1、无参函数的应用场景
 def interactive():
     name=input('username>>: ')
     age=input('age>>: ')
     gender=input('gender>>: ')
     msg='名字:{} 年龄:{} 性别'.format(name,age,gender)
     print(msg)

 interactive()
 interactive()
 interactive()
 interactive()

 2、有参函数的应用场景
 def add(x,y): # 参数-》原材料
     # x=20
     # y=30
     res=x + y
     # print(res)
     return res # 返回值-》产品

 # add(10,2)
 res=add(20,30)
 print(res)

 3、空函数的应用场景
 def auth_user():
     """user authentication function"""
     pass

 def download_file():
     """download file function"""
     pass

 def upload_file():
     """upload file function"""
     pass

 def ls():
     """list contents function"""
     pass

 def cd():
     """change directory"""
     pass


 二、调用函数
 1、语句的形式:只加括号调用函数
 interactive()
 add(1,2)

 2、表达式形式:
 def add(x,y): # 参数-》原材料
     res=x + y
     return res # 返回值-》产品
 赋值表达式
 res=add(1,2)
 print(res)
 数学表达式
 res=add(1,2)*10
 print(res)

 3、函数调用可以当做参数
 res=add(add(1,2),10)
 print(res)

 三、函数返回值
 return是函数结束的标志,即函数体代码一旦运行到return会立刻
 终止函数的运行,并且会将return后的值当做本次运行的结果返回:
1、返回None:函数体内没有return
             return
             return None

 2、返回一个值:return 值
 def func():
     return 10

 res=func()
 print(res)

 3、返回多个值:用逗号分隔开多个值,会被return返回成元组
def func():
    return 10, 'aa', [1, 2]

res = func()
print(res, type(res))

4.2. 函数的定义和调用

注意:每次调用函数时,函数都会从头开始执行,当这个函数中的代码执行完毕后,意味着调用结束了

当然了如果函数中执行到了return也会结束函数

4.3. 函数的文档说明

def test(a,b):
    """用来完成对2个数求和"""
    print("%d" % (a+b))
test(11,33)

4.4. 函数的参数

def func():
    a = 11
    b = 12
    c = a + b
    print(c)
func()


a = 10
b = 12
def func():
    c = a + b
    print(c)
func()

调用函数时参数的顺序

def test(a,b):
    print(a,b)
# test(1,2)
test(b=1,a=3)
# test()

小结:

定义时小括号中的参数,用来接收参数用的,称为 “形参”
调用时小括号中的参数,用来传递给函数用的,称为 “实参”
  1. 缺省参数

调用函数时,缺省参数的值如果没有传入,则取默认值。

下例会打印默认的age,如果age没有被传入:

def printinfo(name, age=35):
   # 打印任何传入的字符串
   print("name: %s" % name)
   print("age %d" % age)

# 调用printinfo函数
printinfo(name="miki")  # 在函数执行过程中 age去默认值35
printinfo(age=9 ,name="miki")

以上实例输出结果:

name: miki
age: 35
name: miki
age: 9

总结:

  • 在形参中默认有值的参数,称之为缺省参数

  • 注意:带有默认值的参数一定要位于参数列表的最后面

      >>> def printinfo(name, age=35, sex):
      ...     print name
      ...
        File "<stdin>", line 1
      SyntaxError: non-default argument follows default argument
    
  1. 不定长参数

有时可能需要一个函数能处理比当初声明时更多的参数, 这些参数叫做不定长参数,声明时不会命名。

基本语法如下:

def functionname([formal_args,] *args, **kwargs):
   """函数_文档字符串"""
   function_suite
   return [expression]

注意:

  • 加了星号(*)的变量args会存放所有未命名的变量参数,args为元组
  • 而加**的变量kwargs会存放命名参数,即形如key=value的参数, kwargs为字典.
>>> def fun(a, b, *args, **kwargs):
...     """不定长参数演示示例"""
...     print("a =%d" % a)
...     print("b =%d" % b)
...     print("args:")
...     print(args)
...     print("kwargs: ")
...     for key, value in kwargs.items():
...         print("key=%s" % value)
...
>>> fun(1, 2, 3, 4, 5, m=6, n=7, p=8)  # 注意传递的参数对应
a = 1
b = 2
args:
(3, 4, 5)
kwargs: 
p = 8
m = 6
n = 7
>>>
>>>
>>>
>>> c = (3, 4, 5)
>>> d = {"m":6, "n":7, "p":8}
>>> fun(1, 2, *c, **d)    # 注意元组与字典的传参方式
a = 1
b = 2
args:
(3, 4, 5)
kwargs: 
p = 8
m = 6
n = 7
>>>
>>>
>>>
>>> fun(1, 2, c, d) # 注意不加星号与上面的区别
a = 1
b = 2
args:
((3, 4, 5), {'p': 8, 'm': 6, 'n': 7})
kwargs:
>>>
>>>
  1. 缺省参数在*args后面
def sum_nums_3(a, *args, b=22, c=33, **kwargs):
    print(a)
    print(b)
    print(c)
    print(args)
    print(kwargs)

sum_nums_3(100, 200, 300, 400, 500, 600, 700, b=1, c=2, mm=800, nn=900)

说明:

  • 如果很多个值都是不定长参数,那么这种情况下,可以将缺省参数放到 *args的后面, 但如果有kwargs的话,kwargs必须是最后的

4.5. 函数的返回值

#定义函数
def add2num(a, b):
    return a+b

#调用函数,顺便保存函数的返回值
result = add2num(100,98)

#因为result已经保存了add2num的返回值,所以接下来就可以使用了
print(result)

  1. 多个return?
def create_nums():
    print("---1---")
    return 1  # 函数中下面的代码不会被执行,因为return除了能够将数据返回之外,还有一个隐藏的功能:结束函数
    print("---2---")
    return 2
    print("---3---")

总结1:

  • 一个函数中可以有多个return语句,但是只要有一个return语句被执行到,那么这个函数就会结束了,因此后面的return没有什么用处

  • 如果程序设计为如下,是可以的因为不同的场景下执行不同的return

      def create_nums(num):
          print("---1---")
          if num == 100:
              print("---2---")
              return num+1  # 函数中下面的代码不会被执行,因为return除了能够将数据返回之外,还有一个隐藏的功能:结束函数
          else:
              print("---3---")
              return num+2
          print("---4---")
    
      result1 = create_nums(100)
      print(result1)  # 打印101
      result2 = create_nums(200)
      print(result2)  # 打印202
    
  1. 一个函数返回多个数据的方式
def calc_num(a, b):
    num1 = a//b
    num2 = a%b 
    return num1, num2  #默认是元组

result = calc_num(5, 2)
print(result)  # 输出(2, 1)

总结2:

  • return后面可以是元组,列表、字典等,只要是能够存储多个数据的类型,就可以一次性返回多个数据

          def function():
              # return [1, 2, 3]
              # return (1, 2, 3)
              return {"num1": 1, "num2": 2, "num3": 3}
    
  • 如果return后面有多个数据,那么默认是元组

          In [1]: a = 1, 2
          In [2]: a
          Out[2]: (1, 2)
    
          In [3]:
          In [3]: b = (1, 2)
          In [4]: b
          Out[4]: (1, 2)
    
          In [5]:
    

4.6. 函数的嵌套调用

一个函数里面又调用了另外一个函数,这就是所谓的函数嵌套调用

def testB():
    print('---- testB start----')
    print('这里是testB函数执行的代码...(省略)...')
    print('---- testB end----')

def testA():
    print('---- testA start----')
    testB()
    print('---- testA end----')

testA()
  • 如果函数A中,调用了另外一个函数B,那么先把函数B中的任务都执行完毕之后才会回到上次 函数A执行的位置

4.7. 函数的应用

  1. 写一个函数打印一条横线
  2. 打印自定义行数的横线
# 打印一条横线
def printOneLine():
    print("-"*30)

printOneLine()

# 打印多条横线
def printNumLine(num):
    i=0

    # 因为printOneLine函数已经完成了打印横线的功能,
    # 只需要多次调用此函数即可
    while i < num:
        printOneLine()
        i += 1

printNumLine(30)
  1. 写一个函数求三个数的和
  2. 写一个函数求三个数的平均值
# 求3个数的和
def sum3Number(a,b,c):
    return a+b+c # return 的后面可以是数值,也可是一个表达式

# 完成对3个数求平均值

def average3Number(a,b,c):

    # 因为sum3Number函数已经完成了3个数的就和,所以只需调用即可
    # 即把接收到的3个数,当做实参传递即可
    sumResult = sum3Number(a,b,c)
    aveResult = sumResult/3.0
    return aveResult

# 调用函数,完成对3个数求平均值
result = average3Number(11,2,55)
print("average is %d"%result)

4.8. 局部变量

def test1():
    a = 300
    print(a)
    a = 200
    print(a)
def test2():
    a = 500
    print(a)
test1()
test2()

  • 局部变量,就是在函数内部定义的变量
  • 其作用范围是这个函数内部,即只能在这个函数中使用,在函数的外部是不能使用的
  • 因为其作用范围只是在自己的函数内部,所以不同的函数可以定义相同名字的局部变量(打个比方,把你、我是当做成函数,把局部变量理解为每个人手里的手机,你可有个iPhone8,我当然也可以有个iPhone8了, 互不相关)
  • 局部变量的作用,为了临时保存数据需要在函数中定义变量来进行存储
  • 当函数调用时,局部变量被创建,当函数调用完成后这个变量就不能够使用了

4.9. 全局变量


# 定义全局变量
a = 100

def test1():
    print(a)  # 虽然没有定义变量a但是依然可以获取其数据

def test2():
    print(a)  # 虽然没有定义变量a但是依然可以获取其数据

# 调用函数
test1()
test2()
  • 在函数外边定义的变量叫做全局变量
  • 全局变量能够在所有的函数中进行访问
a = 100
def test1():
    a = 300
    print(",,,1")
    a = 200
    print("...2")
def test2():
    print(" ....3")
# 调用函数
test1()
test2()
  • 当函数内出现局部变量和全局变量相同名字时,函数内部中的 变量名 = 数据 此时理解为定义了一个局部变量,而不是修改全局变量的值

  • 如果在函数中出现global 全局变量的名字 那么这个函数中即使出现和全局变量名相同的变量名 = 数据 也理解为对全局变量进行修改,而不是定义局部变量

  • 如果在一个函数中需要对多个全局变量进行修改,那么可以使用

     # 可以使用一次global对多个全局变量进行声明
     global a, b
     # 还可以用多次global声明都是可以的
     # global a
     # global b

4.10. 多个函数共享数据

多个函数函数之间共享数据

一般在实际开发过程中,一个程序往往由多个函数(后面知识中会讲解类)组成,并且多个函数共享某些数据,这种场景是经常出现的,因此下面来总结下,多个函数中共享数据的几种方式

  1. 使用全局变量
g_num = 0

def test1():
    global g_num
    # 将处理结果存储到全局变量g_num中.....
    g_num = 100

def test2():
    # 通过获取全局变量g_num的值, 从而获取test1函数处理之后的结果
    print(g_num)

# 1. 先调用test1得到数据并且存到全局变量中
test1()

# 2. 再调用test2,处理test1函数执行之后的这个值
test2()
  1. 使用函数的返回值
def test1():
     # 通过return将一个数据结果返回
     return 50

def test2(num):
    # 通过形参的方式保存传递过来的数据,就可以处理了
    print(num)

# 1. 先调用test1得到数据并且存到变量result中
result = test1()

# 2. 调用test2时,将result的值传递到test2中,从而让这个函数对其进行处理
test2(result)

4.11. 拆包,交换两个变量的值

1.对容器类型中的数据直接拆包

my_high, my_weight, my_age = (178, 100, 18)
print(my_high)
print(my_weight)
print(my_age)

总结:

  • 拆包时要注意,需要拆的数据的个数要与变量的个数相同,否则程序会异常

  • 除了对元组拆包之外,还可以对列表、字典等拆包

      In [17]: a, b = (11, 22)
      In [18]: a
      Out[18]: 11
      In [19]: b
      Out[19]: 22
    
      In [20]: a, b = [11, 22]
      In [21]: a
      Out[21]: 11
      In [22]: b
      Out[22]: 22
    
      In [23]: a, b = {"m":11, "n":22}  # 取出来的是key,而不是键值对
      In [24]: a
      Out[24]: 'm'
      In [25]: b
      Out[25]: 'n'
    
  1. 交换2个变量的值
# 第3种方式
a = 4
b = 5
a, b = b, a

print(a)
print(b)

4.12 函数的引用

在python中,值是靠引用来传递的

我们可以用(id)来判断两个变量是否为同一个值的引用。我们可以将id理解为那块内存的地址标示。

a = 1
b = a
print(id(a))   # 140719292941984
print(id(b))   # 140719292941984 注意两个变量的id值相同

a = 2
print(id(a))   # 140719292942016 注意a的id值已经变了

print(id(b))  # 140719292941984 b的id值依旧

引用(二)

引用当做实参

  • 可变类型与不可变类型的变量分别作为函数参数时,会有什么不同吗?
  • Python有没有类似C语言中的指针传参呢?
def test1(b):  # 变量b一定是一个局部变量,就看它指向的是谁?可变还是不可变
    b += b  # += 是直接对b指向的空间进行修改,而不是让b指向一个新的
    # b = b+b  # xx = xx+yyy 先把=号右边的结果计算出来,然后让b指向这个新的地方,不管原来b指向谁
                # 现在b一定指向这个新的地方

# a = [11, 22]
a = 100
test1(a)
print(a)

总结:

  • Python中函数参数是引用传递(注意不是值传递)
  • 对于不可变类型,因变量不能修改,所以运算不会影响到变量自身
  • 而对于可变类型来说,函数体中的运算有可能会更改传入的参数变量

4.13 可变,不可变类型

总结

  • 所谓可变类型与不可变类型是指:数据能够直接进行修改,如果能直接修改那么就是可变,否则是不可变
  • 可变类型有: 列表、字典、集合
  • 不可变类型有: 数字、字符串、元组

列表:

a = [11, 22]  # 可变类型
print(a[0])  # 获取列表的数据,没问题

a[0] = 100
print(a[0])  # 修改列表中的数据,没有问题

元组:

b = (11, 22)   # 不可变类型

print(b[0])    # 获取元组的数据,没有问题

b[0] = 100     #  修改元组的数据,程序产生异常

print(b[0])

------------------------------------------------
D:\pythonwork\Harry\venv\Scripts\python.exe C:/Users/admin/Desktop/guiderobot_python_win/pathfinder/apps/Intelligent_lighting/__init__.py
Traceback (most recent call last):
  File "C:/Users/admin/Desktop/guiderobot_python_win/pathfinder/apps/Intelligent_lighting/__init__.py", line 5, in <module>
    b[0] = 100     #
TypeError: 'tuple' object does not support item assignment
11

Process finished with exit code 1


4.14函数的注意事项

  1. return 注意事项

一个函数到底有没有返回值,就看有没有return关键字,因为只有return才可以返回数据

当执行完return语句,那么就意味着这个函数的调用完成,return语句后面的代码不会执行

  1. 函数名不能重复

    如果在同一个程序中出现了多个相同函数名的函数,那么后面的函数会覆盖前面的函数,在调用函数的时候就可以出现问题,所以要避免函数名称相同

  2. 作用域

    在一个函数中定义的变量,只能在本函数中有(局部变量)

    在函数外定义的变量,可以在所有的函数中使用(全局变量)

4.15 函数的应用:学生管理系统

# 学生的信息可以使用一个字典类型
# 管理学生可以使用列表

# 定义全局变量学生列表
student_list = [] # list()
# print("全局变量:", id(student_list))

# 显示功能菜单的函数
def show_menu():
    print("-----学生管理系统v1.0-----")
    print("1. 添加学生")
    print("2. 删除学生")
    print("3. 修改学生信息")
    print("4. 查询学生信息")
    print("5. 显示所有学生信息")
    print("6. 退出")


# 添加学生
def add_student():
    name = input("请输入学生的姓名:")
    age = input("请输入学生的年龄:")
    sex = input("请输入学生的性别:")

    # 定义学生字典类型的变量
    student_dict = {} # dict()
    # 把学生的信息使用字典进行存储
    student_dict["name"] = name
    student_dict["age"] = age
    student_dict["sex"] = sex
    # 这里可以不使用global因为列表是可变类型,可以在原有数据的基础上进行修改,内存地址不变
    # 因为列表的内存地址不变,全局变量不需要使用global
    # 加上global表示内存地址要发生变化

    # 把学生信息添加到学生列表中
    student_list.append(student_dict)
    # global student_list
    # # student_list = [{'name': "李四", "age":"18", "sex":"男"}]
    # student_list.append(student_dict)


# 显示所有学生信息
def show_all_student():
    # print(student_list, id(student_list))
    for index, student_dict in enumerate(student_list):
        # 学号和下标的关系
        student_no = index + 1

        print("学号:%d 姓名:%s 年龄:%s 性别:%s" % (student_no, student_dict["name"],
                                           student_dict["age"], student_dict["sex"]))


# 删除学生信息
def remove_student():
    student_no = int(input("请输入要删除学生的学号:"))
    # 获取学生字典信息的下标
    index = student_no - 1
    if index >= 0 and index < len(student_list):
        # 根据下标删除学生信息
        del student_list[index]
    else:
        print("请输入正确的学号")

# 修改学生信息
def modify_student():
    student_no = int(input("请输入要修改学生的学号:"))
    # 根据学号计算下标
    index = student_no - 1

    if index >= 0 and index < len(student_list):
        # 根据下标获取学生字典信息
        student_dict = student_list[index]

        name = input("请输入您修改后的名字:")
        age = input("请输入您修改后的年龄:")
        sex = input("请输入您修改后的性别:")

        student_dict["name"] = name
        student_dict["age"] = age
        student_dict["sex"] = sex
    else:
        print("请输入正确的学号")


# 查询学生
def search_student():
    name = input("请输入要查询的学生姓名:")

    # 遍历学生列表信息
    for index, student_dict in enumerate(student_list):
        # pass # 空实现
        if student_dict["name"] == name:
            student_no = index + 1
            # 说明找到了这个学生
            print("学号:%d 姓名:%s 年龄:%s 性别:%s" % (student_no, student_dict["name"],
                                               student_dict["age"], student_dict["sex"]))
            break
    else:
        print("对不起,没有找到这个学生")

# 程序启动的函数
def run():

    while True:
        # 显示功能菜单
        show_menu()
        # 接收用户的指令
        menu_option = input("请输入您需要的功能选项:")

        if menu_option == "1":
            print("添加学生")
            add_student()
        elif menu_option == "2":
            print("删除学生")
            remove_student()
        elif menu_option == "3":
            print("修改学生信息")
            modify_student()
        elif menu_option == "4":
            print("查询学生信息")
            search_student()
        elif menu_option == "5":
            print("显示所有学生信息")
            show_all_student()
        elif menu_option == "6":
            print("退出")
            break

# 执行程序启动的函数
run()

4.16 递归函数

递归函数

在函数内部,可以调用其他函数,如果一个函数在内部调用自己本身,这个函数就是递归函数。

递归函数的特性:

  1. 必须有一个明确的结束条件;
  2. 每次进入更深一层递归时,问题规模相比上次递归都应有减少
  3. 相邻两次重复之间有紧密的联系,前一次要为后一次做准备
  4. 递归的效率不高,递归层次过多会导致栈的溢出

例子:

计算机1到100 的和

# 循环方式
def sum_cycle(n):
    sum = 0
    for i in range(1, n + 1):
        sum += i
        print(sum)
sum_cycle(100)
# 递归方式
def sum_recu(n):

    if n > 0:
        return n + sum_recu(n - 1)
    else:
        return 0
sum = sum_recu(100)
print(sum)

4.17 匿名函数

  1. 函数可以做为参数传递给另外一个函数, 可以使得函数的实现更加通用.
  2. 匿名函数也可以作为参数传递给另外一个函数, 对于只需要用到一次函数, 可以通过匿名函数减少代码量.

4.18 推导式

python 语言有一种独特的推导式,相当于语法糖的存在

  1. 列表推导式
lis = [x * x for x in range(1, 10)]
print(lis)
-----------------------------------
[1, 4, 9, 16, 25, 36, 49, 64, 81]

Process finished with exit code 0
lis = []
for i in range(1, 10):
    lis.append(i*i)
print(lis)
------------------------------------
[1, 4, 9, 16, 25, 36, 49, 64, 81]

Process finished with exit code 0

增加条件语句

print([x * x for x in range(1, 11)])
print([x * x for x in range(1, 11)if x % 2 == 0])
--------------------------------------------------
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
[4, 16, 36, 64, 100]

Process finished with exit code 0

多重循环

print([a + b for a in '123' for b in 'abc'])
--------------------------------------------
['1a', '1b', '1c', '2a', '2b', '2c', '3a', '3b', '3c']

Process finished with exit code 0

同时循环a和b两个变量

更多应用

dic = {"k1": "v1", "k2": "v2"}
a = [k+":"+v for k, v in dic.items()]
print(a)
--------------------------------------
['k1:v1', 'k2:v2']

Process finished with exit code 0

  1. 字典推导式
dic = {x: x**2 for x in (2, 4, 6)}
print(dic)
print(type(dic))
----------------------------------
{2: 4, 4: 16, 6: 36}
<class 'dict'>
Process finished with exit code 0

3.集合推导式

a = {x for x in 'abracadabra' if x not in 'abc'}
print(a)
print(type(a))
------------------------------------------------
{'d', 'r'}
<class 'set'>

Process finished with exit code 0

没有元组推导式

tup = (x for x in range(9))
print(tup)
print(type(tup))
---------------------------
<generator object <genexpr> at 0x000001FAE48C8900>
<class 'generator'>
Process finished with exit code 0

4.19 set集合set,list,tuple之间的类型转换

set 是集合类型

a = set()
print(type(a))
b = [1, 2, 3, 12, 3, 1, 3]
print(b)
print(set(b))
---------------------------
<class 'set'>
[1, 2, 3, 12, 3, 1, 3]
{1, 2, 3, 12}
Process finished with exit code 0

set, list, tuple,之间可以相互转换

c = {1, 2}
d = list(c)
print(d)
print(type(c))
----------------
[1, 2]
<class 'set'>

Process finished with exit code 0
d = [1, 2, 3, 12]
e = tuple(d)
print(e)
--------------------
(1, 2, 3, 12)
Process finished with exit code 0
e = (1, 2, 3, 12)
f = list(e)
print(f)
-------------------
[1, 2, 3, 12]

Process finished with exit code 0

使用set,可以快速的完成对list中的元素去重复的功能

4.20高级函数

高阶函数: 函数的参数是一个函数类型

高阶函数:函数的返回值是一个函数类型

def calc_num(new_func):
    a = 1
    b = 2

    # 执行外界传入过来的函数
    result = new_func(a, b)

    return result


def sum_num(num1, num2):
    return num1 + num2


# 调用函数
result = calc_num(sum_num)
print(result)

----------------------------
3
Process finished with exit code 0
def show():

    # 在python里面可以函数里面在定义一个函数
    def print_info():
        print("哈哈, 我是一个子函数")

    # 函数的返回值是一个函数类型
    return print_info

new_func = show()

print(new_func, type(new_func))

# 调用返回的函数
new_func()
----------------------------------------
<function show.<locals>.print_info at 0x00000265C90AA160> <class 'function'>
哈哈, 我是一个子函数
Process finished with exit code 0
  1. reduce 用法

reduce()根据函数对容器类型中每一个数据进行计算.

第一个参数功能函数,函数需要带有两个参数

第二个参数是要操作的容器类型

计算列表中的累加和:

import functools

my_list = [1, 2, 3, 4, 5]


def f(x1, x2):
    return x1 + x2


result = functools.reduce(f, my_list)
print(result)

5.文件操作

5.1 文件操作介绍

<1>什么是文件

<2>文件的作用

大家应该听说过一句话:“好记性不如烂笔头”。

不仅人的大脑会遗忘事情,计算机也会如此,比如一个程序在运行过程中用了九牛二虎之力终于计算出了结果,试想一下如果不把这些数据存放起来,相比重启电脑之后,“哭都没地方哭了”

可见,在把数据存储起来有做么大的价值

使用文件的目的:

就是把一些存储存放起来,可以让程序下一次执行的时候直接使用,而不必重新制作一份,省时省力

5.2 文件的读写

<1>写数据(write)

使用write()可以完成向文件写入数据

demo: 新建一个文件 file_write_test.py,向其中写入如下代码:

f = open('test.txt', 'w')
f.write('hello world, i am here!')
f.close()

运行之后会在file_write_test.py文件所在的路径中创建一个文件test.txt,其中数据如下:

hello world, i am here!

注意:

  • 如果文件不存在那么创建,如果存在那么就先清空,然后写入数据

<2>读数据(read)

使用read(num)可以从文件中读取数据,num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中所有的数据

demo: 新建一个文件file_read_test.py,向其中写入如下代码:

f = open('test.txt', 'r')
content = f.read(5)  # 最多读取5个数据
print(content)

print("-"*30)  # 分割线,用来测试

content = f.read()  # 从上次读取的位置继续读取剩下的所有的数据
print(content)

f.close()  # 关闭文件,这个可以是个好习惯哦

运行现象:

hello
------------------------------
 world, i am here!

注意:

  • 如果用open打开文件时,如果使用的"r",那么可以省略,即只写 open('test.txt')

<3>读数据(readlines)

就像read没有参数时一样,readlines可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素

#coding=utf-8

f = open('test.txt', 'r')
content = f.readlines()
print(type(content))

i=1
for temp in content:
    print("%d:%s" % (i, temp))
    i += 1

f.close()

<4>读数据(readline)

#coding=utf-8

f = open('test.txt', 'r')

content = f.readline()
print("1:%s" % content)

content = f.readline()
print("2:%s" % content)


f.close()

5.3 应用1:制作文件的备份

任务描述

  • 输入文件的名字,然后程序自动完成对文件进行备份

参考代码

# 提示输入文件
oldFileName = input("请输入要拷贝的文件名字:")

# 以读的方式打开文件
oldFile = open(oldFileName,'rb')

# 提取文件的后缀
fileFlagNum = oldFileName.rfind('.')
if fileFlagNum > 0:
    fileFlag = oldFileName[fileFlagNum:]

# 组织新的文件名字
newFileName = oldFileName[:fileFlagNum] + '[复件]' + fileFlag

# 创建新文件
newFile = open(newFileName, 'wb')

# 把旧文件中的数据,一行一行的进行复制到新文件中
for lineContent in oldFile.readlines():
    newFile.write(lineContent)

# 关闭文件
oldFile.close()
newFile.close()

5.4 文件的相关操作

有些时候,需要对文件进行重命名、删除等一些操作,python的os模块中都有这么功能

1.文件重命名

os模块中的rename()可以完成对文件的重命名操作

rename(需要修改的文件名, 新的文件名)

import os
os.rename("毕业论文.txt", "毕业论文-最终版.txt")

2.删除文件

os模块中的remove()可以完成对文件的删除操作

remove(待删除的文件名)

import os
os.remove("毕业论文.txt")

3.创建文件夹

import os
os.mkdir("张三")

4.获取当前目录

import os
os.getcwd()
  1. 改变默认目录
import os
os.chdir("../")
  1. 获取目录列表
import os
os.listdir("./")
  1. 删除文件夹
import os
os.rmdir("张三")

5.5应用:批量修改文件名

<1>运行过程演示

  • 运行程序之前

<2>参考代码

#coding=utf-8
# 批量在文件名前加前缀
import os

funFlag = 1 # 1表示添加标志  2表示删除标志
folderName = './renameDir/'

# 获取指定路径的所有文件名字
dirList = os.listdir(folderName)

# 遍历输出所有文件名字
for name in dirList:
    print name

    if funFlag == 1:
        newName = '[东哥出品]-' + name
    elif funFlag == 2:
        num = len('[东哥出品]-')
        newName = name[num:]
    print newName

    os.rename(folderName+name, folderName+newName)

5.6综合应用

学生管理系统(文件版)

# 学生的信息可以使用一个字典类型
# 管理学生可以使用列表
import os

# 定义全局变量学生列表
student_list = [] # list()
print("全局变量:", id(student_list))

# 显示功能菜单的函数
def show_menu():
    print("-----学生管理系统v1.0-----")
    print("1. 添加学生")
    print("2. 删除学生")
    print("3. 修改学生信息")
    print("4. 查询学生信息")
    print("5. 显示所有学生信息")
    print("6. 退出")


# 添加学生
def add_student():
    name = input("请输入学生的姓名:")
    age = input("请输入学生的年龄:")
    sex = input("请输入学生的性别:")

    # 定义学生字典类型的变量
    student_dict = {} # dict()
    # 把学生的信息使用字典进行存储
    student_dict["name"] = name
    student_dict["age"] = age
    student_dict["sex"] = sex
    # 这里可以不使用global因为列表是可变类型,可以在原有数据的基础上进行修改,内存地址不变
    # 因为列表的内存地址不变,全局变量不需要使用global
    # 加上global表示内存地址要发生变化

    # 把学生信息添加到学生列表中
    student_list.append(student_dict)
    # global student_list
    # # student_list = [{'name': "李四", "age":"18", "sex":"男"}]
    # student_list.append(student_dict)


# 显示所有学生信息
def show_all_student():
    # print(student_list, id(student_list))
    for index, student_dict in enumerate(student_list):
        # 学号和下标的关系
        student_no = index + 1

        print("学号:%d 姓名:%s 年龄:%s 性别:%s" % (student_no, student_dict["name"],
                                           student_dict["age"], student_dict["sex"]))


# 删除学生信息
def remove_student():
    student_no = int(input("请输入要删除学生的学号:"))
    # 获取学生字典信息的下标
    index = student_no - 1
    if index >= 0 and index < len(student_list):
        # 根据下标删除学生信息
        del student_list[index]
    else:
        print("请输入正确的学号")

# 修改学生信息
def modify_student():
    student_no = int(input("请输入要修改学生的学号:"))
    # 根据学号计算下标
    index = student_no - 1

    if index >= 0 and index < len(student_list):
        # 根据下标获取学生字典信息
        student_dict = student_list[index]

        name = input("请输入您修改后的名字:")
        age = input("请输入您修改后的年龄:")
        sex = input("请输入您修改后的性别:")

        student_dict["name"] = name
        student_dict["age"] = age
        student_dict["sex"] = sex
    else:
        print("请输入正确的学号")


# 查询学生
def search_student():
    name = input("请输入要查询的学生姓名:")

    # 遍历学生列表信息
    for index, student_dict in enumerate(student_list):
        # pass # 空实现
        if student_dict["name"] == name:
            student_no = index + 1
            # 说明找到了这个学生
            print("学号:%d 姓名:%s 年龄:%s 性别:%s" % (student_no, student_dict["name"],
                                               student_dict["age"], student_dict["sex"]))
            break
    else:
        print("对不起,没有找到这个学生")


# 保存学生列表数据到文件中
def save_data():
    file = open("student_list.data", "w", encoding="utf-8")
    # 把列表转成字符串
    student_list_str = str(student_list)
    # 把列表数据写入到文件中
    file.write(student_list_str)
    file.close()


# 加载文件中的数据
def load_data():

    result = os.path.exists("Test")
    print(result)
    # 判断文件或者文件夹是否存在
    if os.path.exists("student_list.data"):
        file = open("student_list.data", "r", encoding="utf-8")

        # 读取文件中的数据
        file_content = file.read()
        new_student_list = eval(file_content)
        print(new_student_list, type(new_student_list))
        # global student_list
        # student_list = new_student_list

        student_list.extend(new_student_list)
        print("全局变量:", id(student_list))

        file.close()

# 程序启动的函数
def run():

    # 加载文件中的数据
    load_data()

    while True:
        # 显示功能菜单
        show_menu()
        # 接收用户的指令
        menu_option = input("请输入您需要的功能选项:")

        if menu_option == "1":
            print("添加学生")
            add_student()
        elif menu_option == "2":
            print("删除学生")
            remove_student()
        elif menu_option == "3":
            print("修改学生信息")
            modify_student()
        elif menu_option == "4":
            print("查询学生信息")
            search_student()
        elif menu_option == "5":
            print("显示所有学生信息")
            show_all_student()
        elif menu_option == "6":
            # 保存数据到文件
            save_data()
            print("退出")
            break

# 执行程序启动的函数
run()

6.面向对象

6.1面向对象编程介绍

面向对象

  1. 概述

如今主流的软件开发思想有两种:一个是面向过程,另一个是面向对象

面向过程出现得较早,典型代表为C语言,开发中小型项目的效率很高,但是很难适用于如今主流的大中型项目开发场景。面向对象则出现得更晚一些,典型代表为Java或C++等语言,更加适合用于大型开发场景。两种开发思想各有长短。

对于面向过程的思想: 需要实现一个功能的时候,看重的是开发的步骤和过程,每一个步骤都需要自己亲力亲为,需要自己编写代码(自己来做)

对于面向对象的思想:当需要实现一个功能的时候,看重的并不是过程和步骤,而是关心谁帮我做这件事(偷懒,找人帮我做)

面向对象的三大特征有:封装性、继承性、多态性

  1. 生活举例

  2. 洗衣服

    1.1. 面向过程(手洗):脱衣服、找一个盆、加水、加洗衣粉、浸泡30分钟、搓洗、拧衣服、倒掉水、再加水、漂洗、拧衣服、倒掉水、晾衣服。

    1.2. 面向对象(机洗):脱衣服、放入洗衣机、按下开关、拿出衣服晾晒。

  3. 买电脑

    2.1 面向过程(自己买):需要电脑、查询参数信息、横向比较机型、了解打折信息、与店家讨价还价、下单、收快递、开机验货、确认收货。

    2.2 面向对象(找人买):需要电脑、找秘书帮我买、收电脑。

6.2 类和对象

面向对象编程的2个非常重要的概念:类和对象

对象是面向对象编程的核心,在使用对象的过程中,为了将具有共同特征和行为的一组对象抽象定义,提出了另外一个新的概念——类

类就相当于制造飞机时的图纸,用它来进行创建的飞机就相当于对象

人以类聚 物以群分。
具有相似内部状态和运动规律的实体的集合(或统称为抽象)。 
具有相同属性和行为事物的统称

类是抽象的,在使用的时候通常会找到这个类的一个具体的存在,使用这个具体的存在。一个类可以找到多个对象

  1. 对象
某一个具体事物的存在 ,在现实世界中可以是看得见摸得着的。

可以是直接使用的
  1. 类和对象之间的关系

小总结:类就是创建对象的模板

  1. 练习:区分类和对象
奔驰汽车 类
奔驰smart 类 
张三的那辆奔驰smart 对象
狗 类
大黄狗 类 
李四家那只大黄狗 对象 
水果 类
苹果 类 
红苹果 类 红富士苹果 类 
我嘴里吃了一半的苹果 对象
  1. 类的构成

类(Class) 由3个部分构成

  • 类的名称:类名
  • 类的属性:一组数据
  • 类的方法:允许对进行操作的方法 (行为)

5.1. 举例:

1)人类设计,只关心3样东西:

  • 事物名称(类名):人(Person)
  • 属性:身高(height)、年龄(age)
  • 方法(行为/功能):跑(run)、打架(fight)

2)狗类的设计

  • 类名:狗(Dog)
  • 属性:品种 、毛色、性别、名字、 腿儿的数量
  • 方法(行为/功能):叫 、跑、咬人、吃、摇尾巴
  1. 类的抽象

如何把日常生活中的事物抽象成程序中的类?

拥有相同(或者类似)属性和行为的对象都可以抽像出一个类

方法:一般名词都是类(名词提炼法)

6.1. 坦克发射3颗炮弹轰掉了2架飞机

  • 坦克--》可以抽象成 类
  • 炮弹--》可以抽象成类
  • 飞机-》可以抽象成类

6.2. 小明在公车上牵着一条叼着热狗的狗

  • 小明--》 人类

  • 公车--》 交通工具类

  • 热狗--》 食物类

6.3定义类

定义一个类,格式如下:

class 类名:
    方法列表

demo:定义一个Hero类

# class Hero:  # 经典类(旧式类)定义形式
# class Hero():

class Hero(object):  # 新式类定义形式
    def info(self):
        print("英雄各有见,何必问出处。")

说明:

  • 定义类时有2种形式:新式类和经典类,上面代码中的Hero为新式类,前两行注释部分则为经典类;

  • object 是Python 里所有类的最顶级父类;

  • 类名 的命名规则按照"大驼峰命名法";

  • info 是一个实例方法,第一个参数一般是self,表示实例对象本身,当然了可以将self换为其它的名字,其作用是一个变量 这个变量指向了实例对象

6.4 创建对象

python中,可以根据已经定义的类去创建出一个或多个对象。

创建对象的格式为:

对象名1 = 类名()
对象名2 = 类名()
对象名3 = 类名()

创建对象demo:

class Hero(object):  # 新式类定义形式
    """info 是一个实例方法,类对象可以调用实例方法,实例方法的第一个参数一定是self"""
    def info(self):
        """当对象调用实例方法时,Python会自动将对象本身的引用做为参数,
            传递到实例方法的第一个参数self里"""
        print(self) 
        print("self各不同,对象是出处。")


# Hero这个类 实例化了一个对象  taidamier(泰达米尔)
taidamier = Hero()

# 对象调用实例方法info(),执行info()里的代码
# . 表示选择属性或者方法
taidamier.info()

print(taidamier)  # 打印对象,则默认打印对象在内存的地址,结果等同于info里的print(self)
print(id(taidamier))  # id(taidamier) 则是内存地址的十进制形式表示

6.5添加和获取对象的属性

class Hero(object):
    """定义了一个英雄类,可以移动和攻击"""
    def move(self):
        """实例方法"""
        print("正在前往事发地点...")

    def attack(self):
        """实例方法"""
        print("发出了一招强力的普通攻击...")

# 实例化了一个英雄对象 泰达米尔
taidamier = Hero()

# 给对象添加属性,以及对应的属性值
taidamier.name = "泰达米尔"  # 姓名
taidamier.hp = 2600  # 生命值
taidamier.atk = 450  # 攻击力
taidamier.armor = 200  # 护甲值

# 通过.成员选择运算符,获取对象的属性值
print("英雄 %s 的生命值 :%d" % (taidamier.name, taidamier.hp))
print("英雄 %s 的攻击力 :%d" % (taidamier.name, taidamier.atk))
print("英雄 %s 的护甲值 :%d" % (taidamier.name, taidamier.armor))

# 通过.成员选择运算符,获取对象的实例方法
taidamier.move()
taidamier.attack()

6.6在方法内通过self获取对象属性

class Hero(object):
    """定义了一个英雄类,可以移动和攻击"""
    def move(self):
        """实例方法"""
        print("正在前往事发地点...")

    def attack(self):
        """实例方法"""
        print("发出了一招强力的普通攻击...")

    def info(self):
        """在类的实例方法中,通过self获取该对象的属性"""
        print("英雄 %s 的生命值 :%d" % (self.name, self.hp))
        print("英雄 %s 的攻击力 :%d" % (self.name, self.atk))
        print("英雄 %s 的护甲值 :%d" % (self.name, self.armor))


# 实例化了一个英雄对象 泰达米尔
taidamier = Hero()

# 给对象添加属性,以及对应的属性值
taidamier.name = "泰达米尔"  # 姓名
taidamier.hp = 2600  # 生命值
taidamier.atk = 450  # 攻击力
taidamier.armor = 200  # 护甲值

# 通过.成员选择运算符,获取对象的实例方法
taidamier.info()  # 只需要调用实例方法info(),即可获取英雄的属性
taidamier.move()
taidamier.attack()

7. 异常,模块

7.1 异常

异常:

当python检查到一个错误时,解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的“异常”

7.2 捕获异常

案例剖析

  1. 捕获异常 try...except...

看如下示例:

try:
    print('-----test--1---')
    open('123.txt','r')
    print('-----test--2---')
except IOError:
    pass

运行结果:

-----test--1---

Process finished with exit code 0

说明:

  • 此程序看不到任何错误,因为用except 捕获到了IOError异常,并添加了处理的方法
  • pass 表示实现了相应的实现,但什么也不做;如果把pass改为print语句,那么就会输出其他信息

小总结:

try:
    print('-----test--1---')
    open('123.txt','r')
    print('-----test--2---') 
    #  解释 可能产生异常的代码;放在try中
    
    
except IOError:
    pass   # 解释 如果产生错误时处理的方法
  • 把可能出现问题的代码,放在try中
  • 把处理异常的代码,放在except中
  1. except捕获多个异常

看如下示例:

try:
    print num
except IOError:
    print('产生错误了')

运行结果如下:

Traceback (most recent call last):
  File "D:/work/test.py", line 2, in <module>
    print(num)
NameError: name 'num' is not defined

    
Process finished with exit code 1

想一想:

上例程序,已经使用except来捕获异常了,为什么还会看到错误的信息提示?

答:

except捕获的错误类型是IOError,而此时程序产生的异常为 NameError ,所以except没有生效

修改后的代码为:

try:
    print num
except NameError:
    print('产生错误了')

运行结果如下:

  File "D:/work/test.py", line 2
    print num
          ^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(num)?

Process finished with exit code 1

实际开发中,捕获多个异常的方式,如下:

#coding=utf-8
try:
    print('-----test--1---')
    open('123.txt','r') # 如果123.txt文件不存在,那么会产生 IOError 异常
    print('-----test--2---')
    print(num)# 如果num变量没有定义,那么会产生 NameError 异常

except (IOError,NameError): 
    #如果想通过一次except捕获到多个异常可以用一个元组的方式

注意:

  • 当捕获多个异常时,可以把要捕获的异常的名字,放到except 后,并使用元组的方式仅进行存储
  1. 获取异常的信息描述

  2. 捕获所有异常

  3. else

咱们应该对else并不陌生,在if中,它的作用是当条件不满足时执行的实行;同样在try...except...中也是如此,即如果没有捕获到异常,那么就执行else中的事情

try:
    num = 100
    print("num")
except NameError as errorMsg:
    print('产生错误了:%s'%errorMsg)
else:
    print('没有捕获到异常,真高兴')

运行结果如下:

num
没有捕获到异常,真高兴
Process finished with exit code 0
  1. try...finally...

try...finally...语句用来表达这样的情况:

在程序中,如果一个段代码必须要执行,即无论异常是否产生都要执行,那么此时就需要使用finally。 比如文件关闭,释放锁,把数据库连接返还给连接池等

demo:

import time
try:
    f = open('test.txt')
    try:
        while True:
            content = f.readline()
            if len(content) == 0:
                break
            time.sleep(2)
            print(content)
    except:
        #如果在读取文件的过程中,产生了异常,那么就会捕获到
        #比如 按下了 ctrl+c
        pass
    finally:
        f.close()
        print('关闭文件')
except:
    print("没有这个文件")

说明:

test.txt文件中每一行数据打印,但是我有意在每打印一行之前用time.sleep方法暂停2秒钟。这样做的原因是让程序运行得慢一些。在程序运行的时候,按Ctrl+c中断(取消)程序。

我们可以观察到KeyboardInterrupt异常被触发,程序退出。但是在程序退出之前,finally从句仍然被执行,把文件关闭。

7.3 异常的传递

  1. try嵌套中
import time
try:
    f = open('test.txt')
    try:
        while True:
            content = f.readline()
            if len(content) == 0:
                break
            time.sleep(2)
            print(content)
    finally:
        f.close()
        print('关闭文件')
except:
    print("没有这个文件")

运行结果:

In [26]: import time
    ...: try:
    ...:     f = open('test.txt')
    ...:     try:
    ...:         while True:
    ...:             content = f.readline()
    ...:             if len(content) == 0:
    ...:                 break
    ...:             time.sleep(2)
    ...:             print(content)
    ...:     finally:
    ...:         f.close()
    ...:         print('关闭文件')
    ...: except:
    ...:     print("没有这个文件")
    ...: finally:
    ...:     print("最后的finally")
    ...:     
xxxxxxx--->这是test.txt文件中读取到信息
^C关闭文件
没有这个文件
最后的finally
  1. 函数嵌套调用中
    def test1():
        print("----test1-1----")
        print(num)
        print("----test1-2----")


    def test2():
        print("----test2-1----")
        test1()
        print("----test2-2----")


    def test3():
        try:
            print("----test3-1----")
            test1()
            print("----test3-2----")
        except Exception as result:
            print("捕获到了异常,信息是:%s"%result)

        print("----test3-2----")



    test3()
    print("------华丽的分割线-----")
    test2()

总结:

  • 如果try嵌套,那么如果里面的try没有捕获到这个异常,那么外面的try会接收到这个异常,然后进行处理,如果外边的try依然没有捕获到,那么再进行传递。。。
  • 如果一个异常是在一个函数中产生的,例如函数A---->函数B---->函数C,而异常是在函数C中产生的,那么如果函数C中没有对这个异常进行处理,那么这个异常会传递到函数B中,如果函数B有异常处理那么就会按照函数B的处理方式进行执行;如果函数B也没有异常处理,那么这个异常会继续传递,以此类推。。。如果所有的函数都没有处理,那么此时就会进行异常的默认处理,即通常见到的那样
  • 注意观察上图中,当调用test3函数时,在test1函数内部产生了异常,此异常被传递到test3函数中完成了异常处理,而当异常处理完后,并没有返回到函数test1中进行执行,而是在函数test3中继续执行

7.4 抛出自定义的异常

抛出自定义的异常

用raise语句来引发一个异常。异常/错误对象必须有一个名字,且它们应是Error或Exception类的子类

下面是一个引发异常的例子:

class ShortInputException(Exception):
    """ 自定义的异常类 """
    def __init__(self, length, least):
        #  super().__init__()
        self.length = length
        self.least = least


def main():
    try:
        s = input('请输入 --> ')
        if len(s) < 3:  # raise引发一个你定义的异常
            raise ShortInputException(len(s), 3)
    except ShortInputException as result:    # x这个变量被绑定到了错误的实例
        print('ShortInputException: 输入的长度是 %d,长度至少应是 %d'% (result.length, result.least))
    else:
        print('没有异常发生.')
        
         
main()

注意

  • 以上程序中,关于代码

    #	super().__init__()
    

    的说明

    这一行代码,可以调用也可以不调用,建议调用,因为__init__方法往往是用来对创建完的对象进行初始化工作,如果在子类中重写了父类的__init__方法,即意味着父类中的很多初始化工作没有做,这样就不保证程序的稳定了,所以在以后的开发中,如果重写了父类的__init__方法,最好是先调用父类的这个方法,然后再添加自己的功能

7.5 模块介绍

模块

  1. Python中的模块

有过C语言编程经验的朋友都知道在C语言中如果要引用sqrt函数,必须用语句#include <math.h>引入math.h这个头文件,否则是无法正常进行调用的。

那么在Python中,如果要引用一些其他的函数,该怎么处理呢?

在Python中有一个概念叫做模块(module),这个和C语言中的头文件以及Java中的包很类似,比如在Python中要调用sqrt函数,必须用import关键字引入math这个模块,下面就来了解一下Python中的模块。

说的通俗点:模块就好比是工具包,要想使用这个工具包中的工具(就好比函数),就需要导入这个模块

  1. import

在Python中用关键字import来引入某个模块,比如要引用模块math,就可以在文件最开始的地方用import math来引入。

形如:

    import module1,mudule2...

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

在调用math模块中的函数时,必须这样引用:

  模块名.函数名
  • 想一想:

    为什么必须加上模块名调用呢?

  • 答:

    因为可能存在这样一种情况:在多个模块中含有相同名称的函数,此时如果只是通过函数名来调用,解释器无法知道到底要调用哪个函数。所以如果像上述这样引入模块的时候,调用函数必须加上模块名

    import math

    #这样会报错
    print sqrt(2)

    #这样才能正确输出结果
    print math.sqrt(2)

有时候我们只需要用到模块中的某个函数,只需要引入该函数即可,此时可以用下面方法实现:

    from 模块名 import 函数名1,函数名2....

不仅可以引入函数,还可以引入一些全局变量、类等

  • 注意:

    • 通过这种方式引入的时候,调用函数时只能给出函数名,不能给出模块名,但是当两个模块中含有相同名称函数的时候,后面一次引入会覆盖前一次引入。也就是说假如模块A中有函数function( ),在模块B中也有函数function( ),如果引入A中的function在先、B中的function在后,那么当调用function函数的时候,是去执行模块B中的function函数。
    • 如果想一次性引入math中所有的东西,还可以通过from math import *来实现
  1. from…import

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

语法如下:

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

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

    from fib import fibonacci

注意

  • 不会把整个fib模块导入到当前的命名空间中,它只会将fib里的fibonacci单个引入
  1. from … import *

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

    from modname import *

注意

  • 这提供了一个简单的方法来导入一个模块中的所有项目。然而这种声明不该被过多地使用。
  1. as
    In [1]: import time as tt

    In [2]: time.sleep(1)
    ---------------------------------------------------------------------------
    NameError                                 Traceback (most recent call last)
    <ipython-input-2-07a34f5b1e42> in <module>()
    ----> 1 time.sleep(1)

    NameError: name 'time' is not defined

    In [3]: 

    In [3]: 

    In [3]: tt.sleep(1)

    In [4]: 

    In [4]: 

    In [4]: from time import sleep as sp

    In [5]: sleep(1)
    ---------------------------------------------------------------------------
    NameError                                 Traceback (most recent call last)
    <ipython-input-5-82e5c2913b44> in <module>()
    ----> 1 sleep(1)

    NameError: name 'sleep' is not defined

    In [6]: 

    In [6]: 

    In [6]: sp(1)

    In [7]:
  1. 定位模块

当你导入一个模块,Python解析器对模块位置的搜索顺序是:

  1. 当前目录
  2. 如果不在当前目录,Python则搜索在shell变量PYTHONPATH下的每个目录。
  3. 如果都找不到,Python会察看默认路径。UNIX下,默认路径一般为/usr/local/lib/python/
  4. 模块搜索路径存储在system模块的sys.path变量中。变量里包含当前目录,PYTHONPATH和由安装过程决定的默认目录。

7.6模块制作

  1. 定义自己的模块

在Python中,每个Python文件都可以作为一个模块,模块的名字就是文件的名字。

比如有这样一个文件test.py,在test.py中定义了函数add

test.py

    def add(a,b):
        return a+b
  1. 调用自己定义的模块

那么在其他文件中就可以先import test,然后通过test.add(a,b)来调用了,当然也可以通过from test import add来引入

main.py

    import test

    result = test.add(11,22)
    print(result)
  1. 测试模块

在实际开中,当一个开发人员编写完一个模块后,为了让模块能够在项目中达到想要的效果,这个开发人员会自行在py文件中添加一些测试信息,例如:

test.py
    def add(a,b):
        return a+b

    # 用来进行测试
    ret = add(12,22)
    print('int test.py file,,,,12+22=%d'%ret)

如果此时,在其他py文件中引入了此文件的话,想想看,测试的那段代码是否也会执行呢!

main.py
    import test

    result = test.add(11,22)
    print(result)

运行现象:

至此,可发现test.py中的测试代码,应该是单独执行test.py文件时才应该执行的,不应该是其他的文件中引用而执行

为了解决这个问题,python在执行一个文件时有个变量__name__

直接运行此文件

在其他文件中import此文件

总结:

  • 可以根据__name__变量的结果能够判断出,是直接执行的python脚本还是被引入执行的,从而能够有选择性的执行测试代码

7.7模块中的__all__

  1. 没有__all__

  2. 模块中有__all__

总结

  • 如果一个文件中有__all__变量,那么也就意味着这个变量中的元素,不会被from xxx import *时导入

7.8 python中的包

  1. 引入包

1.1 有2个模块功能有联系

1.2 所以将其放到同一个文件夹下

1.3 使用import 文件.模块 的方式导入

1.4 使用from 文件夹 import 模块 的方式导入

1.5 在msg文件夹下创建__init__.py文件

1.6 在__init__.py文件中写入

1.7 重新使用from 文件夹 import 模块 的方式导入

总结:

  • 包将有联系的模块组织在一起,即放到同一个文件夹下,并且在这个文件夹创建一个名字为__init__.py 文件,那么这个文件夹就称之为
  • 有效避免模块名称冲突问题,让应用组织结构更加清晰
  1. __init__.py文件有什么用

__init__.py 控制着包的导入行为

2.1 __init__.py为空

仅仅是把这个包导入,不会导入包中的模块

2.2 __all__

__init__.py文件中,定义一个__all__变量,它控制着 from 包名 import *时导入的模块

2.3 可以在__init__.py文件中编写内容

可以在这个文件中编写语句,当导入时,这些语句就会被执行

__init__.py文件

2.4 可以控制导入其他模块

目录结构

sendmsg.py 和 recvmsg.py文件中的内容

python2导入失败

python3导入成功,但是不能使用模块

在文件夹下创建一个文件

python2导入成功,但不能使用

python3导入成功,但不能使用

解决python2不能使用的方式

python2的解放方式对python3不生效

解决python3不能使用的方式

7.9面向对象方式的学生管理系统

整个系统中有3个程序文件:

  1. student.py

这个文件中定义了学生类.

# 学生类
class Student(object):
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

2.student_manager_system.py

这个文件中定义了StudentManagerSystem

from student import Student
import os


# 定义学生管理系统类, 顶级函数和顶级类都要有两个换行
class StudentManagerSystem(object):

    def __init__(self):
        # 用于存储学生信息
        self.student_list = []

    # 显示功能菜单
    @staticmethod
    def show_menu():
        print("-----学生管理系统V1.0-------")
        print("1. 添加学生")
        print("2. 删除学生")
        print("3. 修改学生")
        print("4. 查询学生")
        print("5. 查询所有学生")
        print("6. 退出")

    # 添加学生
    def append_student(self):
        print("添加学生")
        # 接收学生信息
        name = input("请输入学生的姓名:")
        age = input("请输入学生的年龄:")
        sex = input("请输入学生的性别:")

        # # 创建空的字典
        # student_dict = {}
        # # 给字典添加键值对
        # student_dict["name"] = name
        # student_dict["age"] = age
        # student_dict["sex"] = sex

        # 创建学生对象
        student = Student(name, age, sex)

        # 把学生字典添加到学生列表里面
        self.student_list.append(student)

    # 显示所有的学生信息
    def show_all(self):
        print("查询所有学生")
        for index, student in enumerate(self.student_list):
            print("学号: %d 姓名: %s 年龄: %s 性别: %s" % (index + 1,
                                                   student.name,
                                                   student.age,
                                                   student.sex))

    # 删除学生
    def remove_student(self):
        print("删除学生")
        # 接收用户输入的学号
        student_no = int(input("请输入要删除学生的学号:"))
        # 把学号转成下标
        index = student_no - 1

        # 判断下标是否合法
        if index >= 0 and index < len(self.student_list):
            # 根据下标删除对应的学生
            del self.student_list[index]
        else:
            print("您要删除的学生不存在!")

    # 修改学生信息
    def modify_student(self):
        print("修改学生")
        # 获取要修改学生的学号
        student_no = int(input("请输入要修改学生的学号:"))
        # 把学号转成下标
        index = student_no - 1
        # 判断下标是否合法
        if index >= 0 and index < len(self.student_list):
            # 根据下标获取要修改学生的字典信息
            student = self.student_list[index]
            # 接收用户输入修改后的信息
            new_name = input("请输入修改后姓名:")
            new_age = input("请输入修改后的年龄:")
            new_sex = input("请输入修改后的性别:")
            # # 修改字典里面的信息
            # student_dict["name"] = new_name
            # student_dict["age"] = new_age
            # student_dict["sex"] = new_sex

            # 修改对象属性
            student.name = new_name
            student.age = new_age
            student.sex = new_sex

        else:
            print("您要修改的学生不存在!")

    # 查询学生
    def query_student(self):
        print("查询学生")
        # 接收用户输入的姓名
        name = input("请输入您要查询的学生姓名:")

        # 遍历学生列表,判断姓名是否相同
        for index, student in enumerate(self.student_list):
            if student.name == name:
                print("找到了,信息如下:")
                print("学号: %d 姓名: %s 年龄: %s 性别: %s" % (index + 1,
                                                       student.name,
                                                       student.age,
                                                       student.sex))
                break
        else:
            print("对不起,没有找到该学生")

    # 保存数据
    def save_data(self):
        # 打开文件
        file = open("students.data", "w", encoding="utf-8")

        # [{"name": "张三"}, person2]
        # 把列表对象转成列表字典存储到文件里面,因为字典是数据,可以根据字典创建后续使用的学生对象
        # 1. 列表推导式  2. map
        new_list = [student.__dict__ for student in self.student_list]
        # 列表转成字符串
        student_list_str = str(new_list)

        print("写入文件的数据:", student_list_str)
        # 写入数据,把学生列表写入文件
        file.write(student_list_str)
        # 关闭文件
        file.close()

    # 加载文件中的数据
    def load_data(self):

        print("读取文件中的数据")
        # 判断数据文件是否存在
        if os.path.exists("students.data"):

            # 打开文件
            file = open("students.data", "r", encoding="utf-8")
            # 读取数据, 这里的数据是字符串
            file_data = file.read()

            # "[{'name': '张三', 'age': '20', 'sex': '男'}]"

            new_student_list = eval(file_data)

            # 把列表字典转成列表学生对象
            new_list = [Student(student_dict["name"],
                                 student_dict["age"],
                                 student_dict["sex"])
                                 for student_dict in new_student_list]

            print("读取文件的数据:", new_list)

            # 1. 把数据直接赋值给student_list 这个全局变量
            # global student_list
            # student_list = new_student_list
            # print("load_data:", student_list)

            # 2. 把文件读取到的数据添加到学生列表里面来
            self.student_list.extend(new_list)
            # 关闭文件
            file.close()
        else:
            print("还没有本地文件数据")

    # 程序的入口函数,程序启动后执行的函数
    def run(self):

        # 加载文件中的数据,只加载一次
        self.load_data()

        while True:

            # 显示功能菜单
            self.show_menu()
            # 接收用户输入的功能选项
            menu_option = int(input("请输入功能选项:"))
            if menu_option == 1:
                # 添加学生
                self.append_student()
            elif menu_option == 2:
                # 删除学生
                self.remove_student()
            elif menu_option == 3:
                # 修改学生
                self.modify_student()
            elif menu_option == 4:
                # 查询学生
                self.query_student()
            elif menu_option == 5:
                self.show_all()
            elif menu_option == 6:
                # 在程序退出之前,保存学生列表中的数据到文件
                self.save_data()
                print("程序退出了")
                break
  1. main.py

这个文件是系统启动的入口文件,运行这个文件系统才能启动.

from student_manager_system import StudentManagerSystem

if __name__ == '__main__':
    # 创建学生管理系统对象
    system = StudentManagerSystem()
    # 让系统运行起来
    system.run()

7.10 PEP8编码规范

PEP8 提供了 Python 代码的编写约定. 本节知识点旨在提高代码的可读性, 并使其在各种 Python 代码中编写风格保持一致.

  1. 缩进使用4个空格, 空格是首选的缩进方式. Python3 不允许混合使用制表符和空格来缩进.

  2. 每一行最大长度限制在79个字符以内.

  3. 顶层函数、类的定义, 前后使用两个空行隔开.

  4. import 导入

    1. 导入建议在不同的行, 例如:

      import os
      import sys
      # 不建议如下导包
      import os, sys
      # 但是可以如下:
      from subprocess import Popen, PIPE
      
    2. 导包位于文件顶部, 在模块注释、文档字符串之后, 全局变量、常量之前. 导入按照以下顺序分组:

      1. 标准库导入
      2. 相关第三方导入
      3. 本地应用/库导入
      4. 在每一组导入之间加入空行
  5. Python 中定义字符串使用双引号、单引号是相同的, 尽量保持使用同一方式定义字符串. 当一个字符串包含单引号或者双引号时, 在最外层使用不同的符号来避免使用反斜杠转义, 从而提高可读性.

  6. 表达式和语句中的空格:

    1. 避免在小括号、方括号、花括号后跟空格.
    2. 避免在逗号、分好、冒号之前添加空格.
    3. 冒号在切片中就像二元运算符, 两边要有相同数量的空格. 如果某个切片参数省略, 空格也省略.
    4. 避免为了和另外一个赋值语句对齐, 在赋值运算符附加多个空格.
    5. 避免在表达式尾部添加空格, 因为尾部空格通常看不见, 会产生混乱.
    6. 总是在二元运算符两边加一个空格, 赋值(=),增量赋值(+=,-=),比较(==,<,>,!=,<>,<=,>=,in,not,in,is,is not),布尔(and, or, not
  7. 避免将小的代码块和 if/for/while 放在同一行, 要避免代码行太长.

    if foo == 'blah': do_blah_thing()
    for x in lst: total += x
    while t < 10: t = delay()
    
  8. 永远不要使用字母 'l'(小写的L), 'O'(大写的O), 或者 'I'(大写的I) 作为单字符变量名. 在有些字体里, 这些字符无法和数字0和1区分, 如果想用 'l', 用 'L' 代替.

  9. 类名一般使用首字母大写的约定.

  10. 函数名应该小写, 如果想提高可读性可以用下划线分隔.

  11. 如果函数的参数名和已有的关键词冲突, 在最后加单一下划线比缩写或随意拼写更好. 因此 class_ 比 clss 更好.(也许最好用同义词来避免这种冲突).

  12. 方法名和实例变量使用下划线分割的小写单词, 以提高可读性.

更多规范点击查看官网

更新中...

posted @ 2021-06-03 11:54  xiongsheng  阅读(161)  评论(0编辑  收藏  举报