Python(2023-4-6)

第一章:计算机基础知识

1.介绍

# 计算机是什么:在现实生活中我们无法离开计算机    电脑 笔记本  手机 游戏机 汽车导航...计算机就是一个用来计算的机器
# 目前来讲  计算机只能根据人类的指令来完成各种操作  人让他干嘛它就得干嘛
# 计算机由软件和硬件组成
# 硬件包含  键盘  鼠标 显示器  cpu  主板  内存 硬盘  硬件是看得见 摸得到的
#  软件:看得见  摸不着 负责计算机的运行  软件负责控制计算机的硬件  软件包含:系统软件和应用软件



# 计算机的使用方式:使用计算机必须通过软件对计算机完成各种操作  但是注意 软件开发并不是所有的功能都会对用户开饭  用户需要调用软件的接口来操作计算机


# 接口也叫交互界面


# 用户界面分为 两种:TUI (文本交互界面)和GUI(图形化交互界面)

2.命令行简介

命令行就是文本交互界面
	通过命令行可以使用一个一个的指令指令来操作计算机  任何计算机的系统中都有
	命令行有多个不同的名字:
			命令行  命令行窗口  DOS窗口  命令提示符  CMD窗口  SHell  终端
			
			
	1.然后进入到命令行:
    		win+r  cmd进入终端
    		
    		
    2.命令行结构:
    C:  当前所在的磁盘目录
    		可以通过 X:来切换盘符  x表示盘符
    		
    		
    常用的DOS命令:
    		dir  查看当前目的文件夹
    		cd 目录名  进入文件夹
    				--cd  .  表示当前目录
    				--cd ..  表示上一级目录
    				--md  名称  创建一个文件夹
    				--rd 文件夹名称  删除文件夹
    				--del  文件名   删除文件
    				--cls  清楚屏幕
    				
    				
    				
    				命令的语法:
    						命令 [参数][选项]	
    						
    环境变量:可以通过修改环境变量  来对计算机进行修改(主要是配置一些路径)
    1、查看环境变量
    		右键此电脑  -- 属性  ---高级系统设置 --环境变量--点击path 新建
    			环境变量界面分为两个部分
    			上面是用户环境变量
    			下面是系统变量
    			建议只是修改用户变量
    2、添加环境变量
    		一个环境变量有多个值  值与值之间使用;(英文)隔开
    
    3、删除环境变量
    		删除键
    		
    		
   path环境变量:
   			path中保存的是一个一个的路径  当我们在命令行中输入一个目录(或访问一个文件时)
   				系统会首先在当前目录下寻找  如果找到了就直接执行或者打开
   				如果没有找到  则会依次去环境变量的路径中去寻找  直到找到  没有的话 就报错
   				依次我们可以将一些经常需要使用的文件放在这里  就可以使用
   				
   				注意事项:1.如果环境变量中没有path  可以收到添加
   						2.path环境变量不区分大小写
   						
   						十进制:
   						--十进制就满十进一的进制
   						--十进制当中一共有10个数字
   								0 1 2 3 4 5 6 7 8 9
   						十进制间如何计数:
   		0 1 2 3 4 5 6 7 8 9 10 ..11..20
   		
   		二进制:
   		满二进一
   		二进制一共两个数字  0 1
   		二进制计数:
   		  1  10 11 100 101 110 111 10000
   		  所有的数据在计算机底层都是以二进制的形式保存  
   		  内存中的每一个小个子称为一共小格子  bit
   		  		byte是我们最小的可操作单位
   		  		8bit=1byte(字节)
   		  
   		  
   		八进制:
   			满八进一
   			八进制中一共有八个数字  0 1 2 3 4 5 6 7 8
   			八进制计数:
   			0 1 2 3 4 5 6 7 11..12..13..14..15..16..17..21..27..30...
   			
   	十六进制:
   			满十六进一
   			十六进制 一共是16个数字
   				由于十六进制是满16才进位的  所以十六进制中引入了
   				a b c d e f 来表示10 11 12 13 14 15
   		所以:十六进制的数是
   		1 2 3 4 5 6 7 8 9 a  b c d e f
   		
   	十六进制计数:
   	0 1 2 3 4 5 6 7 8 9  a(10) b(11) c(12) d(13) e(14) f(15) 
    		到了16就是满16进位  因此16等于10  
    		17 =16+1=10+1=11
    		18=17+1=11+1=12
    		19=18+1=12+1=13
    		20=19+1=13+1=14
    		21=20+1=14+1=15
    		22=21+1=15+1=16
    		23=22+1=16+1=17
    		24=23+1=17+1=18
    		25=24+1=18+1=19
    		26=25+1=19+1=1a
    		27=26+1=1b
    		28=27+1=1c
    		29=28+1=1d
    		30=29+1=1e
    		31=1f (到这里已经满16位了     因此就像9到10 一样  由9满10进位为10  1f就相当于九)
    		32=20
    		33=22
    
    
    文本文件和字符集
    		文本分为两种  一种脚纯文本  还有一种叫做  富文本
    		纯文本只能保存单一的文本内容  无法保存内容无关的东西(字体 图片)
    		富文本:可以保存文本以外的内容 (word文档)
    		
    		
    		
    		
    		在开发时  编写程序使用的都是纯文本
    		
    		纯文本在计算机底层会转换为二进制保存
    		将字符转换为二进制码的过程称为编码
    		将二进制码转换为字符的过程称为解码
    		
    		编码和解码所采用的规则我们称为字符集  
    		常见的字符集:
    				ASCII
    					美国人编码  使用7位来对美国常用的字符进行编码
    					-包含128个字符
    				GBK
    						使用8位  包含256个字符
    						国标码  中国的编码
    				Unicode
    					万国码 包含世界上的所有语言和符号 
    				UTF-8
    				
    				
    				
    				
    				最常用的就是utf-8
    				
    				
    	乱码:我们在编写程序的时  出现乱码的时候  就立刻去检查字符集是否正确
    				
    		
    

第二章:Python入门

1.Python介绍

汇编语言:使用符号来代替机器码  编写程序的时 不需要使用二进制 而是直接编写符号 然后再由计算机执行 符号转换为机器的过程称为汇编
		将机器码转换为符号的过程 称为反汇编
		汇编语言一般只适用于某些硬件   兼容性比较差
高级语言:高级语言的语法基本和现代的英语语法一致   并且和硬件的关系没有那么复杂了
		并且高级语言学习起来更加的容易
		
		
		
		Python开发环境搭建:
		
				Python解释器分类:
						CPython  使用C语言编写
						PyPy 使用python编写的
						IronPython  用.net编写的解释器
						JPython  用java开发的
						
		步骤:1.下载安装包
			2.安装Python
			3.配置环境变量
		

2.几个基本概念

# 表达式:就是类似于数学公式的东西  比如  2-2 3+6  表达式一般是用于计算一些结果  如果在交互模式输入一个表达式
# 会自动输出  在py文件里面是不会输出  要输出 要使用语句
#   print("")

print("你好")

# 语句:在程序语句中一般需要完成某种功能 比如打印信息  获取信息  为变量赋值等  这些就是语句
a=100
print(a)
# 语句的执行会对程序产生影响  在交互模式中不一定会输出语句的执行结果.

# 程序(program)  程序就就是由一条一条的语句和一条一条的表达式构成

# 函数(function)  函数急速一种语句  函数就是用来完成特定的功能  
# 函数分类:由python解释器提供的函数 可以再python中直接使用  内置函数
# 自定义函数;自己定义  然后调用
# 当我们需要完成某个功能  就可以调用内置函数 或者自定义函数  
# 函数的两个要素  
#   参数:括号中的内容就是参数  函数中可以没有参数 也可以有多个参数 使用,号隔开
#   返回值:返回值是函数的返回结果  不是所有的函数都有返回值

3.Python基本语法

# 基本语法:
# 在python中严格区分大小写
# 2.在python中每一行急速一条语句 每条语句以换行符结束也就是回车
print(123+456)

# 3.每一条语句长度不要过长 (规范中建议每行不要超过80个字符)

# python是缩进严格的语言  在python不要随意缩进

# 在python使用#好来代表注释  #号 后面的内容为注释  注释的内容会被解释器所忽略 一般习惯上后面有一个空格

4.字面量和变量

# 字面量和变量
# 字面量就是一个一个的值  比如:1 2 3 4 5 6 ‘hello’
# 字面量所表示的意思  就是他的字面值  在程序中可以直接使用字面量
# 变量(variable) 变量可以用来保存字面量 并且变量中保存的字面量是不定的
#  变量本身没有任何意思  它会根据不同的字面量来表示不同的意思
a=100
print(a)

a='hello'
print(a)

# 一般在开发的时候使用变量
salary=1000
print("工资是:",salary)

5.变量和标识符

# 在python定义变量:  python中使用变量 直接为变量赋值即可
# 但是我们不能使用没有进行过赋值的变量  不然报错
# python是一个动态类型的语言 可以为变量赋任意类型的值  也可以任意修改变量的值
a=100
print(a)

a='hello 计算机科学与技术'
print(a)

# 标识符:在python中可以自主命名的内容都属于标识符  比如:变量名  函数名  类名
# 标识符必须遵循标识符的命名规范  1,。标识符可以含有数字 下划线 但是不能使用数字开头
#   例如; a_1
# 标识符不能是关键字或保留字  也不建议使用函数名作为标识符 这样会导致函数被覆盖
# 命名规范采用驼峰命名法
A_1=100;
print(A_1)

print(max(12, 34, 56))

6.数值

# 数据类型指的就是变量的值的类型  也就是可以为变量赋那些值

a="hello World"
print(type(a))


b=123
print(type(a))

# 在python中数值被分为了三种 整数  浮点数  复数

# 整数:在python中所有的整数都是int类型
# 在python整数的大小没有限制 可以是一个无限大的整数  如果数字的长度过大 可以使用下划线来分隔
print("100次幂",99999999999999**100)


# 其他进制的整数: 10进制的数字不能以0开头
# 二进制  0b开头
# 八进制:  0o开头
# 十六进制: 0x开头

print("二进制",0b10)#只要是数字打印的一定是以10进制输出

print("八进制",0o10)
print("十六进制",0x10)

# 也可以通过运算符来对数字进行运算
c=90
c=c+90
print(c)

# 浮点数:在python中所有的小数都是浮点数类型
m=9.19
print("类型是",type(m))

7.字符串

#字符串:用来表示一串文本信息  字符串是程序中使用的最多的数据类型
# 在python中字符串需要使用引号引起来
a='hello World'
print(type(a))

a=123
print(type(a))

# 如果使用字符串 则是一个变量  引号可以是单也可以是双 但是注意不要混着用  引号不能混合使用

# 长字符串:单引号和双引号不能跨行使用  使用三重引号来代表 三重引号可以换行
s=""""n"""
print(s)

# 转义字符
# \' 表示 ‘
#  \" 表示"

8.格式化字符串

# 格式化字符串:
a='hello 计算机科学与技术'
# 字符串之间也是可以用来做加法运算  如果将两个字符串相加 则会自动将两个字符串拼接为一个

print(a)

b="计算机"
print(a+b)

print("a="+a)#这个写法在python中不常见
# 字符串只能和字符串进行加法运算  不能和其他数据类型做加法  如果做了 就会报错


# 在创建字符串时 可以再字符串中指定占位符
n=90
# %s在python就是一个占位符
n='计算机 %s'
print(n)
# %s 在字符串中表示任意占位符
# %f 浮点数占位符
#  %d 整数占位符

# 格式化字符串 可以在字符串前面添加一个f来创建一个格式化字符串
# 在格式化字符串中可以直接嵌入变量
c=f'hello 计算机科学与技术{a}{b}'
print(c)

9、字符串的复制


name='吴邪'

print('欢迎!'+name+' 热烈欢迎')

# 字符串的复制  就是将字符串和数字相乘
a='abc'
# *在语言中表示乘法
c=a*4
print(c)#如果将字符串和数字相乘  则会将字符串重复指定次数并返回

10.布尔值和空值

# 布尔值:(Boolean)  bool  布尔值主要用来做逻辑判断
# 布尔值:True(真)  False(假)

a=True
b=False
print(a,b)

# 布尔值实际上也属于整型 True就相当于1  False就相当于0
print(True+False)#输出1

# 空值 :None专门用来表示不存在

11.类型检查

# 布尔值:(Boolean)  bool  布尔值主要用来做逻辑判断
# 布尔值:True(真)  False(假)

a=True
b=False
print(a,b)

# 布尔值实际上也属于整型 True就相当于1  False就相当于0
print(True+False)#输出1

# 空值 :None专门用来表示不存在
a=-123
b='123'
print(a==b)#false

# 通过类型检查可以检查只能值的类型

# 类型检查  type()  用来检查值的类型
print(type(a))#该检查结果会作为返回值返回  可以通过变量来接收返回值

print(type(None))#空类型

第三章:数据类型

1.对象介绍

# 对象(object)


# 程序运行当中 所有的数据都是存储在内存当中然后再运行  对象就内存中专门用来存储指定数据的一块区域
# 对象实际上就是一个容器 专门用来存取数据
# 像我们之前学的数值 字符串  布尔值  NOne都是对象

# 对象的结构:每个对象都要保存三种数据
#  id  标识  id用来标识对象的唯一性质  每一个对象都有一个唯一的id 对象的id就相当于身份证
#         可以通过id()函数来查看对象的id  id是由解析器生成的 在CPython中id就是内存地址
#               对象一旦创建  id就不能更改
# type      类型:
#           类型用来标识当前对象所属的类型  比如 int  None str
#               类型决定了对象有哪些功能
#               python是一门强类型语言  一旦创建 就不能更改
#  value    值:值就是对象中存储的具体的数据
#           通过type()来查看类型
#            对于有些对象值是可以改变的  对象可以分为两大类  一个可变对象  一个是不可变对象
#           可变对象可以改变值  不可变对象就不能改变

print(id(1))
print(id(2))

2.变量和对象

# 对象并没有直接存储到变量中  在python中变量更是像给对象起了一个别名

# 变量中存储的不是对象的值  而是对象的id(内存地址)  当我们使用变量时  实际上就是在通过对象id在查找对象
# 变量中保存的对象只有在为变量重新赋值时 才会改变
# 变量和变量之间是相互独立  修改另一个对另一个是不会产生影响的


# 类型转换:所谓的类型转换就是将一个对象类型转换其它对象类型

a='hello'
b=123
#print(a+b)
# 类型转换不会改变对象本身的类型 而是将对象的值转换为新的对象  而是根据当前对象的值转换创建一个新的对象
# 类型转换的四个函数  int()  float() str()  bool()

b=str(b)#把类型转换后赋值给他  之后才会改变
print(a+b)


#           --int()
#                       --规则:
#                   布尔值:True--> 1  False-->0
#             --float()  对于浮点数:直接取整  直接保留整数部分 小数部分直接省略
#
#           str()  --把类型转换为字符串  注意一定要赋值  不然无意义

c=12.90
c=int(c)
print(c)

m=123
n='计算机'
m=str(m)
print(m+n)

3.运算符

# 运算符:操作符

# 运算符可以对一个值或多个值进行运算或者操作
# 比如  + - = 都属于运算符
#   算数运算符  比较运算符  比较运算符   逻辑运算符 条件运算符


# 1.加法 +  两个字符串之间进行相加 则进行拼串
print(1+2)


# 2.减法 -
print(10-9)


# 3.乘法 *
print(90**5)

# 4.除法 /  总会返回一个浮点类型
print(9/4)

# 5. 整除 //  返回整数  舍弃小数
print(4//3)

# 6.取模: %       就是返回除法运算的余数
print(12%3)


# 7.赋值运算符: =  将等号右边的值赋值给左侧的变量
a=90
print(a)

# +=  相当与 a=a+5

# -=  相对于 a=a-5

# **= 相当与  a=a**5

4.关系运算符

# 关系运算符 用来比较两个数之间的关系 总会返回一个布尔值
# 如果关系成立  返回True  否则返回False
print(12>90)#返回false

print((12>=2))#true

5.逻辑运算符

# 逻辑运算符:
# not  逻辑非
#               not可以对符号右侧的值进行非运算
#               对于非运算  可以对布尔值来取反
#                 对于非布尔值运算会先将其转换为布尔值  在对其进行运算
# and 逻辑与
#           and  可以对符号两次的值进行与运算
#                     只有在符号两次的值都为true的时候才会返回
#                       python中的与运算符  是找False    第一个值是false 后面的值就都是False
#  or 或
#       对符号两侧的值进行或运算  或运算只要一个为真  就会返回真  后面的就不看了

#           或运算  是找true的  有true后面就不用看了

# 逻辑运算符主要用来进行一些逻辑判断


a=True
b=False
print(not a)

m=True and False
print(m)#True

6.非布尔值的与或运算

非布尔值的与或运算:
		当我们对非布尔值进行与或运算时  python会将其当做布尔值运算  最终返回原值
		与运算是找false 如果第一个值是true 则不看第二个值 如果第一个值是false 则返回第一个值  负则返回第二个值
		
		或运算:或运算是找true   如果第一个值是true  则直接返回第一个值  否则返回第二个值

7.条件运算符



# 条件运算符
# 语法:  语句1 if  条件表达式 else 语句2

# 执行流程: 条件运算符 在执行时 会先对条件表达式进行求值判断  如果判断结构为true 则执行语句1  并且返回结果
# 如果判断结果为false 则执行语句2  并返回执行结果


print("你好  软件工程")  if True else print("你好 计算机科学")

a=100
b=99
print("a大") if a>b else print("b大")#输出a大

8.运算符的优先级

运算符的优先级:
		
# 和数学一样  python中先乘除后加减  or  and 先算与运算  优先级一样自做向右计算
#    优先级的大小可以使用括号来改变

a=1 or 2 and 2
print(a)

n=1 and  (2 or 2)
print(n)

# l逻辑运算符可以连着使用

result=1<2<5#相单于  1< 2 and 2 <3

第四章:流程控制语句

1.if语句

# python代码在执行的时候  是按照自上而下顺序执行的
# 通过流程控制语句  可以改变程序的执行顺序 也可以让指定的程序反复执行多次
# 流程控制语句分为  条件判断  和循环语句
# 1.条件判断语句  if语句
#   if在执行时会先对条件表达式进行求值判断  如果为true就执行if后的语句  如果为false则不执行

a=10
b=9
if a>b:print("你好")

# 在开发的时候  不会直接写死
num=90
if num>80:print("num比80大")
# 在python中  默认情况下if语句只会控制紧随其后的语句  如果在if可以控制多条语句 可以在if后面跟着一个代码块
# 代码块:指的是  代码块中保留着 一组代码  同一个代码块中的代码要么执行  要么及都不执行  代码块就是一种为代码分组的机制
#如果要书写代码块  就不能再冒号后面写代码了
if True:
    print("计算机科学")
    print("与技术学院欢迎你!")
    print("计算机科学")
# 代码块  以缩进开始    直到代码恢复到之前的缩进为止  就结束代码块

num=10
if num>20:
    print("num比20大")
    if num<20:
        print("num比20小")


if num>1 and num<20:
    print("num在这个范围内!")

# 可以使用逻辑运算符来连接多个条件  如果希望所有条件同时满足 则需要and  如果希望只要有一个条件满足就是要or

if 8<num<20:
    print("一样的")

# 缩进有两种方式:
# 一种是使用tab键  一种是使用空格去缩进  python推荐使用空格来缩进

# python代码中使用的缩进方式必须统一  要么tab键 要么 空格  不能乱

2.input函数

# input()获取用户的输入
#input()在调用的时候  程序会暂停
# 输入完成后 会以返回值的形式返回
# i=input("请输入")
# print(i)
# 注意input返回的结果是一个字符串
# 在input可以设置一个字符串作为参数 该参数会作为提示文字

username=input("请输入")
# 判断用户名是否是admin
if username=='admin':
    print("欢迎光临!")

3.if-else语句

# 让用户在控制台中输入一个目录
age=input("请输入年龄:")

age=int(age)
# 注意一定要进行类型转换  不然返回一个字符串  if后面的比较运算符不支持这种运算
if age>18:
    print("你已经成年了")



    # if -else语句:
# 语法:if 条件表达式 :
#         代码块
#      else:
#       代码块
# 在执行时  会先对if后的条件进行求值判断  如果为true 则执行if后面的代码块  如果为false则执行else后的代码块

age=20
if age>18:
    print("你已经成年了")
else:
    print("你还未成年")

4.if-elif-else语句

# if-elif-else语句
# 语法:
# if 条件表达式:
#        代码块
#  elif 条件表达式:
#       代码块
# elif 条件表达式:
#        代码块
# else :
#   代码块

# 这个语句在执行的时候 会自上而下 依次对条件表达式进行求值判断  如果表达式位true 则执行当前代码块 然后语句结束
# 为false  就继续向下判断  直到直到为止
# 如果所有表达式都是false则执行else后面的代码块

age=90
if age>200:
    print("活着")
elif age>80:
    print("老大不小了")
elif age>85 and age<100:
    print("已经老了")
elif age>18:
    print("你还是小孩")
else:print("好了 入土了")

第五章:循环语句

1.while语句

# while  条件表达式:
#           代码块
# 在执行的时候会对while后的条件表达式进行求值判断  如果判断为true 则执行循环体   循环体执行完毕 继续判断 因此类型  找到为false
# 条件表达式恒伟true的时候  会一直执行  这个就是死循环
# 循环的三个要素:初始化表达式  通过表达式初始化一个变量
#               条件表达式 设置循环执行的条件
#               更新表达式 修改初始化变量的值的

age=0
while age<100:
    print("你好",age)
    age+=1#这个表达式  不能用 age++ age-- 因为这个python

i=0
while i<10:
    print("第",i)
    i=i+1

2.whlie练习

# 1.求100以内的所有奇数之和

# 获取100有以内的数
i=0
# 创建一个变量来保存结果
result=0
while i<100:
    i+=1
    # 判断i是不是奇数
    if i%2!=0:
        result=result+i

    print(i)
print("100以内的奇数之和:",result)



# 2.求100以内所有7的倍数之和 以及个数

i=7
result=0
count=0
while i<100:
    result+=i
    print("7的倍数:",i)
    i+=7
    count=count+1
print("7的倍数总和:",i)
print("个数为:",count)


# 3.计算水仙花数

# 获取1千以内的三位数
i=100
while i<1000:
    # 判断i是否是水仙花数  假设i的百位数是a  个位数b  个位数 c  a的三次方+b的三次方+c的三次方=
    #求i的百位数
    a=i
    # 求i的百位数
    b=(i-1*100)//10
    print(b)
    # 求i的个位数
    c=i%10
    print(c)
    print("1000以内的数",i)
    # 判断是否是水仙花数
    if a**3+b**3+c**3==i:
        print(i)
    i+=1

3.循环嵌套

# 打印矩形
# 外层循环控制高度  内层循环控制宽度
i=0
while i<5:
    # 创建一个内层循环来控制图形的宽度
    j=0
    while j<100:
        print("*",end='')
        j+=1
    # print("*",end='')
    print()
    i+=1

# 循环嵌套时  外层循环执行一次 内循环执行一圈
# 打印矩形
# 外层循环控制高度  内层循环控制宽度
i=0
while i<5:
    # 创建一个内层循环来控制图形的宽度
    j=0
    while j<100:
        print("*",end='')
        j+=1
    # print("*",end='')
    print()
    i+=1

# 循环嵌套时  外层循环执行一次 内循环执行一圈



k=0
while k<5:
    m=0
    while m<k+1:
        print("*",end='')
        m+=1
    print()
    k+=1

九九乘法表

# 打印九九乘法表

# 创建一个循环来控制图形的高度

i=0
while i<9:
    i+=1

    # 创建一个内层循环来控制图形的高度
    j=0
    while j<i:
        j+=1
        print(f"{j}*{i}={i*j}",end="")
    print()
# 创建一个循环;来解1-100内的数
i=2
while i<=100:

    #     创建一个变量  记录i的状态
    flag=True



    # 判断i是否是质量数
    #     获取所有可能称为质数的数
    j=2
    while j<i:

        #     判断i是否能被j整除
        if i % j == 0:
            #     i能被j整除  就不是质量数
            flag = False

        j+=1

    if flag:
        print(i)
    i+=1

4.break和continue语句

#break  可以用来立即退出循环语句  包括if--else--if


# continue:可以用来跳过当次循环  这个的作用域就是离最近的循环起作用

# pass  作用就是一个占位符  可以让当前循环通过

# 创建一个5次的循环
i=0
while i<5:
    print(i)
    if i==2:
        break#立即退出循环语句
    else:
        print("循环结束!")
    i+=1


p=0
while p<5:
    p+=1
    if p==2:
        continue#跳过当p=2的那次循环
    print(p)
else:
    print("第二次")
模块:通过模块来对python来进行扩展

# 引入一个time模块来来求运行时间


from time import *


# 作用:time函数可以用来获取当前的时间  返回的单位是秒


begin=time()#获取程序执行开始时间


i=2
while i<=100000:
    #     创建一个变量  记录i的状态
    flag=True
    # 判断i是否是质量数
    #     获取所有可能称为质数的数
    j=2
    while j<i:

        #     判断i是否能被j整除
        if i % j == 0:
            #     i能被j整除  就不是质量数
            flag = False

        j+=1

    if flag:
        print(i)
    i+=1


# 获取程序结束时间
end=time()

print(end-begin,"秒")







第六章:序列

1.列表

# 列表:list  列表是python里面的一个对象
#               对象就是内存中专门用来存取数据的一块区域
#               之前我们学习的对象  像数值 他里面只能保存一个单一的值 或者数据
#           列表中可以保存多个数据

# 列表的使用:
#         1.列表的创建
#           2.操作列表中的数据



#    创建列表  通过中括号来创建
my_list=[1.243,31,1,23,'吴邪']
print(my_list)


# 列表中存储的数据叫做元素  一个列表中可以存储多个元素  也可以在列表创建的时候来指定列表中的元素

listTest=[10]  #创建一个只包含一个元素的列表

# 当向列表中添加多个元素时  多个元素之间使用,号隔开
# 列表是用来存储对象的对象
listTest=[12,32,12,12,12,13]
print(listTest)

# 列表可以保存任意的对象
my_list=['王胖子','解雨臣','12']
print(my_list)


# 列表中对象都会按照插入·的顺序存储到列表中  每一个插入的对象保存到第一个位置  第二个插入的保存到第二个位置  以此类推

# 我们可以通过索引获取列表中的元素

# 索引是元素在列表中的位置  索引是从0开始的整数  列表的第一个位置 索引为0  第二个位置索引为1  因此类型
print(my_list[2])  #这个就是在获取索引为2的元素

# 如果使用的索引超过了最大范围  会抛出异常


# 获取列表的长度  也就是列表的元素个数
print("列表的长度为:",len(my_list))

# 获取到的长度的值  是列表的索引加一

2.切片

my_list=['吴邪','王胖子','张起灵','黑瞎子','21','12','44']

# 切片指向的是从现有列表中  获取一个子列表

# 在python中列表的索引可以是负数  如果索引是负数  则会从后向前获取元素  -1代表倒数第一个  -2代表倒数第二个 以此类推

print(my_list[-2])


# 通过切片来获取指定的元素
# 语法:列表[起始:结束:步长]  步长表示获取元素的间隔  默认值是1
print(my_list[0:3])#通过切片获取元素的时候  会包括起始位置的元素  不会包括结束位置的元素


# 做切片操作时  湖返回一个新的列表  不会影响到原来的列表
# 起始和开始如果都省略不=不写  则截取所有元素
print(my_list)


print("**********************************")
print(my_list[1:2:3])


# 步长不能是0  可以是负数   负数代表的是从列表的后面向前面截取

3.通用操作

# 创建一个列表
stus=['王胖子','解雨臣','12','王胖子','解雨臣','12','王胖子','解雨臣','12']

my_list=['王胖子','解雨臣','12','王胖子','解雨臣','12','王胖子','解雨臣','12']

# +  与   *
print(stus==my_list)

#  +  代表可以将两个列表拼接在一块
print(stus+my_list)

# *  可以赋值列表的个数
print(stus*4)


# in  和  not in
# in 用来检查元素是否在这个元素中
print('2' in my_list)#存在就返回true  否则返回false

print('吴邪' not  in my_list)#检查元素不在列表中  在返回false  不在返回true




# len()获取列表的长度


# min()获取列表中的最小值
# max(0获取列表中的最大值
print(max(my_list))
print(min(my_list))



# index()
# count()
# 方法和函数基本上是一样的  只不过方法必须通过对象.方法的形式去调用
print(my_list.index('解雨臣'))#获取解雨臣在my_list这个列表中的位置   注意是第一次出现 如果获取的是列表中没有的元素则报错

# index的第二个参数代表开始查找的位置  第三个参数 代表参数的结束位置
print(my_list.count('12'))
# count是计数  统计元素在列表中出现的次数
# 序列:是python中最基本的数据结构   数据结构是计算机中数据存储的一种方式
# 序列用于保存一组有序的数据  所有的数据在序列当中都有一个唯一的位置 (索引)  并且序列中的数据都会按照添加的顺序来分配索引


# 序列的分类; 可变序列 (序列中的元素可以改变)
#                   >列表(list)
# 不可变序列(序列中元素不能改变)
#               >字符串(str)
#               >元组(tuple0

#           之前列表的操作 都是序列的基本操作

s="hello world"
print(s[2])

4.修改列表

# 1.通过所有来修改元素
stus=['吴邪','王胖子','解雨臣','黑瞎子','吴邪','王胖子','解雨臣','黑瞎子','吴邪','王胖子','解雨臣','黑瞎子']

stus[0]='修改l1'
print(stus)



stus[3]='张起灵'
print(stus)

# 2.通过delete来输出元素
del stus[3]#删除索引为2的元素


# 3.通过切片来修改
stus[0:2]='123'#在给切片赋值  必须传递序列 当我们设置了步长时  序列中的元素个数必须和切片中元素的个数一致

# 也可以通过切片来删除元素

# 以上操作只适用于可变序列  不可变序列就不能使用这些操作 可以通过list()函数来转换为列表

5.列表的方法

#列表的方法
stu=['吴邪','黑瞎子','沙和尚']
print(stu)


# 1.append(s)  向列表的最后添加一个元素
stu.append('张启山')
print("修改后:",max(stu))

# 2 insert(s,x)  向列表的指定位置插入一个元素  参数1:要插入的位置  参数2 要插入的元素
stu.insert(2,'王胖子')#插入在角标为2的位置

# 3 extend(t)  使用新的序列来扩展当前序列
# 需要一个序列作为参数  它会将该序列中的元素添加到当前序列中
stu.extend(['你好','计算机科学与技术学院'])#把里面的序列添加到stu列表中


# 4.  clear()清空序列
stu.clear()#清空stu序列


# 5.pop() 根据索引删除并返回指定元素
i=stu.pop(1)#删除并且返回删除的元素
print(i)


# 6.remove()  删除指定值的元素
stu.remove('吴邪')
print("删除后:"+stu)


# 7.reverse()用来反转列表
stu.reverse()

# 8.sort()用来对列表进行排序 默认是升序排列
# 降序排列传递 reverse=True作为参数
stu.sort(reverse=True)

6.遍历列表

# 列表的遍历
# 指的是将列表中的所有元素取出来
# 创建列表:
stu=['吴邪','黑瞎子','张启山','早啦兔子']

# 遍历列表
#
# i=0
# while i<4:
#     print(stu[i])
#     i+=1
# while i
#     print(stu[i])
#     i+=1

# 2.使用for循环来遍历

# 语法  for 变量  in 序列:
#           代码块
for s in stu:
    print(s)

# for 循环的代码会执行多次  序列中有多少元素就会执行一次
# 每执行一次就会将序列中的一个元素赋值给变量

7.员工管理系统

# 功能:增删改查

# 1.查询员工

# 2.添加一个


# 3.删除员工


# 4.退出系统

# 创建列表  保存一个信息  员工的信息以字符串的形式保存到列表中
emps=['吴邪\t18\t吴山居\t']

while True:
    # 显示系统的欢迎信息
    print("欢迎使用员工管理系统")

    print('---请选择要做的操作--')
    print("\t1.查询员工")
    print("\t2.添加员工")
    print("\t3.删除员工")
    print("\t4.退出系统")
    user_choose=input("请选择【1-4】")

    # 根据用户的选择来做相关的操作
    if user_choose=='1':
        # 查询员工
        print('序号\t','姓名\t','年龄\t','住址\t')
        # 创建一个变量来保存员工的序号
        n=1
        # 显示员工信息
        for emp in emps:
            print(f'\t{n}{emp}',emp)
            n+=1


        pass
    elif user_choose=='2':
        # 删除员工
        # 获取要删除的员工序号
        del_num=int(input("请输入要删除的员工的序号"))

        # 用户输入的是序号
        # 判断序号是否有效
        if 0<del_num<=len(emps):
            del_i=del_num
            #     显示员工提示信息
            # 显示系统的欢迎信息
            print("欢迎使用员工管理系统")

            print('---请选择要做的操作--')
            print("\t1.查询员工")
            print("\t2.添加员工")
            print("\t3.删除员工")
            print("\t4.退出系统")
            user_choose = input("请选择【1-4】")
        else:
            print("输入有误 请重新操作!")
        pass
    elif user_choose=='3':
        pass
    elif user_choose=='4':
        input("退出")
        break
    else:
        print("输入有误")
    print("--------------------------------------------------------------")

8.range

# range()是一个函数 可以用来生成一个自然数的序列
# 该函数需要三个参数
#     1.起始位置(可以省略 默认值是0)
#         2. 结束位置
#       3.步长(可以省略 默认值是1)
r=range(1,5,2)
print(list[r])
for i in range(20):
    print(i)
# 通过range()可以创建一个执行指定次数的for循环
# for循环除了创建方式以外  其余都和while一样

9.元组

# 元组(tuple)

# 元组是一个不可变序列
# 它的操作方式基本上是和列表一样的
# 所以在操作元组  就把元组当做一个不可变的列表
# 希望数据不会改变时  就使用元组

# 创建元素
# 使用小括号来创建元素
my_tuple=('吴邪','王胖子')#创建了一个空元组
print(my_tuple[0])
print(my_tuple[1])
# my_tuple[3]='吴邪'#这个是错误的  不可以赋值  元组表示可变序列

# 当元组表示空元组时  括号可以省略
# 如果元组不是空元组  它里面至少有一个

ml=10,2,1,2,12
a,b,c,d,e=ml
print(a,b,c,d,e)#元组的解包

i=100
o=900
print(i,o)
i,o=o,i
print(i,o)

# 在对一个元组进行解包时  变量的数量必须和元组中的元素数量一致
# 也可以在变量前面加个* 这样变量会获取一组中所有剩余的元素
#       注意不能同时出现两个*号的变量

10.可变对象

# 可变对象:
# 每个对象都保存了三个数据 id(标识) type(类型)  value(值)
# 列表就是一个可变对象
a=[12,31,23]

a[0]=10
# 这个操作是在通过变量去修改对象的值
# 这个操作不会改变变量所指向的对象  修改对象
# 当我们去修改对象时 如果有其他变量也指向了该对象  则修改也会在其他的变量中体现

a=[12,33,12]
# 这个操作是在给变量重新赋值
# 这种操作会改变变量所指的对象
# 为一个变量重新赋值时 不会影响到其他的变量
# 一般只有在赋值时 才是修改变量  其余是修改对象

# ==和is
# == !=比较的是对象的值是否相等
# is is not 比较的是对象的id是否相等(比较两个对象是否同一个对象)

b=12
print(b is  a)#返回false  地址值不一样

第七章.字典

1.字典

# 字典(dict)是一种映射  字典属于一种新的数据结构 称为映射(mapping)
# 字典的作用和列表类似 都是用来存储对象的容器
# 列表存储数据的性能很好 但是查询数据的性能很差
# 字典中每一个元素都有唯一的名字 通过这个唯一的名字都可以快速的查找到指定的元素

# 在查询元素时 字典的效率非常快
# 在字典中可以保存多个对象 每个对象都会有一个唯一的名字  这个唯一的名字我们称键(key)  这个对象称为值 value
# 所以字典 我们也称为 键值对 key-value 结构  ,每个字典中都可以有多个键值对 而每一个键值对称其为item

# 字典的创建  使用  {}来创建字典
dict={"123",239,"吴邪"}#集合
print(dict,type(dict))

# 创建包含数据的字典
# 语法 {key:value,key:value,key:value}
d={"name":"吴邪",
   "age":"12",
   "address":"吴山居"}
print(d)
# 字典的值 可以是任意对象  可变和不可变  都可以
# 字典的键 可以是任意的不可变对象  int str  bool tuple
# 字典的键是不可重复的  字典的键一般使用字符串
print(d,type(d))


# 我们根据键来获取的值
print(d["name"])

# 如果使用了字典中不存在的键 则报错

2.字典的使用


# 1.创建字典:使用{k1:v1,k2:v2,...}

# 2.还可以使用dict()来创建
d=dict(name="吴邪",age=19,gender="男")#每一个参数都是键值对 参数就是键 参数名就是值(这种方式创建的字典 key都是字符串)
print(type(d))

# 也可以将一个包含双值子序列的序列转换为字典

# 双值序列 序列中只有两个值  例如[1,2] ('a',2)
# 子序列:如果序列中的元素也是序列 那么我们就称这个元素为子序列
# 例如:[(1,2),(3,5)]
d1=dict([('name','吴邪'),('age','19')])
print(type(d1))


# len() 获取字典中键值对的个数
print(len(d1))

# in  检查字典是否包含指定的键
print("name" in d)#true

# not in 检查字典是否不包含指定的键
print("name" not in d1)

# 获取字典中的值  根据键来取值
# 语法:d[key]
print(d['name'])

person="男"
print(type(person))#str

# 通过中括号来获取值时  如果键不存在  则会抛出异常keyError
# get(key[,default])该方法用来根据键来获取字典的值
print(d.get('name'))#如果获取的键在字典中不存在则会返回none 不会报错
# 也可以指定一个默认值 来作为第二个参数  这样获取不到值时 就会返回默认值

# 修改 字典:
# d[key]=value
d['name']="解雨臣"
print(d['name'])

# 也可以使用这个来添加数据
d['phone']='12933'


# setdefault(key[,default])可以用来向字典中添加key-value
reuse=d.setdefault('name','张启山')#如果key已经存在于字典中 则返回key的值 不会对字典做任何操作
# 如果key不存在 则向字典中添加这个key 并且设置value
# 可以定义一个变量来接收返回的值
print(reuse)


# update([]) 将其他的字典中的key-value添加到当前字典中
i={'a':1,'b':1,'c:':'8'}
j={'p':2,'m':90,'s':78}
i.update(j)#如果有重复的key则会替换


# 字典的删除:del  字典名
del d['name']

# popitem()  随机删除字典中的键值对
# 删除之后 他会将删除的key-value作为返回值返回
# 返回的是一个元组 元组中有两个元素 第一个元素是删除key 第二个是时候粗的value
g=d.popitem()
print(g)

# pop() 根据字典中的key来删除值
# 会将删除掉的value返回
# 如果删除不存在的key 则会抛出异常
t=i.pop('d','不存在!')
print(t,)
# 如果找到了默认值 在删除不存在的key时 不会报错 而是直接返回默认值

# clear()用来清空字典
j.clear()

# copy()  该方法用于对字典进行浅复制
r=i.copy()
print(r)#复制后的对象 和原对象是独立的

#浅复制 只会简单的赋值对象内部的值 如果值也是一个可变对象 这个可变对象不会被复制 
d2={'a':'吴邪'}


3.字典的遍历

# 字典的遍历:
#     三个方法:
# keys()  该方法会返回字典的所有的key
d={'name':'吴邪','age':19,'gender':'男'}
# 该方法会返回一个序列 序列中保存字典的所有数据
# 通过去遍历keys去获取所有的键
# print(d.keys())
# 通过变量keys()来获取所有的键

for k in d.keys():
    print(k,d[k])


# values() 该方法会返回一个序列  序列中保留有字典的左右的值
for v in d.values():
    print(v)

# items()
# 该方法会返回字典中所有的项
# 它会返回一个序列 序列中包含有双值子序列
# 双值分别是字典中的key和value
print(d.items())
# 遍历
for i,j in d.items():
    print(i,'=',j)

4.集合

# 集合:set
# 集合和列表非常相似
# 1.集合中只能存储不可变对象
# 2.集合中存储的对象是无序的(不是按照元素的插入顺序保存)
# 3.集合中不能出现重复的元素

# 集合
# 使用{}来创建集合
s2={1,2,3,4,5,6}
# s={[1,2,3],[2311,21]}#这个是不能存储的 因为列表是可变对象
# 2.使用set()来创建集合
s1=set()
# 通过set()来将序列和字典转换为集合
s3=set([1,2,3,4,52])
print(s3)#集合的元素不能重复
# 使用set() 将字典转换为集合时 只会包含字典中的键

# 创建集合
s4={'a','9','吴邪'}
print(s4)

# 使用in和not in 来检查元素是否在集合中

# 使用len()来获取集合中元素的数量

# add()向集合中添加元素
s4.add('解雨臣')
print(s4)

# update() 将一个集合中的元素添加到另一个集合中
s4.update(s3)
print(s4)
# update()可以传递字典或序列作为参数 字典只会使用键

# pop()随机删除集合中的元素 并且返回  可以定义变量来接收这个值
s2.pop()

# clear() 情况集合

# copy()对集合进行浅复制

# 集合就是一种不可重复的序列

5.集合运算

# 集合的运算
# 创建两个集合
s1={1,2,3,4,5,221,34,2091}
s2={98,72,21,1,2,4}

# 交集运算
# 对集合做运算时 不会影响原来的集合 而是将运算结果返回
re=s1&s2
print(re)#求交集


# 并集运算
po=s1|s2
print(po)

# -  差集
sub=s1-s2
print(sub)

# ^异或集  获取只在一个集合中出现的元素
ti=s1^s2
print(ti)




# <= 检查一个集合是否是另一个集合的子集
# 如果一个集合中的元素全部都在另一个集合中出现 那么这个集合就是另一个集合的子集
a={1,2,3,4,5}
b={1,2,3}
su=a<=b
print(su)#false a不是b子集

第八章:函数

1.函数介绍

# 函数:函数也是一个对象   对象是一个内存中专门用来专门存储数据的一块区域
#函数可以用来保存一些课执行的代码 并且可以在需要的时候 对这些语句进行多次调用
# 创建函数  def 函数名(形参1,形参2...形参n):
#                  代码块

def fun(i,j):
    p=i+j
    return p
# 调用函数
p=fun(12,89)
print("和为:",p)

# fn是函数对象  fn()调用函数

2.函数的参数

# 函数的参数:
def fn(i,j):
    l=i*j+i+j
    return l;
m=fn(120,90)#调用函数【
print(m)

# 函数的参数:在定义函数时  可以在函数名后的()在定义数量不等的形参
# 在多个形参之间使用 逗号隔开   
# 形参:(形式参数)  定义形参就是在函数内部声明了变量 但是并不赋值
# 实参(实际参数)  如果函数定义时 指定了形参 那么在调用函数时 也必须传递实参 我们实参将会赋值给对应的形参

3.参数的传递方式

# 调定义函数
def fn(a: object, b: object, c: object) -> object:
    l = a + b + c
    return l


n = fn(1, 2, 3)
print(n)


# 实参的传递方式:
# 定义形参时 可以为形参指定默认值
# 指定了默认值以后 如果用户传递了参数 则默认值就没有任何作用
# 如果用户没有传递 则默认值会生效
def fn1(a, b, c=90):
    return a + b + c


print(fn1(12, 12))

# 实参的传递方式
# 位置参数
# 位置参数就是将对应位置的实参 赋值给对应位置的形参
# 第一个实参赋值给第一个形参 第二个实参赋值给第二个形参  ....
fn(12, 3, "吴邪")
# 关键字参数:
# 关键字参数 可以不按照形参定义的顺序去传递 而直接根据参数名去传递参数
fn1(b=90,a=89)#好处就是不用建议参数位置
# 关键字和位置参数可以混合使用
# 混合使用关键字和位置参数时 必须将位置参数写到前面

参数在调用时 解析器不会检查实参的类型 实参可以传递任意类型的对象

每一个参数都是独立 
如果形参指向的是一个对象 当我们通过形参去修改对象时 会影响到所有指向该对象的变量

4.不定长参数

# 定义一个函数 可以求任意个数的和
def fn(a,b,c):
    return a+b+c
# 求任意数字的和  就不满足题意了
# 因此在定义函数时 可以在形参前面加上一个* 这样这个形参将会获取到所有的实参 将会将所有的实参保存到一个元组中
#   *a会接收所有的位置实参 并且会将这些实参统一保存到一个元组中  (装包)
def fn1(*a):
    # 定义变量来保存结果
    result=0
    # 需要遍历元组 并且将元组中的数进行累加
    for i in a:
        result+=i

    return result
print(fn1(12,34))
# 注意:带*号的形参只能有一个  带*号的参数可以和其他参数配合使用  第一个参数给a 第二个参数给b 剩下的都保存到c的元组中
# 可变参数不是必须写在最后 但是注意 带*号的参数后的所有参数 必须以关键字参数的形式传递

# *号形参只能接收位置参数  而不能接收关键字参数
#  **形参可以接收其他的关键字参数 它会将这些参数统一保存到字典中 字典的key就是参数的名字
# 字典的value 就元素的值
# **形参只能哟Uyghur 并且必须写在所有的参数的最后

5.参数的解包

# 参数的解包
def fn(a,b,c):
    print(a,b,c)
fn(1,2,3)

# 创建一个元组:
t=(10,23,40)
fn(t[0],t[1],t[2])

# 传递实参时 也可以在序列类型的参会时前面添加*号 这样也会自动将序列中的元素因此作为参数传递
fn(*t)
# 要求序列中元素的个数必须和形参的个数一致


# 创建一个字典
d={'a':'20','b':'78','c':'n'}
# 对字典解包  通过**来对字典解包
fn(**d)

6.返回值

# 防护值:

def sum(*nums):
    result=0
    for n in nums:
        result+=n
    return result
p=sum(123,456,789)
print(p)

# 返回值 就是函数执行以后返回的结果
if p>1000:
    print("你好!")
elif p<9000:
    print("你不行了!")
else:
    print("你不好")

# return后面跟声明值 后面就会返回声明值
# return后面可以跟任何的对象 甚至可以是一个函数

def un(a,b):
    def n():
        print("你好")
        return n()
un(12,31)
# 如果仅仅写了一个return或者不写return 则相对于return None
# 在函数中 return后的代码都不会执行  return一旦执行局自动结束

def Person():
    return 10
# Person和Person的区别
print(Person())#函数调用
print(Person)#函数对象

7.文档字符串

# 文档字符串
# help()是python中的内置函数
# 通过help()函数可以查询一些函数用法
help(print)#获取print的函数说明

def fn():
    '''这是一个文档字符串 具体说明了函数的使用
        a,作用
        b,作用
    '''
    return 0
help(fn)
#文档字符串  (doc str) 在定义函数时 可以在函数内部编写文档字符串 文档字符串就是函数的一个说明
# 当我们编写了文档字符串时 就可以通过help()函数来查看函数的说明
# 文档字符串非常简单 其实直接在函数的第一行写一个字符串就是文档字符串

8.作用域与命名空间

# 作用域:scope  产生作用的一个区域 指的是变量生效的区域
def fn():
    a=10
    return  a
print(fn())
# print(a)#这个就无法访问 作用域就是在函数内部

# 在python中一共有两种作用域
# 全局作用域
#       --全局作用域在程序执行时创建 在程序执行结束时销毁  所有函数以外的区域就是全局作用域
#           在全局作用域中定义的变量 都属于全局变量 全局变量可以在程序的任意位置被访问
# 函数作用域
#       --函数作用域 在函数调用时创建 在调用结束时销毁
# 函数每调用一次就会产生一个新的函数作用域
# 在函数作用域中定义的变量只能在函数内部访问 无法在外部被访问
#

def function():
    def fnp():
        print("你好")
    fnp()
function()

# 当我们使用一个变量 时 我们会优先在当前作用域中查找该变量 如果有则使用 如果没有则继续在上一级作用域中寻找
# 以此类推 查到最后还是没有 那么就是报错 undefined
# 在函数中为变量赋值时 默认都是局部变量  如果需要修改全局变量 则需要使用global关键字来声明变量
# 此时在修改变量 就是修改根据的值

9.命名空间

# 命名空间:namespace  就是变量存储的位置 每一个变量都需要存储到指定的命名空间当中
# 每一个作用域都会有一个它对应的命名空间
# 全局命名空间:用来保存全局变量  函数命名空间 :用来保存函数中的变量
# 命名空间实际上就是一个字典 是一个专门用来存储变量的字典

# locals()函数就是用来获取当前作用域的命名空间
# 如果在全局作用域中 调用locals则获取全局 命名空间 如果在函数作用域中调用locals则获取函数命名空间
# 返回一个字典
scope=locals()
print(scope)

# 向字典中添加一个key-value就相当于在全局中创建了一个变量
def fn():
    scope=locals()#在函数内部调用 会获取到函数的命名空间

    #     获取全局命名空间  global()函数可以获取任意位置的命名空间
    global_w=globals()
    return scope
i =fn()
print(i)

10.递归

# 递归:
# 需求求10的阶乘
# 创建一个函数用来求阶乘
def factorial(n):
    # 该函数用来求任意函数的阶乘
    # 参数:n  求阶乘的数字
    # n=10
    # 定义变量来保存结果
    result=n
    for i in range(1,n):
        result*=i

    # factorial(n)*factorial(n-1)
    return result

        # 递归:递归式的函数:函数调用函数
# 注意:递归如果是无穷递归 内存会被占满 递归是解决问题的方式 它和循环很像 它的整体思想是将一个大问题分解为一个个小问题
i=factorial(10)
print(i)

def fn():

    fn()
#     递归1函数的两个条件:
# 1.基线条件  问题可以被分解的最小问题 当满足基线条件时 递归就不在执行了
# 2.递归条件:就是将问题分解的条件


#
def fact(n):
    #     参数是一样的
# 基线条件
#     判断n是否为1
        if n==1:
            return 1
        elif n>1:
            return n*fact(n-1)
# 调用函数
test001=fact(1)
print(test001)
test002=fact(9)
print(test002)
# 递归和函数类似 可以用来解决循环的问题  

11.高阶函数

# 高阶函数:
class A:
    age=None
    name=None

    def fn(self):
        self.age=self


print(A.age)

# 高阶函数:接收函数作为参数 或者将函数作为返回值的函数就是高阶函数

# 创建一个列表
list=[1,2,3,4,5,6,7]

# 定义一个函数 把列表中的所有偶数 返回
def fn(lst):
    # 定义一个函数 用来检查一个任意的数字是否是偶数
    def fn2(i):
        if i%2==0:
            return True

    # fn()函数可以将指定列表中的所有偶数获取出来 并且保存到一个新列表中返回 lst就是要筛选的列表
    # 创建一个新列表
    new_list=[]
    # 对列表进行筛选
    for n in lst:
        # 判断n的
        if fn2(n):
            new_list.append(n)
    # 返回新列表
    return new_list
print(fn(list))

12.匿名函数

# 匿名函数:filter()可以从序列中过滤出符合条件的元素 保存到另一个新的序列
# 参数:1.函数 根据该函数来过滤序列(课迭代的结构)  2.需要过滤的序列
# 返回值:过滤后的新的序列
def fn():
    return 0
# r=filter(fn,1)

# fn是作为参数传递进函数中的  而fn实际上只有一个作用 就是作为参数  filter调用完成后就没有用了

# 匿名函数:lambda函数表达式  专门用来创建一些简单的函数 是创建函数的另一种方式:
# 语法:lambda 参数列表 :返回值

def fn1(a,b):
    return a+b

lambda a,b:a+b #这个就是匿名函数

# 也可以将匿名函数赋值给变量

p=filter(lambda a,b:a+b,1)
print(p)


# map()可迭代对象中的所有元素做指定的操作 然后将其添加到一个新的对象返回
# 匿名函数一般都是作为参数使用 其他地方一般不会使用

13.sort的使用

# sort的使用:
# 该方法用来对列表中的元素进行排序
li=[1,2,3,53,21,245,321,334]
# sort()默认比较的是列表元素中的大小
li.sort(key=int)#在sort中可以接收一个关键字参数 key  key需要一个函数作为参数
# 每次都会以列表中的一个元素作为参数来调用函数 并且调用函数的返回值来比较元素的大小
print(li)
#sorted()这个函数可以对任意序列进行排序 并且使用sorted()进行排序不会影响到原来的对象 而是返回一个新对象

14.闭包

# 闭包:将函数作为函数返回值返回 也是一种闭包、
def fn():
#     将函数内部在定义一个函数
    def inner():
        print("我是inner")
#         将内部函数inner作为返回值返回
    return inner

r=fn()
    # r是一个函数 是调用fn()后返回的函数  这个函数实在fn内部定义 并不是全局函数
    # 所以这个函数总是能访问到fn()函数内部的变量
r()
# 这种高阶函数我们称为闭包 通过闭包可以创建一些只有当前函数能访问的变量  可以将私有属性藏到闭包中

# 形成闭包的要求:
# 1函数嵌套
# 2.将内部函数作为返回值返回
# 3.内部函数必须使用到外部函数的变量

15.装饰器

# 创建几个函数:
def add(a,b):
        return a+b
def mul(a,b):
    return a*b


# 希望函数在计算前打印开始计算 计算结束会打印计算完毕
d=add(12,90)
print(d)
# 我们可以通过修改函数中的代码来完成这个需求 但是会产生以下问题:1.修改的函数过多 修改起来会比较麻烦  2.不方便后期的维护
# 并且这样做会违反开闭原则
# 我们希望在不修改函数的情况下 来对函数进行扩展
# 只需要根据现有的函数来创建一个新的函数
def new_add(a,b):
    print("函数执行~~")
    r=add(a,b)
    print("计算结束~~")
    return r
p=new_add(123,456)
print(p)


# 装饰器的使用:
# 上边的方式:我们已经可以在不修改源代码的情况下进行扩展了 但是要求我们每扩展一个函数就要创建一个新的函数 实在是麻烦了
# 为了解决这个问题 我们可以创建一个函数 让这个函数可以自动的帮助我们去生产函数
def begin_end():
#     作用:就是对其他函数进行扩展 使其他函数在执行前打印开始执行 执行后打印结束
# 创建一个新函数
    def new_function():
        print("开始执行~~~")
        # add(123,789)#调用被扩展的函数

        pass
# 返回一个新函数
    return new_function()

# 像这种函数就成为装饰器  通过装饰器可以不修改原来函数的情况下对函数进行扩展
# 在开发中  我们都是通过对装饰器来扩展函数的功能的

@begin_end#在定义函数时 可以通过@装饰器 来生缘指定装饰器 来装饰当前的函数 可以对同一个函数指定多个装饰器 从内到外的顺序去装饰器
def say_hello():
    print("大家好!~~~")

say_hello()

第九章:面向对象

1.对象

# Object
# 对象;对象是内存中专门用来存放数据的一块区域
# 对象中可以存放各种数据 (比如:数字 布尔值 代码)

# 对象:1.对象的标识  2.对象的类型  3.对象的值
# 面向对象:python是一门面向对象的编程语言  

# 面向对象:关注的是对象 而不关注过程
# 将所有的功能保存到对象中  要使用某个功能 直接找到对应的对象即可 这样子可复用性高

2.类

# 类(class)
# 对象是类的实例  如果多个对象是通过一个类创建的 我们称这些对象是一类对象
# 我们自定义的类都需要使用大写字母开头:
a=int(10)
b=str('hello')
# 这个就是声明类的实例

# 定义简单的类:使用class关键字
# class  类名(【父类】):
#       代码块
class Myclass():
    pass

print(type(Myclass))

# 使用Myclass来创建一个对象
mc=Myclass()#mc就是通过Myclass创建的对象   mc就是类的实例


# isinstance()用来检查一个对象是否是一个类的实例

3.对象的创建流程

# 对象的创建流程:

# 类也是一个对象  类就是一个用来创建对象的对象
# 可以向对象中添加变量 对象中的变量称为属性
# 语法:对象.属性名=属性值
class MyClass():
    name:''
    def fun(self):
        print("你好 我是类的里面的方法")
    def funTest(self):
        print("你好 计算机科学与技术!")
    pass
mc=MyClass()
mc.name='吴邪'
print(mc.name)

mc.fun()

4.类的定义

# 类的定义:类和对象都是对程序中内容的一个抽象
# 实际上所有的事物 由两部分组成:1,数据(属性)  2.行为(方法)

class Person():
    # 在类的代码块 中定义变量和函数
    # 在类中所定义的变量 都会称为所有实例的公共属性
    name=''#公共属性 所有实例都可以访问

#     在类中定义的函数称为方法
# 这些方法都可以通过类的实例来访问
    def methods(self):
        self.name="吴邪"
        print("我是方法!")

# 创建Person的实例
p1=Person()
p2=Person()
print(p1==p2)
print(p1.name)
print(p1.methods())

# 调用方法 对象.方法名()
# 方法调用和函数调用的区别
# 如果函数调用 则调用时传递几个参数 就会有几个实参
# 当时如果是方法调用 默认传递一个参数 所以实际上至少要定义一个形参

5.属性和方法

# 属性和方法:

class A:
    name=''
    age=''
    def fn(self):
        print("你好!")
        print(self)



p=A
p.name="吴邪"
# 类中定义的属性和方法都是公共的  任何该类的实例都可以访问
# 属性和方法查找的流程:当我们调用一个对象的属性时 解析器会先在当前对象中寻找是否含有该属性
# 如果有 则返回当前对象的属性值
# 如果没有 则去当前对象中去寻找  如果有则返回类对象的属性值
# 如果没有则报错
p.fn("吴邪")
# 类对象和实例中都可以保存属性(方法)
# 如果这个属性(方法) 是所有实例所共享的 则应该将其保存到类对象中
# 如果这个属性方法是某个实例独有 则应该保存到实例对象中
# 一般情况下 属性保存到实例对象 方法保存在





# 在方法中  不能直接访问类中的属性
# 方法每次被调用时 解析器都会自动来传递这个实参
class B:
   def say_hello(a):
        print("你好")
   def say_test(self):
        print(self)
# 方法如果是p1调的 则第一个参数就是p1对象
# 如果是p2调用的 则第一个参数就是p2对象 一般情况下 都会把这个参数命名为 self

test=B
test.say_hello(1)
test.say_test("你好 计算机科学与技术")

6.类的特殊方法init

# 定义一个类:
class Person:
    def __init__(self,name,age,gender):
        print("自动执行了!~")
        # 通过self中初始化属性
        self.name=name
        self.age=age
        self.gender=gender
        # 调用类的创建对象时 类后面的所有参数 都会依次传递给给对应的参数
        pass
    def __int__(self):
        pass
    # 特殊方法 不需要我们自动调用  不要尝试去调用这种方法 特殊的方法会在特殊的时刻自动调用
    # 特殊方法什么时候调用
    # 特殊方法有什么作用
    def say_hello(self):
        # 必须传递一个self参数 其他的随便
        print("我是计算机科学",self)


# 手动去天津爱name属性



# 目前来讲:对于Person 类来所name是必须的 并且每一个对象中的name属性基本上都是不同的
# 而 我们现在是将name属性在定义为对象以后 手动添加到对象中  这种方式很容易出现错误

# 我们希望用户在创建对象  必须设置name属性   如果不设置 则对象无法设置  属性的创建应该是自动完成的
# 表示自动完成的

# 在类中 我们可以定义特殊方法  特殊方法都是以双下划线开头  双下划线结尾 的方法


# 创建对象的流程:
# 1.创建一个变量:在内存中创建一个新对象
# 2.在内存中创建一个新对象
#3. 执行类中的代码块
# 4._init(self)__执行
# 5.将对象的id赋值给变量


# init方法会在对象创建的时候调用
# init可以用来向新创建的对象进行初始化属性

# 类的基本结构:
# class 类名(【父类】):
#         公共的属性...
#       对象的初始化方法
#           def __init(self,...):
#           .....
#           其他的方法
#            def methods(self,...):
#                   ...
#   ...............

7.练习

# 定义一个类:
class   Dog:
    '''这个狗的类 里面指定好属性和方法'''
        #     创建初始化方法
    def __init__(self,name,age,gender,height):
        self.name=name
        self.age=age
        self.gender=gender
        self.height=height
    def methods1(self):
        print("狗叫")
    def methods2(self):
        print("狗吃屎")
    def methods(self):
        print("%s 快乐的奔跑!")
d=Dog('旺财',19,'男',120)
print(d.name,d.age,d.height)
d.methods2()
# 目前我们可以通过对象.属性的方式来修改值  但是这个不安全  导致任意对象都可以随意修改  我们需要一种方式来增强数据的安全性
# 1.数据不能随意修改
# 2.数据不能修改为任意的值

8.封装

# 封装是面向对象的三大特性之一:
# 封装是指向隐藏对象中有些不希望被外部访问到的属性和方法
# 如何获取修改对象中的属性?
#   我们需要提供一个getter和setter方法 来使外部可以访问到属性
#       getter 获取对象指定的属性(get_属性名)

class Dog:
    def __init__(self,name):
        self.H_name=name
    '''狗的类
    '''
    def say_hello(self):
        print("Hello World!")
    def get_name(self):
        '''get_name用来获取对象的name属性'''
        return self.H_name#这样子就获取的了属性
    def set_name(self,name):
        self.H_name=name#调用set方法来修改属性
#     如何去隐藏一个对象中的属性

#



# 使用封装:确实是增加了类的定义的复杂程度 但是也确保了数据的安全性
# 增加get和set方法 很好的控制了属性是否是只读的
# 如果希望属性是只读的  则可以直接取去掉set方法
# 以此类推


g=Dog('旺柴')
print(g.H_name)
# 修改name的值
g.set_name('如花')
print("修改后~~")
print(g.get_name())

9.隐藏类中的属性

#
class React:
    '''
    表示矩形的类

    '''
    def __init__(self,width,height):
        self.hidden_width=width
        self.hidden_height=height
    # 定义一个获取宽度的方法
    def get_height(self):
        return self.hidden_width
    def get_width(self):
        return self.hidden_height
    def set_width(self,width):
        self.hidden_width=width
    def set_height(self,height):
        self.hidden_height=height
    # 提供计算面积的方法
    def get_area(self):
        return self.hidden_height*self.hidden_width

Area=React(1,2)

# 先获取长
Area.set_width(12)
Area.set_height(19)
print("面积为:",Area.get_area())
# 可以为镀锡的属性使用双下划线开头 __xxx
# 双下划线开头的属性 是对象的隐藏属性 隐藏属性只能在类的内部访问 无法通过对象访问
# 双下划线开头的属性是隐藏属性 无法通过对象访问 其他隐藏属性只不过是python自动为属性修改了一个名字
# 实际上将名字修改为了 _类名__属性名 比如__name  --> _Person__name
# 一般情况下  使用__开头的属性是私有属性 没有特殊需求不要修改私有属性

10.装饰器

# 装饰器:

class Person:
    def __init__(self,name):
        self._name=name
        # property 装饰器 用来将一个get方法转化为对象的属性  添加为property装饰器以后 我们就可以像调用属性一样使用get方法
    @property#装饰器  有了这个就可以直接调用属性
    def name(self):
        print("get方法执行了~~")
        return  self._name
    # 使用property装饰的方法 必须和属性名一致
    # set方法的装饰器:@属性名.setter
    @name.setter#这个就是set方法的装饰器
    def name(self,name):
        print("这个是set方法")
        self._name=name
        
        
myPerson=Person('吴邪')
print(myPerson.name)
myPerson.name='张启山'
print("修改后:",myPerson.name)

11.继承

class Animal:
    # 定义跑和睡觉两个方法
    def run(self):
        print("动物跑起来~~")
    def sleep(self):
        print("动物睡觉~~~")

# 还想定义一个狗类  也要有动物类的方法

myAnimal=Animal()
myAnimal.sleep()
myAnimal.run()

# 继承父类的方法:  继承是面向对象的三大特性之一:通过继承我们可以使一个类获取到其他类中的属性和方法
class Dog(Animal):#在括号里面就可以指定父类
    def run(self):#重写父类的方法
        # 通过继承我们可以使一个类获取到其他类中的属性和方法
        # 在定义类 可以在类名后面的括号中指定当前的父类 (超类 基类 super)
        super().run()
        # 子类可以直接继承父类中的所有属性和方法
    def bark(self):
        print("汪汪汪~~")
#         通过继承可以直接让子类获取到父类的方法或属性  避免编写重复性的代码  并且也符合ocp开闭原则
# 所以我们经常需要缇欧继承来对一个类来进行扩展
d=Dog()
d.run()
d.sleep()

print(isinstance(d, Animal))#true

class Cat(Animal):
    def run(self):
        print("跑起来~~·")
# 在创建类时  如果省略了父类  则默认父类为Object  所有类的父类
c=Cat()
c.run()
# 检查这个类是不是另一个类的子类
print(issubclass(Cat, Animal))#true
print(isinstance(Cat, object))#true

12.方法的重写

# 方法的重写:
class Animal:
    def run(self):
        print("动物会跑!~~")
    def sleep(self):
        print("动物睡觉~~··")

class Dog(Animal):
    def bark(self):
        print("狗叫~~")
    def run(self):
        print("我重写了父类的方法")

# 创建dog实例
d=Dog()
d.run()

# 如果在子类中  如果有和父类同名的方法 则通过子类实例 去调用方法时  会调用子类的方法而不是 父类的方法
# 这个特点我们称为方法的重写 override

class A(object):
    def test(self):
        print("我是测试方法")
class B(A):
    def test(self):
        print("我重写A的方法")
class C(B):
    def test(self):
        print("我重写了B类的方法")
# 当我们调用一个对象的方法时  会优先去当前对象中寻找是否具有该方法 如果有则直接调用  如果没有 则去当前对象的父类中寻找
# 以此类推

13.super关键字

# super关键字:
class Animal:
    def __init__(self,name):
        self._name=name
    @property
    def name(self):
        return self._name
    @name.setter
    def name(self,name):
        self._name=name
    def run(self):
        print("动物会跑~~")
    def sleep(self):
        print("动物睡觉~~")


class Dog(Animal):

    def __init__(self,name,age):
        # 希望直接调用父类的init方法
        # Animal.__init__(self,name)
        super(Dog, self).__init__(self)
        self._name=name
        self._age=age

    def run(self):
        print("狗跑")
    def sleep(self):
        print("狗睡觉")
    # 父类中所有的方法都会被子类继承  包括特殊方法  也可以重写特殊方法


f=Dog('旺财',19)
print(f.run())
print(f.name)

14.多重继承

# 多重继承:
class A:
    def test(self):
        print("测试方法~~")
class B():
    def test(self):
        print("我重写父类A的方法")

class C():
    def test(self):
        print("我重写了B类中的方法")
# 类名.__base__这个属性可以用来获取当前类的所有父类
print(C.__bases__)
print(A.__bases__)
# 在python中是支持多重继承的  也就是我们可以为一个类同时指定多个父类
# 可以在括号的后面添加多个类
class D(A,B,C,object):
    # 多重继承可以拥有多个父类
    def test1(self):
        print("你好")

d=D()
d.test()
# 在开发中  没有特殊情况 不建议使用这种多重继承
# 多个父类中有同名的方法 则会先在第一个父类中寻找 然后找第二个  然后第三个...前面会覆盖后面的

15.多态

# 多态:是面向对象三大特征之一:多态就是多种形态
# 一个对象可以从不同的形态去呈现

# 定义两个类
class A:
    def __init__(self,name,age):
        print("我是初始化方法")
        self._name=name
        self._age=age
    @property
    def name(self):
        return self._name
    @name.setter
    def name(self,name):
        self._name=name
class B(A):
    pass

test=B('吴邪',19)
print(test.name)


 # len()之所以 一个对象能通过len(0来获取长度 是因为该对象中有一个特殊方法  __len__
 # 1说 主要对象中具有__len__特殊方法  就可以通过len来获取长度
 
 # 面向对象三大特征:封装
#                       --确保对象中数据安全
# 继承  
#       保证了对象的可扩展性
# 多态  
#       保证了程序的灵活性

16.类中的属性和方法

# 类中的属性和方法:
class A(object):
    count=0#这个属性就;诶属性
    # 类属性  可以通过类或类的实例去访问
# 但是类属性只能通过类对象来修改  无法通过实例对象修改
    def __init__(self,name):
        self._name=name
#     实例属性 只能通过实例对象来访问和修改  类对象无法访问和修改
    @property
    def name(self):
        return self._name
    @name.setter
    def name(self,name):
        self._name=name
    def test(self):
        print("测试")

# 类方法:在类内部使用  @classmethod来修饰的方法属于类方法
#     类方法的第一个参数为cls  也会自动传递  cls就是当前的类对象
    @classmethod
    def test_class(cls):

        print("这个是 类方法")
# 静态方法:在类中使用@staticmethod来修饰的方法属于静态方法
    @staticmethod
    def test_static():
        print("我是静态方法~")#静态方法不需要指定任何的参数 静态方法可以通过类和实例去调用
#         静态方法 基本上是和当前类无关的方法  只是一个保存到当前类中的函数 
# 静态方法一般都是工具方法  


# 类属性:
# 实例属性
# 类方法和静态方法
# 实例方法


#         实例方法:
# 在类中定义 以self为第一个参数的方法都是实例方法
# 实例方法 在调用  解释器 会将调用对象作为self传入
# 实例方法 可以通过实例和类去调用
# 当通过实例去调用时  会自动将当前调用对象作为self传入
# 当通过类去调用时  不会自动传递self  那此时我们必须手动传递
# 实例方法
a=A('吴邪')
print(a.count)
print(a.name)
a.test()
A.test(a)
# 实例属性:
# 通过实例对象添加的属性属于实例属性
a.count=10
a.test_class()
# 类方法和实例方法的区别:实例方法的第一个参数为self  而类方法的第一个参数是cls
# 类方法可以通过类去调用和通过实例去调用

17.垃圾回收

# 程序在运行过程中 也会产生垃圾  垃圾过多之后会影响到程序的性能  所以这些垃圾必须清理
# 没有的东西就是垃圾  在程序中
class A():
    def __init__(self):
        self.name='A类'

    def __del__(self):
#         这个是特殊  方法  会周期垃圾回收前被调用
        print("垃圾删除~")
a=A()

print(a)


input("请输入~")
    # 在程序中  没有被引用的对象就是垃圾
a=None#将a设置为None  此时没有任何的变量对A()对象进行引用  它就是变成了垃圾
print(a)
# 这种垃圾过多之后 就影响到了程序的性能

# 所谓的垃圾就是将垃圾从内存中删除

# 在python中 有自动的垃圾回收机制  他会自动将这些没有被的对象删除  所以我们不用去手动处理回收垃圾

18.其他特殊方法

# 其他特殊方法:特殊方法都是使用双下划线开头双下划线结尾
# 特殊方法不需要手动调用  需要在一些特殊情况下执行

class A(object):
    def __init__(self,name,age):
        self.name=name
        self.age=age


    # str()这个特殊方法  会在我们将对象转换为字符串的时候调用  作用  可以用来指定对象转换为字符串的结果
    def __str__(self):
        return 'Hello World'
    def __repr__(self):
        # 这个特殊方法会对当前对象使用repr()函数时 调用
        return 'hello repr方法'

    def __gt__(self, other):
#         会在对象作大于比较的时候使用
# 需要两个参数   一个self表示当前对象  other 表示和当前对象比较的对象
        return self.age>other.age

    def __len__(self):
#         这个方法就是获取长度的
        return len(self)
    
    def __add__(self, other):
#         做加法:
        return self.age+other.age


#         当我们打印一个对象时 实际是打印对象中的特殊方法  __str__的返回值
p1=A('吴邪',19)
p2=A('王胖子',190)
print(p1)
o=[12,3,4,5,62,3,45]

第十章:模块化

1.模块介绍

# 模块介绍:
#       模块化  将完成的程序  分解为一个一个的小的模块  通过模块组合  来搭建出一个完整的程序
# 不采用模块化 统一将所有的代码编写到一个文件中
# 采用模块化  将程序分别编写到多个文件中
#       模块化优点:
#       1.方便开发
#         2.方便维护
#          3.模块可以复用 


# 在python中一个py文件就是一个模块  要想创建模块实际上就是创建一个python文件

# 注意  模块名要符合标识符规范

# 如何在其他模块中引入其他模块
# 1.  import 模块名(模块名  就是python文件的名字  注意不要py)
# 利用引入同一个模块多次  但是模块的实例只有一个
# import test_module

# 2.引入模块第二种方式: 起别名
# import test_module as os

# import可以在程序的任意位置调用  一般情况下  我们在程序的第一行书写import  在每一个模块内部__name__属性 通过这个属性
# 可以获取到模块的名字
# name属性值为__main__是主模块  一个程序中只会有一个主模块  主模块

2.模块的使用

import mTest as k
#导入一个模块m
print(k.a,k.b)

# 在模块中定义的函数  同样可以通过模块来访问
#创建类的实例:
p=k.A()
p.classTest()


# 也可以只引入模块中的部分内容
# form 模块名 import 变量 ,变量....
from mTest import A


# 也可以为引入的变量使用别名
from  mTest import A as  new_name

# 添加了下划线的变量 只能在模块内部访问  在模块外部访问不到   因此使用下划线来使得私有化属性
# import总结:
# import xxx
# import xxx  as yy

3.包

# 包(package)  包也是一个模块  当我们模块中的代码过多时  需要分解为多个模块时  这时就需要使用到包
# 普通的文件就是一个py文件  而包是一个文件夹
# 包中必须要有 一个__init__.py文件
import hello as  test

print(test.a)

# __pycache__是模块的缓存文件
# py代码在执行前  需要被解析器先转换为机器码 然后再执行
# 所以我们在使用模块(包) 时   也需要将模块先转换为机器码然后再交由计算机执行

4.python标准库

#   标准库会死python的安装而安装
#       1.sys模块:他里面提供了一些变量和函数值  使我们可以获取到python解析器的信息 或者通过函数来操作python解析器
# 引入sys模块
import sys

print(sys)

print(sys.argv)  # 命令行里面所包含的参数
# 该属性是一个列表

# sys.modules获取程序中引入的模块
print(sys.modules)  # 是一个字典
import pprint

pprint.pprint(sys.argv)

# sys.path
pprint.pprint(sys.path)  # 是一个列表  列表中保存的是模块的搜索路径

print(sys.platform)  # 表示当前python运行的平台

# 退出程序
sys.exit()  # 这个是个函数  在任意位置插入即可

import os

# os模块可以访问操作系统
# os.environ通过这个可以获取到系统的环境变量
print(os.environ)
print(os)


# os.system()
# 可以用来执行操作系统的名字
os.system('cmd')

第十一章:异常和文件

1.异常的解决

# 程序在运行过程中  不可避免的出现一些错误  这些错误称为异常
# print(10/0)
# 程序运行过程中 一旦出现异常会导致程序立即终止
# 程序运行出现异常  目的并不是让我们的程序直接终止

# try语句:
# try:
#       代码块(可能出现的语句)
# except:
#       代码块(出现错误以后的处理方式)
# else:
#        代码块 (没出错的要执行的语句)

try:
    print(1/4)
except:
    print("当前程序有异常~")
else:
    print("没有错误")
    # 可以将可能出错的代码放入到这个位置  如果没有错误则会正常执行  如果出现错误就执行except代码块里面
    # 防止代码因为小错误而终止

2.异常传播

# 当在函数中出现异常时  如果在函数中对异常进行了处理  则异常不会继续传播  如果函数中没有对异常进行处理  则不会报错

def fun():
    print(10/0)
def fun1():
    try:
        fun()
    except:
        print("程序有错误!")
    else:
        print("第一个函数有问题")
def fun2():
    fun1()
fun2()

        # 异常的处理:抛出异常
        # 当程序运行过程出现异常以后  所有的异常信息会保存到一个专门的异常对象中  而异常对象传播时
        # 实际上就是异常对象抛给了调用处
        # 在python为我们提供了多个异常对象

3.异常对象

# 异常对象:
print("异常出现前")

try:
    print(1/0)
except NameError:#在后面跟着异常类型  那么这个时候  只是会捕获该类型的异常  表示这个类型的异常不会捕获
    # 如果这里后不跟任何的内容 则此时它会捕获所有的异常
    print("异常")
except TypeError:
    print("类型异常")
except ZeroDivisionError:
    print("数据异常")
except Exception as e:
    # 这个异常类型是所有异常的父类  只要写了 这个就会捕获所有的异常
    print(e)
#     可以在异常类后面跟着as  xx  此时xx就是异常对象
else:
    print("异常出现")

print("异常出现后")

# try语句:
# try:
#       代码块(可能出现的语句)
# except 异常类型:
#       代码块(出现错误以后的处理方式)
# 
# except 异常类型
#       代码块
# else:
#        代码块 (没出错的要执行的语句)
#   finally:
#       代码块(即使出现错误都要执行的代码)
# try是必须有的  else有没有都行
# except和finally至少有一个

4.自定义异常

# 抛出异常:可以使用raise语句来抛出异常
# raise语句需要跟一个异常类会异常实例


def add(a,b):
    # 如果a和b中有负数 就向被调用处抛异常
    if a<0 or b<0:
        # raise用于向外部抛出异常  后边可以跟一个异常类 或异常类的实例
        raise Exception('两个参数 不能有负数')
    # 抛出异常的目的  告诉调用者指令调用时出现问题  希望你处理一下
    return a+b

# 也可以使用if-else-if语句代替异常的处理
sum=add(123,456)
print(sum)

# 也可以自定义异常类  就是创建一个类继承于异常类即可
class  A(Exception):
    pass
def sux(a,b):
    if a<0  or b<0:
        raise A
    else:
        print(a+b)
sux(-12,-1)

5.文件

# 文件(File) i/o



# 操作文件的步骤:1.打开文件  2.对文件进行各种操作(读写)  3.保存  4.关闭文件


# 1.打开文件

# 创建文件

# 使用open()函数来打开文件
file_name='demo'
file_test=open(file_name)
# 参数:file:要打开文件的名字
# 返回值:返回一个对象  这个对象就是代表了当前打开的文件
print(file_test)
# 如果目标文件和当前文件在同一个目录下 则写文件名即可

# 如果不在同一级目录  则写全路径即可
file_hello='hello/demo'
file_obj=open(file_hello)
print(file_obj)
# 在window系统使用路径时 可以使用/来代替
# 表示路径时  可以使用..来返回上一级目录

# 如果目标文件距离当前文件比较远  此时可以使用绝对路径  绝对路径从磁盘的根目录开始书写
file_abs='F:\Work\Python\Python\刷课.txt'
file_io=open(file_abs)
print(file_io)

6.文件关闭

# 打开文件

file_name='demo'

# 调用open()来打开文件
file_obj=open(file_name)

# 读取文件中内容  当我们获取到文件对象之后  所有的对文件的操作都应该通过对象来进行
# 读取文件中的内容
try :
    content = file_obj.read()  # read()用来读取文本中的内容  内容定义一个值来接收
    print(content)
except TypeError:
    print("出现异常了~")
except Exception:
    print("收集所有的异常!")


# 关闭文件:
file_obj.close()#关闭文件

# with...as语句
# 在with语句中可以直接使用file_obj拉埃做文件操作
#
with open(file_name) as file_obj:
    print(file_obj.read())#调用这个一次性读取

7.文件读取

#
file_name='demo'
try:
    with open(file_name,encoding='utf-8') as file_obj:
        # 一种:是纯文本文件  (使用utf-8来编写的文本文件)
        # 一种:是二进制文件(图片  视频 ppt等)
        # 通过read()来读取文件中的内容
        # open()打开文件  默认是以纯文本文件打开的  但是open()默认的编码为None
        # 所以处理文本文件时  必须要指定文件的编码
        content=file_obj.read()
        print(content)#调用open()来打开文件里面的内容
        pass
except Exception:
    print("不存在文件!")

8.读取大文件

#
file_name='demo'
try:
    with open(file_name,encoding='utf-8') as file_obj:
        # 一种:是纯文本文件  (使用utf-8来编写的文本文件)
        # 一种:是二进制文件(图片  视频 ppt等)
        # 通过read()来读取文件中的内容
        # open()打开文件  默认是以纯文本文件打开的  但是open()默认的编码为None
        # 所以处理文本文件时  必须要指定文件的编码
        # 注意:使用read()读取大文件  会把所有的内容全部读取出来
        # 如果要读取的文件较大的话  会一次性将文件的内容加载到内容中 任意导致内存泄漏
        # 所以对于较大的文件不要直接调用read()
        content=file_obj.read(6)#指定参数  每一次读取6个字符
        #read()可以接收一个size作为参数  该参数用来指定要读取的字符的数量 默认值为-1
        # content=file_obj.read(6)
        # 每次读取都是从上一次读取到的位置开始读取的
        # 如果字符数量小于size 则会读取剩下所有的
        # 如果读取到文件的最后了  则会返回空串
        # 它会读取文件中的所有字符
        print(len(content))
        print(content)#调用open()来打开文件里面的内容
        pass
except Exception:
    print("不存在文件!")



#读取大文件的方式:
try:
    with open(file_name,encoding='utf-8') as file_obj:
        # 定义一个变量  来指定每次读取的大小
        chunk=100
#         创建一个循环来读取文件内容
        while True:
            content=file_obj.read(chunk)
#             检查是否读取到了内容
            if not chunk:
#                 内容读取完毕
                break
            print(content,end='')

except FileExistsError:
    print("文件出现错误")

9.readline

# readline
file_name='demo'
with open(file_name,encoding='utf-8') as file_obj:
    print(file_obj.read())
    # redaline() 每次调用读取一行
    print(file_obj.readline())
#     readlines()该方法也是一行一行的读取内容  一次性将读取的内容封装到一个列表中返回
    try:
        r=file_obj.readlines()
        print(r[1])
    except Exception:
        print("抛出一个异常!")

10.文件写入

# 文件写入
file_name='demo'

# 使用open()打开文件时 必须指定打开文件所需要做的操作(度  写  追加)  如果不指定操作类型  默认是读取文件
# 而读取文件是不能向文件中写入的
# r表示只读的
# w表示是可写的
with open(file_name,'w',encoding='utf-8') as file_obj:
    # write()来先文件中写入内容
# 如果操作的是一个文本文件的话  则write()需要传递一个字符串作为参数
    file_obj.write('计算机  吴山居  吴山居')

# 读取文本
with open(file_name,'r',encoding='utf-8') as file_obj:
    content=file_obj.read()
    print(content)
    # a表示追加内容  如果文件不存在会创建群文件  如果文件存在则会向文件中追加内容
    # +为操作符追加功能
    # r+  不仅可读又可写 文件不存在会报错
    # w+ 
    x  用来新建文件

11.二进制文件

# 二进制文件:
#读取模式:
# t读取文本文件(默认值)
# b  读取二进制文件
# 读取文本文件时  是以字符为单位   读取二进制是以字节为单位
file_name='5.png'
with open(file_name,'rb')  as file_obj:
    print(file_obj.read(100))
    # 将读取到的内容写出来
    # 定义新的文件
    new_name='Pic.png'
    with open(new_name,'wb') as  new_obj:

        # 定义每次读取的大小
        chunk=1024*100#每次读取100k
        while True:

            content=file_obj.read(chunk)
        # 将读取到的数据写入到新对象中
        #     内容读取完毕  我们终止循环
            if not content:
                break
            new_obj.write(content)

12.读取文件的位置

file_name='demo'

with open(file_name,'rb') as file_obj:
    print(file_obj.read(1))


    # tell()方法用来查看当前读取的位置
    print("当前读取到了",file_obj.tell())
    # seek()可以修改读取的位置
    # 参数 第一个  是要切换的位置
    #     第二个  计算位置方式
                    # 可选值:0从头开始  
                    #           1 从当前位置开始
                    #           2  从最后位置开始

13.文件其他操作

# 文件的其他操作:
import os
from pprint import pprint

# os.listdir()获取当前目录的木结构
r=os.listdir('..')#获取指定目录的目录结构 需要一个路径作为参数 会获取到该路径下的目录结构 默认路径为 .当前目录
# 该方法会返回一个列表  目录中的每一个文件(夹) 的名字都是列表中的一个元素
print(r)


i=os.getcwd()#获取当前所在目录
print(i)

你可能感兴趣的:(python,开发语言)