python基础-个人笔记版

Python介绍:
  1. python3的所有常用语法
  2. 面向对象编程思想
  3. 运用模块进行编程
  4. 游戏编程
  5. 计算机仿真
  跨平台,C语言编写
idle常用快捷键
1. alt+n/p 上一条/下一条语句
2. ctrl+n 新建窗口 ctrl+s保存 F5运行
3. alt + 3 注释 alt + 4 取消注释
基础语法
  1. python 没有变量,只有名字
  2. 字符串 单引号 或 双引号,但必须成对
  
  3. 想打印单引号或者双引号,则用转义字符 反引号
  4. 原始字符串
    在字符串前加 r
    如果字符串末尾有\则会报错
    若需要显示末尾的\ 则拼上 “\”

  5. 长字符串:
    用三引号 “”“”“”即可打印
  
    综上,字符串 单引号,双引号,三引号
6. 条件判断

print("------------请输入数字:---------------")
temp = input()
guess = int(temp)
if guess == 8:
    print("猜中!")
else:
    if guess > 8:
        print("大了")
    else:
        print("小了")
print("game over")
  1. 循环
print("------------猜数字:---------------")
temp = input("------------请输入数字:---------------\n")
guess = int(temp)
while guess != 8:
    temp = input("输入错误,请重新输入:")
    guess = int(temp)
    if guess == 8:
        print("猜中!")
    else:
        if guess > 8:
            print("大了")
        else:
            print("小了")
print("game over")

  1. random模块
import random
secret = random.randint(1,10)
print("------------猜数字:---------------")
temp = input("------------请输入数字:---------------\n")
guess = int(temp)
while guess != secret:
    temp = input("输入错误,请重新输入:")
    guess = int(temp)
    if guess == secret:
        print("猜中!")
    else:
        if guess > secret:
            print("大了")
        else:
            print("小了")
print("game over")
  1. 条件判断
print("判断分数级别:A,B,C,D,E")
score = int(input("请输入分数:"))
if 100 >= score >= 90:
    print("A")
elif 90 > score >= 80:
    print("B")
elif 80 > score >= 70:
    print("C")
elif 70 > score >= 60:
    print("D")
elif 60 > score >= 0:
    print("E")
else:
    print("输入错误!")
  1. assert断言
    assert这个关键字我们称之为“断言”,当这个关键字后边的条件为假时候,程序自动崩溃并抛出AssertionError的异常。
    举个例子:
    assert 3 > 4

一般来说我们可以用Ta在程序中置入检查点,当需要确保程序中某个条件一定为真才能让程序正常工作的话,assert关键字非常有用
11.for循环

for循环语法:
	for 目标 in 表达式:
		循环体


end:结果
	favourite = "fish"
	for i in favourite:
		print(i,end=" ")
	#加 end打印在一行 不加每个元素会自动换行

len:长度
	member = ["赵信", "貂蝉", "吕布", "小乔", "大桥"]
	for each in member:
		print(each, len(each))
favourite = "fish"
for i in favourite:
    print(i,end=" ")
#加 end打印在一行 不加每个元素会自动换行

member = ["赵信", "貂蝉", "吕布", "小乔", "大桥"]
for each in member:
    print(each, len(each))
  1. range
range([start,] stop[, step=1])  []表示可选 step=1默认是1 包前不包后

1个参数:
	range(5) -> range(0, 5)
	list(range(5)) -> [0,1,2,3,4]

2个参数:
	range(2,9) -> 2 3 4 5 6 7 8

3个参数:
	list(range(1,10,3)) -> [1, 4, 7]
	
	for num in range(1,10,3):
		print(num, end=" ")
		#1 4 7
  1. break-continue
    break:终止循环、终止条件语句并跳出当前条件或循环
    continue:继续 continue跳出不执行下边代码 继续从外执行
binge = "你好"
answer = input("请输入刚才说的话:")

while True:
    if answer == binge:
        break
    answer = input("抱歉,错了,请重新输入:")

print("正确,结束")
#打印奇数-continue跳出条件不执行下边代码 继续执行for循环
for i in range(10):
    if i%2 != 0:
        print(i)
        continue
    i +=2
    print(i)

  1. 列表、数组
    列表:数组{大仓库,通过栈实现的}
    	整数 浮点数 字符串 对象
    	
    	普通列表:
    		member = ["吕布","貂蝉","小乔"]
    		number = [1,2,3,4,5]
    	混合列表:
    		mix = [1,"吕布", 3.14, [1,2,3,4,5]]
    	空列表:
    		empty = []
    	
    向列表添加元素:
    	添加一个元素:.append()
    		member.append("大乔")
    		len(member)
    	添加扩展列表元素(1个参数:列表):.extend([]) 
    		member.extend(["刘备","张飞"])
    	在第一个位置插入元素:
    		member.insert(0,"孙悟空")

    获取元素:
    	获取第一个元素:
    		member[0]
    	获取列表的部分列表:
    		member[1:3]
    		member[:]#获取列表的拷贝
    		member[1:]
    		member[:3]
    		
    删除:
    	删除指定元素:
    		member.remove("孙悟空")
    	删除列表:(del语句)
    		del(member)
    	取出最后一个元素:
    		member.pop()
    	取出指定元素:
    		member.pop(1)


    常用操作符:
    	list1 = [123]
    	list2 = [234]
    	list1 > list2 ->False
    	
    	list3 = list1 + list2 -> 相当于.extend()
    	list1 = [123,234]
    	(list1 < list2) and (list1 == list3)
    	
    	list3 *= 5
    	
    	判断元素是否在列表:
    		123 in list3
    		"你好" not in list3
    		123 not in list3
    		--
    		list5 = [123,[1,2,3,"吕布"], 234]
    		“吕布” in list5  -> False
    		“吕布” in list5[1]  -> True
    		list5[1][3] -> "吕布"
    		
    	内置函数:dir(list)#列出所有方法
    		.count()
    			list3.count(123)#某个元素出现的次数
    		.index()
    			list3.index(123)#出现的第一个位置
    			list3.index(123, 3, 7)#起始和结束位置内
    		.reverse()
    			list3.reverse()#元素倒序
    		.sort(func, key,reverse=False)#默认归并排序fun,key不用管
    			list3.sort()#升序排序
    			list3.sort(reverse = True)#降序


    拷贝 则是拷贝一份 list4 = list3[:]
    赋值 则会根据原有变化而变化  list 5 = list3

    如果list3变化,则list5跟着变,而list4不变
member = ["吕布","貂蝉","小乔"]
number = [1,2,3,4,5]
mix = [1,"吕布", 3.14, [1,2,3,4,5]]
empty = []
member.append("大乔")
member.extend(["刘备","张飞"])
member.insert(0,"孙悟空")
#数据交换
temp = member[0]
member[0] = member[1]
member[1] = temp
#删除指定元素
member.remove("孙悟空")
#删除列表 del(member)
#取出最后/指定位置元素 .pop(2)
member.pop()
#获取列表的拷贝/可以是某个区间
member[1:5]
#常用操作符
list1 = [123]
list2 = [234]
list3 = list1 + list2
list3 *= 5
list3.count(123)#某个元素出现的次数
list3.index(123)#出现的第一个位置
list3.index(123, 3, 7)#起始和结束位置内
list3.reverse()#元素倒序
list3.sort()#升序排序
list3.sort(reverse = True)#降序
  1. 元组
元组:和列表是近亲关系(权力)
	元组逗号是标志
	元组不可修改

		创建和访问一个元素(大部分用小括号):
			tuple1 = (1,2,3,4,5,8,4,6,2)
			tuple1[1]#可以获取指定元素
			tuple2 = tuple1[:]#可以拷贝
			
			
			元组逗号是标志:
				temp = 2,3,4
				type(temp)#获取类型 <class 'tuple'>
				temp = ()#创建一个空元组
				temp1 = (1)
				type(temp1)#<class 'int'>
				temp2 = (1,)
				type(temp2)#<class 'tuple'>
				8 * (3,)#*重复操作符 (3, 3, 3, 3, 3, 3, 3, 3)
				
		更新和删除元素:
			元组不可修改:
				tuple1[1] = 3#不可以赋值
			不可删除:
				tuple1.del()#SyntaxError: invalid syntax
		
		常用操作符:
			更新元组:
				tuple1 = tuple1[:3] + (8,) + tuple1[3:]#更新元组
				tuple1 = tuple1[:3] + tuple1[4:]#删除
				tuple1原来的数据会被覆盖最终被python垃圾回收
				
			拼接
				+  
			重复操作符
				* 
			关系操作符:
				> < >= <=  
			逻辑操作符:
				and or
			成员操作符:
				in  not in
tuple1 = (1,2,3,4,5,8,4,6,2)#创建和访问一个元素(大部分用小括号)
tuple1[1]#可以获取指定元素
tuple2 = tuple1[:]#可以拷贝
#元组不可以被修改 tuple1[1] = 3
temp = 2,3,4
type(temp)#获取类型
temp = ()#创建一个空元组
temp1 = (1)
type(temp1)#<class 'int'>
temp2 = (1,)
type(temp2)#<class 'tuple'>
8 * (3,)#*重复操作符
tuple1 = tuple1[:3] + (8,) + tuple1[3:]#更新元组
  1. 字符串方法
字符串:
	字符串更改:
		和元组类似 不可修改,需要修改则通过字符串拼接
	
	
	
	字符串方法:[]表可选
		.capitalize()#把字符串第一个字符改为大写
		.casefold()#把字符串所有字符变为小写
		.center(width)#字符串居中 两边填充width宽度width>len(str3)才生效从左边补充1右边补充1左边补充2个右边补充2个
		.count(sub[start[,end]])#返回sub字符串里边出现的次数,参数表示范围
		.encode(encoding='utf-8', errors='strict')#以encoding指定的编码格式对字符串进行编码
		.endswith(sub[,start[,end]])#检查是否是sub字符串结束的 True/False
		.expandtabs([tabsize=8])#把tab符号(\t)转为空格,默认8
		.find(sub[,start[,end]])#检索sub是否包含在字符串中,返回检索位置,检索不到返 -1 rfind()
		.index(sub[,start[,end]])#和find一样,不过如果sub不在String中会产生一个异常
		.isainum()#如果字符串至少有一个字符并且所有字符都是字母或数字则返回True,否则False
		.isalpha()#如果字符串至少有一个字符并且所有字符都是字母则返回True,否则返回False
		.isdecimal()#如果字符串只包含十进制数字则返回True,否则返回False
		.isdigit()#如果字符串只包含数字则返回True,否则返回False
		.islower()#如果字符串中至少包含一个区分大小写的字符,并且这些字符都是小写,则返回True
		.isnumeric()#如果字符串中只包含数字字符,则返回True
		.isspace()#如果字符串中只包含空格,则返回True
		.istitle()#如果字符串是标题话(所有单次都是以大写开始,其余字母均是小写则返回True
		.isupper()#如果字符串中至少包含一个区分大小写的字符,并且这些字符都是大写,则返回True
		.join(sub)#以字符串作为分隔符,插入到sub中所有的字符之间
		.ljust(width)#返回一个左对齐的字符串并使用空格填充至长度为width的新字符串
		.lower()#转换字符串中所有大写字符为小写 upper()
		.lstrip()#去掉字符串中左边所有空格 rstrip()
		.partition(sub)#找到字符串sub,把字符串分成一个3元组(pre,sub,sub,fol_sub),如uo字符串中不包含sub则返回(‘源字符串’,'','')
		.replace(old,new[,count])#把字符串中的old字符串替换为new字符串,如果count指定,则替换不超过count
		.rfind()#从右边查找
		.rindex()#从右边index
		.rjust(width)#返回一个右对齐字符串
		.rpartition()#从右边开始查找
		.rstrip()#删除字符串末尾空格
		.split(sep=None, maxspit=1)#不带参数默认是以空格为分隔符切片字符串,如果maxsplit参数有设置,则进分割maxsplit个字符串,返回切片后的子字符串拼接的列表
		.splitlines([keepends])#按照‘\n'分隔,返回一个包含各行作为元素的列表,如果keepends参数指定,则返回前keepends行
		.startswith(prefix[,start[,end]])#检索字符串是否以prefix开头,是返回True 
		.strip([chars])#删除字符串前边和后边所有空格,chars参数可以定制删除的字符,可选
		.swapcase()#反转字符串中的大小写
		.title()#返回标题化(所有的单次都是以大写开始,其余字母的小写)的字符串
		.translate(table)#根据table的规则(可以由str.maketrans('a','b')定制)转换字符串中的字符
		.upper()#转换字符串中所有小写为大写
		.zfill(width)#返回长度为width的字符串,原字符串右对齐,前边用0填充
str1 = "I love py"
str1[:6]
str1[6]#找到单个字符
str1 = str1[:6] + " java and" + str1[6:]
#字符串方法
str2 = "HELLO love"
str2 = str2.capitalize()#把字符串第一个字符改为大写
str3 = str2.casefold()#把字符串所有字符变为小写
str4 = str3.center(12)#字符串居中 两边填充width宽度width>len(str3)才生效从左边补充1右边补充1左边补充2个右边补充2个
temp = str4.count(" ", 1, 5)#count(sub(start[,end]))#返回sub字符串里边出现的次数,参数表示范围
str4.encode(encoding='utf-8', errors='strict')#以encoding指定的编码格式对字符串进行编码
temp1 = str4.endswith(" ", 5) #(sub[,start[,end]])#检查是否是sub字符串结束的 True/False
str5 = str3 + "	" + "end"#带tab符号的字符串
str6 = str5.expandtabs()#把tab符号(\t)转为空格,默认8
temp2 = str3.find("l")#(sub[,start[,end]])#检索sub是否包含在字符串中,返回检索位置
str3.index("l")#(sub[,start[,end]])#和find一样,不过如果sub不在String中会产生一个异常
temp3 = str3.isalnum()#如果字符串至少有一个字符并且所有字符都是字母或数字则返回True,否则False
str4.isalpha()#如果字符串至少有一个字符并且所有字符都是字母则返回True,否则返回False
str4.isdecimal()#如果字符串只包含十进制数字则返回True,否则返回False
str4.isdigit()#如果字符串只包含数字则返回True,否则返回False
str4.islower()#如果字符串中至少包含一个区分大小写的字符,并且这些字符都是小写,则返回True
str4.isnumeric()#如果字符串中只包含数字字符,则返回True
str4.isspace()#如果字符串中只包含空格,则返回True
str3.istitle()#如果字符串是标题话(所有单次都是以大写开始,其余字母均是小写则返回True
str3.isupper()#如果字符串中至少包含一个区分大小写的字符,并且这些字符都是大写,则返回True
str4.join("12345")#以字符串作为分隔符,插入到sub中所有的字符之间
str3.ljust(20)#返回一个左对齐的字符串并使用空格填充至长度为width的新字符串
str3.lower()#转换字符串中所有大写字符为小写 upper()
str3.lstrip()#去掉字符串中左边所有空格 rstrip()
str3.partition("o")#(sub)找到字符串sub,把字符串分成一个3元组(pre,sub,sub,fol_sub),如uo字符串中不包含sub则返回(‘源字符串’,'','')
str3.replace("o","e",1)#(old,new[,count])#把字符串中的old字符串替换为new字符串,如果count指定,则替换不超过count
#
#
str3.split("o",maxsplit = 0)#不带参数默认是以空格为分隔符切片字符串,如果maxsplit参数有设置,则进分割maxsplit个字符串,返回切片后的子字符串拼接的列表
str3.splitlines(keepends=1)
str3.strip("e")#删除字符串前边和后边所有空格,chars参数可以定制删除的字符,可选
str3.swapcase()#反转字符串中的大小写
str3.title()#返回标题化(所有的单次都是以大写开始,其余字母的小写)的字符串
str3.zfill(20)#返回长度为width的字符串,原字符串右对齐,前边用0填充
str3.translate(str.maketrans('o','e'))#根据table的规则(可以由str.maketrans('a','b')定制)转换字符串中的字符

17.字符串格式化

字符串格式化;
	未知参数:
		str1 = "{} love {}.{}".format("I","baidu","com")
	指定参数:
		str2 = "{a} love {b}.{c}".format(a="I",b="baidu",c="com")
	格式化符号含义:
		%c 格式化字符及其ASCII码
		%s 格式化字符串
		%d 格式化整数
		%o 格式化无符号八进制数
		%x 格式化无符号十六进制数
		%X 格式化无符号十六进制数(大写)
		%f 格式化定点数,可指定小数点后的精度
		%e 用科学计数法格式化定点数
		%E 作用通%e,用科学计数法格式化定点数
		%g 根据值的大小决定使用%f或%e
		%G 作用通%g,根据指的大小决定使用%f或%e
	
	格式化参数 使用元组或字典
		"%c %c %c" %(97,98,99)
	
	格式化操作符辅助指令:
		m.n	m是显示的最小总宽度,n是小数点后的位数
		-	用于左对齐
		+	在正数签名显示加号(+)
		#	在八进制数签名显示零(‘ 0’ ),在十六进制数签名显示‘0x’或‘0X’
		0	显示的数字前面填充 '0'取代空格
		
	字符串转义:
		\'	单引号
		\"	双引号
		\a	发出系统响铃声
		\b	退格符
		\n	换行符
		\t	横向制表符(TAB)
		\v	纵向制表符
		\r	回车符
		\f	换页符
		\o	八进制代表的字符
		\x	十六进制代表的字符
		\0	表示一个空字符
		\\	反斜杠
str1 = "{} love {}.{}".format("I","baidu","com")
str2 = "{a} love {b}.{c}".format(a="I",b="baidu",c="com")
str3 = "{{a}}".format(a="you")#打印花括号
str4 = "{0:.1f}{1}".format(27.538,"08")#定点数即浮点数
#格式化符号含义:
"%c %c %c" %(97,98,99)#格式化字符及其ASCII码
#格式化操作符辅助指令:
"%5.2f" % 23.456 #整个字符串宽度为5,小数点后占2位
"%.2e" %23.456 #'2.35e+01'->23.5

  1. 三元操作符
x, y = 4, 5
if x < y:
    small = x
else:
    small = y
# 三元操作符 语法: x if 条件 else y
a, b = 8, 10
num = a if a < b else b
  1. 比较操作符
比较操作符:
	> < >= <= == !=
	
if 1==1:
	print()
else:
	print()

while 条件:
	true执行的语句

and 逻辑操作符
	可以将任意表达式连接一起,并得到一个布尔类型的值
	(3>2) and (1>2)
	-> false

随机数:random模块
	randint(),返回一个随机的整数
	导入模块 import random
	secret = random.randint(1,10)
  1. 数据类型
整形,统一只有一种
	长整形也一样

布尔,
	True 1
	False 0
	
	True + True = 2
	
	

浮点型,
	浮点数转为整形 会去除小数点后的数
	

e记法
	1.5e10  1.5E11
	e记法是浮点的科学计数法

类型转换:
	int()
	str()
	float()

str = "I love"
c = str(5e19)//str已经是一个变量名 重新定义出错

内置函数 type()
	判断类型

判断类型是否类型一致 isinstance(a, str)
	a = "xiao"
	isinstance(a, str)
	-> True
	isinstance(a, int)
	-> False
	isinstance(a, float)



!!!基本类型 str, int, float, bool可以被变量覆盖,所以请谨慎操作

  1. 常用操作符
#常用操作符
print("操作符")
a = 5
a-=1
print(a)
a = b = c = d = 10
a+=1
print("a=" + str(a))
b-=2
print("b=" + str(b))
c*=2
print("c=",c)
d/=8
print("d=",d)
d=10
print("d//8=",d//8)
  1. 序列
序列!列表、元组、字符串的共同点
	1.都可以通过索引获取一个元素
	2. 默认索引值都是从0开始
	3. 可以通过分片的方法得到一个范围内的元素的集合
	4. 有很多共同的操作符(重复操作符、拼接操作符、成员关系操作符)
	
序列常见的内置方法:
	list()把一个可迭代对象转换为列表
	help(list)
	list()
	len()#返回长度
	max()#返回序列或者参数集合中的最大值
	min()#返回序列或者参数集合中的最小值
	sum(iterable[, start=0])返回序列iterable和可选参数start的总和
	sorted()#排序
	reversed()#返回迭代器对象,可以转为list再打印出来 反转的元素
	list(enumerate(tuple1))#枚举,生成带index的元组
	zip(a,b)#打包相同index在一起,返回对象
#help(list)
a = "I love java"
b = list(a)
print(b)
c = (1,2,3,4,5)#定义一个元组
d = list(c)
len(b)
max(1,2,3,4,5)#返回最大值,序列、列表、字符串必须一致
tuple1 = (2,3,1)
sum(tuple1,8)#(iterable[, start=0])#返回序列iterable和可选参数start的总和
list(enumerate(tuple1))#枚举,生成带index的元组
a = [1,2,3,4]
b = [4,5,6,7]
temp = list(zip(a,b))#打包相同index在一起
  1. 函数
函数 def
	创建函数:
		def MyFirstFunction():
			print("定义一个函数")
			print("结束")
	调用函数:
		MyFirstFunction()
		
	带多个参数用逗号隔开
	def MyFirstFunction(name):
		print("name = " + name)
		
	带返回值
	def MyFirstFunction(num1, num2):
		'计算两个数值的和'
		#print(num1 + num2)
		return num1 + num2
	
	形参:函数定义过程中的name,占据一个参数位置的形式
	实参:传递进去的值叫做实参,即具体的参数值 
	
	打印函数文档:help(MyFirstFunction)
	
	关键字参数:
		def SaySome(name, words):
			print(name + "->" + words)
		SaySome(words = "改变世界", name = "python")
	#收集参数,即多个参数,默认是把所有参数添加到元组中
		def test(*params):
			print("参数的长度是:", len(params))
			print("第二个参数:", params[1])
	#如果要扩展指定参数,则用关键字参数指定
		def test1(*params,exp):
			print("参数的长度是:", len(params),exp)
			print("第二个参数:", params[1])
		test1(1,2,3,4.5,exp = 8)
	print()函数就有收集参数

函数如果没有返回值,python返回none
	#返回值
	def hello():
		print("hello")
	>>> temp = hello()
	hello
	>>> temp
	>>> type(temp)
	<class 'NoneType'>

#变量作用域
#局部变量:函数内部,使用完之后栈会自动释放,所以在函数外是访问不到的
#成员变量:函数内部调用成员变量并修改,python会新建一个该名称的局部变量代替

global:
	可以把成原变量变为局部变量修改,反之、函数内修改不会导致成员变量值的变化
	count = 5
	def MyFun():
		global count
		count = 10
		print(count)
	MyFun()
	print(count)

#函数
def MyFirstFunction():
    print("定义一个函数")
    print("整个函数只有输出")
#函数调用
MyFirstFunction()
#带多个参数用逗号隔开
def MyFirstFunction(name):
    print("name = " + name)
#带返回值
def MyFirstFunctionAdd(num1, num2):
    '计算两个数字的和'
    #可以打印上述文档
    #print(num1 + num2)
    return num1 + num2
MyFirstFunctionAdd(1,2)
#打印函数文档,默认的特定属性 _doc_/help(函数名)
help(MyFirstFunctionAdd)
#关键字参数:即可以不是按照默认顺序入参
def SaySome(name, words):
    print(name + "->" + words)
SaySome(words = "改变世界", name = "python")
SaySome("java","change the world")
#收集参数,即多个参数,默认是把所有参数添加到元组中
def test(*params):
    print("参数的长度是:", len(params))
    print("第二个参数:", params[1])
#如果要扩展指定参数,则用关键字参数指定
def test1(*params,exp):
    print("参数的长度是:", len(params),exp)
    print("第二个参数:", params[1])
test1(1,2,3,4.5,exp = 8)
#返回值
def hello():
    print("hello")
#变量作用域
#局部变量:函数内部,使用完之后栈会自动释放,所以在函数外是访问不到的
#成员变量:函数内部调用成员变量并修改,python会新建一个该名称的局部变量代替,所以不要修改
#global:可以把成原变量变为局部变量修改,反之、函数内修改不会导致成员变量值的变化
count = 5
def MyFun():
    global count
    print(count)
MyFun()
print(count)

  1. 内嵌函数和闭包
#内嵌函数和闭包
def fun1():
    print("fun1()正在被调用")
    def fun2():
        print("fun2()正在被调用")
    fun2()
fun1()
#闭包:如果在一个内部函数里(Funy),对在外部作用域(Funx)的变量(x)进行引用,那么内部函数Funy()就是一个闭包
def Funx(x):
    def Funy(y):
        return x * y
    return Funy
#调用方式一
Funx(8)(5)
#调用方式二
temp = Funx(8)
temp(5)
#
def Fun1():
    x = 5
    def Fun2():
        nonlocal x
        x *= x
        return x
    return Fun2()
Fun1()
  1. lambda表达式
lambda表达式
	def ds(x):
		return 2 * x + 1
	#lambda语法 lambda 原函数的参数:原函数的返回值
	lambda x: 2 * x + 1
	
lambda表达式的使用:
	python写一些执行脚本,使用lambda可以省定义函数过程,不用专门定义一个函数再调用
	对于一些抽象并且整个过程执行下来只需要调用一两次的函数,使用lambda可以不用考虑命名的问题了
	简化代码的可读性

两个 BIF
	filter()#过滤器,保留关注的信息、筛选
		list(filter(lambda x:x % 2, range(100)))
		
	map()#映射
		list(map(lambda x:x*2, range(10)))
#lambda表达式
def ds(x):
    return 2 * x + 1
#lambda语法 lambda 原函数的参数:原函数的返回值--返回函数对象
g = lambda x: 2 * x + 1
g(2)
def add(x, y):
    return x + y
f = lambda x,y:x+y
f(2,2)
#filter()#过滤器,保留关注的信息、筛选
filter(None, [1,0,False, True,"a","b"])#默认把任何非True的内容过滤掉
#筛选出奇数

#def add(x):
#   return x % 2
add = lambda x:x%2
temp = range(10)
show = filter(add, temp)
#list(show) 第一次迭代所有 第二次迭代为空
#简化
print(list(filter(lambda x:x % 2, range(100))))
#map两个参数,对序列进行加工放到map中
a = list(map(lambda x:x*2, range(10)))
  1. 递归
递归:两个必要条件(1:调用函数自身,2:设置自身正确的返回值)//出来混要还的
	函数调用自身 py设置最高递归深度100层//消耗内存和时间 不断入栈出栈,必须要有正确的返回
	设置递归深度
		#import sys
		#sys.setrecursionlimit(1000)
		
	求阶乘的函数:
		#普通方式:
			def factorial(n):
				result = n
				for i in range(1, n):
					result *= i
				return result
			number = int(input("请输入一个整数:"))
			result = factorial(number)
			print("%d 的阶乘为:%d" % (number,result))
		#递归方式:
			def factorial(n):
				if n == 1:
					return 1#设置自身正确的返回值
				else:
					return n * factorial(n-1)#调用函数自身

			number = int(input("请输入一个整数:"))
			result = factorial(number)
			print("%d 的阶乘为:%d" % (number, result))
#递归:函数调用自身 py设置最高递归深度100层  ctrl+c强制退出
#设置递归深度
#import sys
#sys.setrecursionlimit(1000)
#求阶乘的函数
#def factorial(n):
#    result = n
#    for i in range(1, n):
#        result *= i
#    return result
#number = int(input("请输入一个整数:"))
#result = factorial(number)
#print("%d 的阶乘为:%d" % (number,result))

#递归求阶乘的函数
def factorial(n):
    if n == 1:
        return 1#设置自身正确的返回值
    else:
        return n * factorial(n-1)#调用函数自身

number = int(input("请输入一个整数:"))
result = factorial(number)
print("%d 的阶乘为:%d" % (number, result))
  1. 递归-斐波那契数列
递归例子:斐波那契数列的迭代实现
	第一个月是1,第二个月是1,第三个月是前两个月的和
	
		所经过的月数:1	2	3	4	5	6	7	8	9	10	11	12
		兔子的总对数:1	1	2	3	5	8	13	21	34	55	89	144	
		相除越来越接近黄金分割:0.618
	
	数学函数定义:
				1, 当 n = 1

		F(n)	1, 当 n = 2
				
				F(n-1) + F(n-2), 当 n > 2
			
	迭代VS递归:
		迭代:
			def fab(n):
				n1 = 1
				n2 = 1
				n3 = 1

				if n < 1:
					print("输入有误!")

				while(n-2 > 0):
					n3 = n2 + n1
					n1 = n2
					n2 = n3
					n -= 1

				return n3

			result = fab(20)
			if result != -1:
				print("共有 %d 对小兔子诞生!" % result)
		
		递归:分治思想
			def fab1(n):
				if n < 1:
					print("输入有误!")

				if n == 1 or n == 2:
					return 1
				else:
					return fab1(n-1) + fab1(n-2)
			print(fab1(20))
		
#斐波那契数列的迭代实现
def fab(n):
    n1 = 1
    n2 = 1
    n3 = 1

    if n < 1:
        print("输入有误!")

    while(n-2 > 0):
        n3 = n2 + n1
        n1 = n2
        n2 = n3
        n -= 1

    return n3

result = fab(20)
if result != -1:
    print("共有 %d 对小兔子诞生!" % result)
        
#递归
def fab1(n):
    if n < 1:
        print("输入有误!")

    if n == 1 or n == 2:
        return 1
    else:
        return fab1(n-1) + fab1(n-2)
print(fab1(20))
  1. 递归-汉诺塔
递归:汉诺塔
	-- 解决一个问题需要有耐心 还要有思路
	--题目:
		简单理解为三个步骤:
		- 将前63个盘子从X移动到Y上
		- 将最底下的第64个盘子从X移动到Z上
		- 将Y上的63个盘子移动到Z上
		
		问题一:将X上的63个盘子借助Z移到Y上;
		问题二:将Y上的63个盘子借助X移动到Z上。
		
		问题一拆解:
			-将前62个盘子从X移动到Z上。
			-将最底下的第63个盘子移动到Y上。
			-将Z上的62个盘子移动到Y上。
		问题二拆解:
			-将前62个盘子从Y上移动到X上。
			-将最底下的第63个盘子移动到Z上。
			-将X上的62个盘子移动到Y上
	
	递归实现:
		def hanoi(n, x, y, z):
			if n == 1:
				print(x, '--->', z)
			else:
				hanoi(n-1, x, z, y)# 将前n-1个盘子从x移动到y上
				print(x, '--->', z)# 将最底下的最后一个盘子从x移动到z上
				hanoi(n-1, y, x, z)# 将y上的n-1个盘子移动到z上
#递归——汉诺塔
def hanoi(n, x, y, z):
    if n == 1:
        print(x, '--->', z)
    else:
        hanoi(n-1, x, z, y)# 将前n-1个盘子从x移动到y上
        print(x, '--->', z)# 将最底下的最后一个盘子从x移动到z上
        hanoi(n-1, y, x, z)# 将y上的n-1个盘子移动到z上
n = int(input("请输入层数:"))
hanoi(n, "x", "y", "z")
  1. 字典
字典:{}大括号表示字段,不是数据类型,是映射类型
	{key:value, key:value}

	#创建一个字典
		dict1 = {'1':'one', '2':'two', '3':'three', '6':'six'}
	#获取
		print('2的值是:', dict1['2'])
		print(dict1['2'])
	#创建空字典
		dict2={}
	
字典的内置方法:
	
	#查看方法
		help(dict)
	#一个参数用元组来创建字典
		dict3 = dict((('f', 70), ('i',105),('s',115),('c',67)))
	#创建字典
		dict4 = dict(小陈 = '天道酬勤', 小小 = '飞的更高')
		dict4['小小'] = '美丽动人'
		dict4['爱迪生'] = '天才99%,灵感1%'
	
	创建字段方式2:
		fromkeys((key,key,key),参数)
		
	遍历获取key和value:
		dict2.keys()
		dict2.values()
	获取每一组:
		dict2.items()
#创建一个字典
dict1 = {'1':'one', '2':'two', '3':'three', '6':'six'}
#获取
print('2的值是:', dict1['2'])
print(dict1['2'])
#创建空字典
dict2={}
#查看方法
help(dict)
#一个参数用元组来创建字典
dict3 = dict((('f', 70), ('i',105),('s',115),('c',67)))
#创建字典
dict4 = dict(小陈 = '天道酬勤', 小小 = '飞的更高')
dict4['小小'] = '美丽动人'
dict4['爱迪生'] = '天才99%,灵感1%'

#创建字典没有参数默认查询 fromkeys得到None
dict1 = {}
dict1.fromkeys((1,2,3))
#修改值
dict1.fromkeys((1,2,3),'number')
#只有一个参数
dict1.fromkeys((1,2,3),('one', 'two', 'three'))
#试图修改,而是创建了新的
dict1.fromkeys((1,3),'shuzi')
#初始化赋值
dict1 = dict1.fromkeys((1,2,3),'number')
dict2 = dict1.fromkeys(range(32),'赞')
#获取key
for eachkey in dict2.keys():
    print(eachkey)
#获取value
for eachValue in dict2.values():
    print(eachValue)
#获取每一组 item
for eachItem in dict2.items():
    print(eachItem)

#索引字典中没有的key则会报错 keyError
#print(dict2[32])

#用get方法获取,没有则返回None
print(dict2.get(32))
#可以设置提示,没有提示没有,有则显示
print(dict2.get(32,'没有!'))
print(dict2.get(31,'没有!'))

#检查键是否有 in\not in #在序列中检查的是值是否存在而不是索引值
print(32 in dict2)

#清空字段 clear()
dict2.clear()
#另一种方式存在隐患
a = {"姓名":"小陈"}
b = a
a = {}
print("a = ", a)
print("b = ", b)
c = {"姓名":"小陈"}
d = c
c.clear()
print("c.clear()之后:d = ", d)

#赋值 不等于 全拷贝

a = {1:'one', 2:'two'}
b = a.copy()
c = a
print("id(a) = ", id(a))#2381226472064
print("id(b) = ", id(b))#2381226638080
print("id(c) = ", id(c))#2381226472064
#全拷贝 是创建一个新的对象
#赋值 是指向 如果 c 中新增元素 a会被影响到,而全拷贝的b则不会
c[4] = 'four'
print("a = ", a)
print("b = ", b)
print("c = ", c)

#pop()#弹出键对应的值
print("a", a)
print("a.pop(2) = ", a.pop(2))
print("a", a)
#popitem()#随机弹出,字典中没有顺序
print("b", b)
print("b.pop(2) = ", b.pop(2))
print("b", b)

#setdefault(),添加没有key则创建
a.setdefault('小白')
print("a.setdefault('小白')", a)
a.setdefault(5, 'five')
print("a.setdefault(5, 'five')", a)

#update()修改某个键值对
a.update({'小白':'魅者'})
print("a.update(('小白','魅者'))", a)

  1. 集合
集合:集合里的元素都是唯一的,无序的 set,因此没有索引
	创建方式一:
		num1 = {2,1,5,2,3,6,6}
		print("type(num1)",type(num1))
		print("num1 = ",num1)

	创建方式二:
		num2 = set([1,2,3,4,5,6,6])
		print("num2 = ", num2)

	去重方式一:
		temp = []
		for each in num1:
			if each not in temp:
				temp.append(each)

		print("temp= ", temp)
	去重方式二:
		num3 = list(set(num1))num1放集合中去重转为list输出打印
		print("num3 = ", num3)

	in/not in判断集合中是否存在该元素
		boo = 1 in num3
		print("boo = ", boo)
	
集合的内置方法:
	.add() 向集合中添加元素
	.remove() 移除集合中某个元素
	.frozenset() 定义一个不可变集合#冻结,冰冻 frozen
#集合 集合里的元素都是唯一的,无序的 set 去重!
#创建方式一:
num1 = {2,1,5,2,3,6,6}
print("type(num1)",type(num1))
print("num1 = ",num1)

#创建方式二:
num2 = set([1,2,3,4,5,6,6])
print("num2 = ", num2)

#去重方式一:
temp = []
for each in num1:
    if each not in temp:
        temp.append(each)

print("temp= ", temp)
#去重方式二:
num3 = list(set(num1))#num1放集合中去重转为list输出打印
print("num3 = ", num3)

#in/not in判断集合中是否存在该元素
boo = 1 in num3
print("boo = ", boo)

#add()/remove()
num1.add(6)
print("num1.add(6)->", num1)
num1.remove(5)
print("num1.remove(5)->", num1)

#冻结,冰冻 frozen
#定义一个不可变集合
num4 = frozenset([1,2,3,4,5])
#num4.add(6)#AttributeError: 'frozenset' object has no attribute 'add'
  1. 文件
文件:
	打开文件:
	
	打开模式	执行操作
		'r'		以只读方式打开文件(默认)
		'w'		以写入方式打开文件,会覆盖已存在的文件
		'x'		如果文件已经存在,使用此模式打开将引发异常
		'a'		以写入模式打开,如果文件存在,则在末尾追加写入
		'b'		以二进制模式打开文件
		't'		以文本模式打开(默认)
		'+'		可读写模式(可添加到其他模式中使用)
		'U'		通用换行符支持
		
参数:
	第一个 file:传文件名,如果没有传路径默认当前文件夹
	第二个 mode='r':打开模式 
	其他默认

文件对象的方法:
	文件对象方法		执行操作
	f.close()			关闭文件
	f.read(size=-1)		从文件读取size个字符,当为给定size或给定负值的时候,读取剩余的所有字符,然后作为字符串返回
	f.readline()			以写入模式打开,如果文件存在,则在末尾追加写入
	f.writer(str)		将字符串str写入文件
	f.writelines(seq)		向文件写入字符串序列seq,seq应该是一个返回字符串的可迭代对象
	f.seek(offset, from)	在文件中移动文件指针,从from(0代表文件起始位置,1代表当前位置,2代表文件末尾)便宜offset个字节
	f.tell()				返回当前在文件夹中的位置

使用完文件记得要关闭

		读取文件内容
			f.read()
		读取指定字符数
			f.read(5)
		指针位置
			f.tell()
		移动文件指针
			f.seek(45,0)
		读取一行内容
			f.readline()
		把文件转为list
			lines = list(f)
		打印文件内容方式一(效率较低):转为list打印
			for each_line in lines:
				print(each_line)

		打印文件内容方式二(推荐):直接用for打印文件对象
			f.seek(0,0)
			for each_line in f:
				print(each_line)


		文件的写入,需要有'w'或者'a' 打开方式,w会覆盖,a则是追加
			f = open('E:\\DE\\Recent\\hy\\worklog\\学习\\python\\11-文件\\hello.txt', 'w')
		写入,并返回写入字符的个数
			f.write('I love you A')
		写入完,f.close()才可以从缓冲区到磁盘保存,或者f.tell()
			f.close()
		打开文件,并追加内容
			f = open('E:\\DE\\Recent\\hy\\worklog\\学习\\python\\11-文件\\hello.txt', 'a')
			f.write("\nwhat about you?")
			f.close()
#文件练习
#任务:将文件(record.txt)中的数据进行分割并按照一下规律保存起来:
#	-小陈的对话单独保存为boy_*.txt的文件(去掉“小陈:”)
#	-小客服的对话单独保存为girl_*.txt的文件(去掉“小客服:”)
#	-文件中总共有三段对话,分别保存为boy_1.txt,girl_1.txt,boy_2.txt,
#	girl_2.txt,boy_3.txt,girl_3.txt共6个文件(提示:文件中不通的对话已经使用“===========”分割)

#实现方式一
f = open("record.txt",encoding="utf8")

boy = []
girl = []
count = 1

for each_line in f:
    if each_line[:6] != "======":
        #是字符串,进行文件分割
        (role, line_spoken) = each_line.split(":",1)
        if role == "小陈":
            boy.append(line_spoken)
        if role == "小客服":
            girl.append(line_spoken)
    else:
        #不是字符串,进行文件拆分
        file_name_boy = "boy_" + str(count) + ".txt"
        file_name_girl = "girl_" + str(count) + ".txt"
        #以写入模式打开文件
        boy_file = open(file_name_boy, 'w')
        girl_file = open(file_name_girl, 'w')

        #把列表写入文件
        boy_file.writelines(boy)
        girl_file.writelines(girl)

        #写入完毕 关闭
        boy_file.close()
        girl_file.close()

        boy = []
        girl = []
        count += 1

#不是字符串,进行文件拆分
file_name_boy = "boy_" + str(count) + ".txt"
file_name_girl = "girl_" + str(count) + ".txt"
#以写入模式打开文件
boy_file = open(file_name_boy, 'w')
girl_file = open(file_name_girl, 'w')

#把列表写入文件
boy_file.writelines(boy)
girl_file.writelines(girl)
#写入完毕 关闭
boy_file.close()
girl_file.close()

f.close()

#实现方式二,封装函数


def save_file(boy,girl,count):
    file_name_boy = "boy_" + str(count) + ".txt"
    file_name_girl = "girl_" + str(count) + ".txt"
    
    boy_file = open(file_name_boy, 'w')
    girl_file = open(file_name_girl, 'w')

    boy_file.writelines(boy)
    girl_file.writelines(girl)
    
    boy_file.close()
    girl_file.close()
    
def split_file(file_name):
    
    f = open(file_name, encoding='utf8')

    boy = []
    girl = []
    count = 1

    for each_line in f:
        if each_line[:6] != "======":
            #是字符串,进行文件分割
            (role, line_spoken) = each_line.split(":",1)
            if role == "小陈":
                boy.append(line_spoken)
            if role == "小客服":
                girl.append(line_spoken)
        else:
            save_file(boy, girl, count)
            
            boy = []
            girl = []
            count += 1
    save_file(boy, girl, count)

    f.close()

split_file("record.txt")
  1. os模块
模块:可用代码块的打包 后缀.py
	python跨平台,同样的源代码可以在不同的操作系统实现
	因此,python有了OS模块,不需要关心什么操作系统下使用什么模块,
	OS模块会帮你选择正确的模块并调用

import os#导入os模块调用os的方法
OS模块中关于文件/目录常用的函数使用方法
	函数名				使用方法
	getcwd()			返回当前工作目录
	chdir(path)			改变工作目录
	listdir(path='.')	列举指定目录中的文件名('.'表示当前目录,'..'表示上一级目录)
	mkdir(path)			创建单层目录,如该目录已存在抛出异常
	makedirs(path)		递归创建多层目录,如该目录已存在抛出异常,注意:'E:\\a\\b'和'E:\\a\\c'并不会冲突
	remove(path)		删除文件
	rmdir(path)			删除单层目录,如该目录非空则抛出异常
	removedirs(path)	递归删除目录,从子目录到父目录逐层尝试删除,遇到目录非空则抛出异常
	rename(old, new)	将文件old重命名为new
	system(command)		运行系统的shell命令
		支持路径操作中常用的一些定义不是函数,支持所有平台
	os.curdir			指代当前目录('.')
	os.pardir			指代上一级目录('..')
	os.sep				输出操作系统特定的路径分隔符(Win下为'\\',Linux下为'/')
	os.linesep			当前平台使用的行终止符(Win下为'\r\n',Linux下为'\n')
	os.name				指代当前使用的操作系统(包括:'posix','nt','mac','os2','ce','java')



os.path模块中关于路径常用的函数使用方法
	函数名						使用方法
	basename(path)				去掉目录路径,单独返回文件名
	dirname(path)				去掉文件名,单独返回目录路径
	join(path1[,path2[],...])	将path1,path2各部分组合成一个路径名
	split(path)					分割文件名与路径,返回(f_path,f_name)元组,如果完全使用目录,它也会将最后一个目录作为文件名分离,且不会判断文件或目录是否存在
	splitext(path)				分离文件名与扩展名,返回(f_name,f_extension)元组
	getsize(file)				返回指定文件的尺寸,单位是字节
	getatime(file)				返回指定文件最近的访问时间(浮点型秒数,可用time模块的gmtime()或localtime()函数算)
	getctime(file)				返回指定文件的创建时间(浮点型秒数,可用time模块的gmtime或localtime()函数换算)
	getmtime(file)				返回指定文件最新的修改时间(浮点型秒数,可用time模块的gmtime()或localtime()函数换算)
	
	以下为函数返回True或False
	exists(path)			判断指定路径(目录或文件)是否存在
	isabs(path)				判断指定路径是否是绝对路径
	isdir(path)				判断指定路径是否存在且是一个目录
	isfile(path)			判断指定路径是否存在且是一个文件
	islink(path)			判断指定路径是否存在且是一个符号链接
	ismount(path)			判断指定路径是否是存在且是一个挂载点
	samefile(path1,path2)	判断path1和path2两个路径是否指向同一个文件
help(open)
#OS模块中关于文件/目录常用的函数使用方法
#	函数名			    使用方法
#	getcwd()		返回当前工作目录
#	chdir(path)		改变工作目录
#	listdir(path='.')	列举指定目录中的文件名('.'表示当前目录,'..'表示上一级目录)
#	mkdir(path)		创建单层目录,如该目录已存在抛出异常
#	makedirs(path)		递归创建多层目录,如该目录已存在抛出异常,注意:'E:\\a\\b'和'E:\\a\\c'并不会冲突
#	remove(path)		删除文件
#	rmdir(path)		删除单层目录,如该目录非空则抛出异常
#	removedirs(path)	递归删除目录,从子目录到父目录逐层尝试删除,遇到目录非空则抛出异常
#	rename(old, new)	将文件old重命名为new
#	system(command)		运行系统的shell命令
import os#导入os模块
cur = os.getcwd()#返回当前工作目录
print(cur)
print(os.listdir())#默认列举当前目录
print(os.listdir(".."))#上一级目录
#os.removedirs('B')#删除目录,没有子文件和子目录
#os.system('cmd')#打开windows的cmd窗口
#os.system('calc')#打开计算器
print(os.name)#posix -> unix; nt -> win;...


#os.path模块中关于路径常用的函数使用方法
#	函数名						使用方法
#	basename(path)				去掉目录路径,单独返回文件名
#	dirname(path)				去掉文件名,单独返回目录路径
#	join(path1[,path2[],...])	将path1,path2各部分组合成一个路径名
#	split(path)					分割文件名与路径,返回(f_path,f_name)元组,如果完全使用目录,它也会将最后一个目录作为文件名分离,且不会判断文件或目录是否存在
#	splitext(path)				分离文件名与扩展名,返回(f_name,f_extension)元组
#	getsize(file)				返回指定文件的尺寸,单位是字节
#	getatime(file)				返回指定文件最近的访问时间(浮点型秒数,可用time模块的gmtime()或localtime()函数算)
#	getctime(file)				返回指定文件的创建时间(浮点型秒数,可用time模块的gmtime或localtime()函数换算)
#	getmtime(file)				返回指定文件最新的修改时间(浮点型秒数,可用time模块的gmtime()或localtime()函数换算)
#	
#	以下为函数返回True或False
#	exists(path)			判断指定路径(目录或文件)是否存在
#	isabs(path)				判断指定路径是否是绝对路径
#	isdir(path)				判断指定路径是否存在且是一个目录
#	isfile(path)			判断指定路径是否存在且是一个文件
#	islink(path)			判断指定路径是否存在且是一个符号链接
#	ismount(path)			判断指定路径是否是存在且是一个挂载点
#	samefile(path1,path2)	判断path1和path2两个路径是否指向同一个文件
print(os.path.ismount('E:\\'))#True
print(os.path.samefile('C:\\Users\Grant\Postman','C:\\Users\Grant\Downloads'))#判断如win中两个快捷方式
  1. 文件存储
永久存储:保存文件 例如把字段放到文件中,然后再读取出来到主代码中
标准的模块,把列表,集合,字典存入二进制文件,也可以读取
	pickle:泡菜
	存放:pickling
	读取:unpickling
	
	
	import pickle
	my_list = [1,2,'你好',[2,3]]
	
	#创建pkl文件只是一个标记,wb:二进制写
	pickle_file = open('my_list.pkl', 'wb')
	
	dump(list,file)
	
		#把列表写到文件 此时在缓存中
		pickle.dump(my_list, pickle_file)
		
		#关闭文件,从缓存保存到文件
		pickle_file.close()


	load(file)
		#从文件中读取二进制数据 'rb'
		pickle_file = open('my_list.pkl','rb')
		my_list2 = pickle.load(pickle_file)
	
	print(my_list2)
#标准的模块,把列表,集合,字典存入二进制文件,也可以读取
#导入pickle包
import pickle
my_list = [1,2,'你好',[2,3]]
#创建pkl文件只是一个标记,wb:二进制写
pickle_file = open('my_list.pkl', 'wb')
#把列表写到文件 此时在缓存中
pickle.dump(my_list, pickle_file)
#关闭文件,从缓存保存到文件
pickle_file.close()

#从文件中读取二进制数据 'rb'
pickle_file = open('my_list.pkl','rb')
my_list2 = pickle.load(pickle_file)
print(my_list2)
  1. 异常处理

异常处理:Exception 永远不要相信用户的输入

Python标准异常总结(常见)
AssertionError 断言语句(assert)失败
AttributeError 尝试访问未知的对象属性
EOFError input()读取到EOF和没有接收任何数据
IndexError 索引超出序列范围
KeyError 字典中查找一个不存在的关键字
NameError 尝试访问一个不存在的变量
OSError 操作系统产生的异常(例如打开一个不存在的文件)
SyntaxError Python语法错误
TypeError 不同类型的无效操作

检测异常并处理
任何出现在
try:
检测范围
except Exception[as reason]:
出现异常(Exception)后的处理代码

except (异常类型元组) as reason:
	print()

except:#所有异常都这么打印
	print()
finally:
	无论如何都会被执行的代码

代码形式引出一个异常
raise ZeroDivisionError("除数为零异常")

else与if while try搭配

与 if搭配 if else 要么要么

与 while 搭配 while中有break,执行break,则不执行同级的else,否则循环结束执行else

与 try 搭配 有异常 不执行 无异常则执行else

with语句
with会自动关闭文件
try:
with open("data1.txt", 'w') as f:
for each_line in f:
print(each_line)
except OSError as reason:
print("出错啦" + str(reason))

#常见异常
#AssertionError 断言语句(assert)失败
my_list = ["Nihao"]
##assert(len(my_list) > 0)
##my_list.pop()
##assert(len(my_list) > 0)

#AttributeError	尝试访问未知的对象属性
##my_list.you

#IndexError	索引超出序列范围
##my_list = [1,2,3]
##my_list[3]


#KeyError	字典中查找一个不存在的关键字
##my_dict = {"one":1, "two":2,"three":3}
##print(my_dict['one'])
##print(my_dict['four'])

#NameError	尝试访问一个不存在的变量
##you

#OSError	操作系统产生的异常(例如打开一个不存在的文件)

#SyntaxError	Python语法错误
##print 'I love you'

#TypeError	不同类型的无效操作
##1 + '1'
try:
    f = open("ab.txt", 'w')
    for each_line in f:
        print(each_line)
except OSError as reason:
    print("出错啦" + str(reason))
finally:
    f.close()
#with改造关注文件被调用自动关闭文件
try:
    with open("data1.txt", 'w') as f:
        for each_line in f:
            print(each_line)
except OSError as reason:
    print("出错啦" + str(reason))
  1. 安装EasyGui
EasyGui:
	安装EasyGui
	导入
	import easygui
	导入全部命令
	from easygui import *
	
	
	import easygui
	easygui.msgbox("hello world")

	#方式二:导入全部命令 from easygui import *
	msgbox("hello world")
  1. 对象
对象:
	对象= 属性+方法
	
OO的特征:
	封装:python的列表就是对象,对象封装
	继承:子类动态继承父类属性和方法
	多态:相同的方法名字,在不同的类实现方式不一样
面向对象编程
	self是什么:类似于C++语言的this指针
	一个类可以创建出很多对象,所以self相当于门牌号
	
	类定义的时候 self是第一个参数,这是要求
	
	class Ball:
    def setName(self, name):
        self.name = name
    def kick(self):
        print("我叫%s,谁替我" % self.name)
		
	构造方法;
		__init__(self,param1, param2)
		
		对象被创建的时候自动被调用

公有和私有:
	默认类中属性和方法是共有的
	
		python中定义私有变量只需要在变量名或函数名前加上“__”两个下划线,
	那么这个函数或变量就会为私有的了。

继承:
	class DerivedClassName(BaseClassName):#括号内写父类名(也叫基类、超类)

多重继承:class DerivedClassName(BaseClassName,Base2,Base3)
	不确定需要使用,不适用,容易混乱导致bug

组合:现在要求定义一个类,叫水池,水池里要有乌龟和鱼。

		class Turtle:
			def __init__(self,x):
				self.num = x

		class Fish:
			def __init__(self,x):
				self.num = x
		class Pool:
			def __init__(self,x,y):
				self.turtle = Turtle(x)
				self.fish = Fish(y)


纵向继承 横向组合



类、类对象、实例对象

	属性和方法名相同,属性会覆盖方法
	self绑定
	Person 是个类
	Person()是类对象
	p = Person() p是实例对象
	self相当于某个实例如:
		class Person:
			def setXY(self,x,y):
				self.x = x
				self.y = y
	其中self就相当于 Person()对象实例
	
	查看类中属性
		Person.__dict__
	查看实例中属性方法
		p.__dict__
	
	如果此时把类对象删除,就不能重新定义实例,但原来定义的实例还在内存中
		del Person #静态属性和方法
		d = Person()#报错
		p#还在 类对象在内存中,只有当程序退出才释放

  1. 类和对象bif
类和对象相关的BIF
	issubclass(class, classinfo):判断是不是子类
	classinfo 可以是类对象组成的元组,只要class与其中任何一个候选类的子类,则返回True
	
	isinstance(Object,classinfo):检查实例对象是否是属于一个类
	第一个参数不是object,则返回Flase,第二个参数不是类或者类对象组成的元组,会抛出一个TypeError异常
	
	attr:属性
		hasattr(Object, name) 对象里是否有对应的属性 name要用字符串形式
		getattr(object,name[,default]) 返回对象指定的属性值,如果指定值不存在返回default 没有default返回异常
		setattr(Object,name,value) 新建一个属性值
		delattr(Object,name) 删除指定属性的值
		
		property(fget=None,fset=None,fdel=None,doc=None)通过属性设置属性


__init__(self):返回值必须是null,即没有返回值   需求才写去初始化

对象实例化的第一个被调用方法 __new__(cls[,...])  当修改继承一个不可修改的类时,去重写__new__
	class CapStr(str):
    def __new__(cls,string):
        string = string.upper()
        return str.__new__(cls,string)

	a = CapStr("I love world")
	print(a)


算术运算1
	__add__(self,other):定义加法的行为
	__sub__(self,other):减法
	__mul__(self,other):乘法
	__truedlv__(self,other):真除法
	__floordiv__(self,other):整数除法
	__mod__(self,other):定义取模算法
	__divmod__(self,other):定义当被divmode()调用时的行为
	__pow__(self,other):定义当被power()调用或**运算时的行为
	__lshift__(self,other):按位左移位的行为:<<
	__rshift__(self,other):按位右移:>>
	__and__(self,other):按位与操作的行为:&
	__xor__(self,other):按位异或:^
	__or__(self,other):按位或操作:|
算术运算2
	反运算
		_radd_(self, other)	(与上方相同,当左操作数不支持相应的操作时被调用)
		……
	增量
		__iadd__(self,other):+=
		……
	一元操作符
		__neg__(self)	定义正号的行为:+x
		__pos__(self)	负号:-x
		__abs__(self)	绝对值
		__invert__(self)	按位求反
	类型转换
		__complex__(self)	
		__int__(self)
		__float__(self)
		__round__(self[,n])
		
		
#获取当前时间,导入time模块 localtime方法 struct_time 时间格式
import time as t


访问属性方法


描述符:
	将某种特殊类型的类的实例指派给另一个类的属性

  1. 定制序列
定制序列:协议(Protocols)与其他编程语言中接口类似 -》指南

#定制序列
class CountList:
    def __init__(self,*args):
        self.values = [x for x in args]
        self.count = {}.fromkeys(range(len(self.values)),0)

    def __len__(self):
        return len(self.values)

    def __getitem__(self,key):
        self.count[key] += 1
        return self.values[key]

#统计元素访问的次数
c1 = CountList(1,3,5,7)
c2 = CountList(2,4,6,8)
c1[1]
c2[2]
c1[1] + c2[3]
print(c1.count)
print(c2.count)
#定制序列
class CountList:
    def __init__(self,*args):
        self.values = [x for x in args]
        self.count = {}.fromkeys(range(len(self.values)),0)

    def __len__(self):
        return len(self.values)

    def __getitem__(self,key):
        self.count[key] += 1
        return self.values[key]

#统计元素访问的次数
c1 = CountList(1,3,5,7)
c2 = CountList(2,4,6,8)
c1[1]
c2[2]
c1[1] + c2[3]
print(c1.count)
print(c2.count)
  1. 迭代-生成器
#迭代器
##	iter()
##	next()
string = 'hello'
it = iter(string)
##print(next(it))
##print(next(it))
##print(next(it))
##print(next(it))
##print(next(it))
##print(next(it)) #StopIteration
while True:
    try:
        each = next(it)
    except StopIteration:
        break
    print(each)
    
#for
for each in string:
    print(each)

#对应两个魔法方法
##    __iter__() #return self
##    __next__() #决定迭代规则

##class Fibs:
##    def __init__(self):
##        self.a = 0
##        self.b = 1
##    def __iter__(self):
##        return self
##    def __next__(self):
##        self.a,self.b = self.b, self.a + self.b
##        return self.a
##    
##fibs = Fibs()
##for each in fibs:
##    if each < 20:
##        print(each)
##    else:
##        break
    
#或者加个参数,控制迭代范围
class Fibs:
    def __init__(self,n):
        self.a = 0
        self.b = 1
        self.n = n
    def __iter__(self):
        return self
    def __next__(self):
        self.a,self.b = self.b, self.a + self.b
        if self.a > self.n:
            raise StopIteration
        return self.a
    
fibs = Fibs(100)
for each in fibs:
        print(each)

生成器:yield

	所谓的协同程序就是可以运行的独立函数调用,函数可以暂停或者挂起,并在需要的时候从程序离开的地方继续或者重新开始。
#生成器 yield 相当于迭代器的iter()
def myChen():
    print("生成器被执行。。")
    yield 1
    yield 2
myC = myChen()
print(next(myC))
print(next(myC))
#print(next(myC)) StopIteration
  1. 模块
模块:更高级的封装
	容器:数据的封装
	函数:语句的封装
	类:方法和属性的封装
	模块:模块就是程序

在py安装目录,写入.py文件就是一个模块
导入模块 import hello  其中hello 是命名空间,使用hello.hi() 
import hello
hello.hi()
import hello as h
h.hi()

第二种 from 模块名 import 函数名

from hello import hi,add
hi()
add()
from hello import *#不建议使用容易覆盖
import hello as h
h.hi()
模块 if __name__ == '__main__':

表示
	def c2f(cel):
		fah = cel * 1.8 + 32
		return fah
	
	def f2c(fah):
		cel = (fah - 32) / 1.8
		return cel
	
	def test():
		print('')
		print('')
	
	if __name__ == '__main__':#是主程序的话调用,是模块名的话就不调用
		test()

写好的模块放在哪里:
	搜索路径
	import sys
	sys.path
	print("sys.path->",sys.path)
	#其中 D:\\install\\py\\lib\\site-packages 是用来存放模块的路径(推荐)
	#把路径拼进去 sys.path.append("")就可以导入了

包(package)
	1. 创建一个文件夹,用于存放相关的模块,文件夹的名字即包的名字
	2. 在文件夹中创建一个__init__.py的模块文件,内容可以为空
	3. 将相关的文件放入文件夹中

导入就是包名.模块名
import test.hello as h
h.hi()
h.add()
#搜索路径
import sys
sys.path
print("sys.path->",sys.path)
#其中 D:\\install\\py\\lib\\site-packages 是用来存放模块的路径(推荐)
#把路径拼进去 sys.path.append("")就可以导入了
##包(package)
##	1. 创建一个文件夹,用于存放相关的模块,文件夹的名字即包的名字
##	2. 在文件夹中创建一个__init__.py的模块文件,内容可以为空
##	3. 将相关的文件放入文件夹中
##
##导入就是包名.模块名
import test.hello as h
h.hi()
h.add()
  1. python文档,社区
	使用现成的库
	电池:Python标准库
		Python标准库中包含一般任务所需要的模块(数百个库)
	充电器:
		Python的文档
	
	PEP:规范
	PEP 3000:定义Python 3.0相关技术规格
	PEP 333: Python 的Web相关技术规格
	PEP 本身定义在PEP 1
	PEP 8 :定义了Python代码的风格指南
	PEP 0:PEP的列表:https://www.python.org/dev/peps/
	
	
	
第三方模块社区:
	https://pypi.python.org/pypi

使用一个模块 可以去看接口文档也可导入

import timeit

dir(timeit)

timeit.__all__
	#作者希望你使用的所有类和方法
	from timeit import * 
	导入的是所有__all__的方法
timeit.__file__
	源代码所在的位置

help(timeit)
  1. 什么是网络爬虫
网络爬虫:在庞大网络中搜索提取有用的信息数据
	
	Python如何联网
		自带电池:urllib -> url + lib
	
	URL一般格式:
		protocol://hostname[:port]/ path / [;parameters][?query]#fragment
	
	URL由三部分组成:
		协议:http,https,ftp,file, ed2k...
		第二部分存放资源的服务器域名系统或ip地址(有时候要包含端口号,各种传输协议都有默认端口号,如http默认80)
		第三部分是资源的具体地址,如目录或文件名等。
	
	urllib是python的一个包
		主要使用urllib.request 访问请求响应
##import urllib.request
#传进去的是字符串会自动转为request对象
##response = urllib.request.urlopen('http://placekitten.com/g/500/600')
##cat_img = response.read()
##
##with open('cat_500_600.jpg','wb') as f:
##    f.write(cat_img)
##print(response.info())#打印HTTPMessage信息
##print(response.getcode())

#利用有道词典翻译
import urllib.request
import urllib.parse
import json

content = input("请输入需要翻译的内容:")

url = "https://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule"
data = {}
data['i'] = content
data['from'] = 'AUTO'
data['to'] = 'AUTO'
data['smartresult'] = 'dict'
data['client'] = 'fanyideskweb'
data['salt'] = '16258115347721'
data['sign'] = '87b4c06990aca5edffdfc2e097055ad4'
data['lts'] = '1625811534772'
data['bv'] = '5b3e307b66a6c075d525ed231dcc8dcd'
data['doctype'] = 'json'
data['version'] = '2.1'
data['keyfrom'] = 'fanyi.web'
data['action'] = 'FY_BY_CLICKBUTTION'
data = urllib.parse.urlencode(data).encode("utf-8")#python默认不是utf-8

response = urllib.request.urlopen(url, data)
html = response.read().decode('utf-8')

target = json.loads(html)
print("翻译结果:%s" % (target['translateReslut'][0][0]))
#隐藏
opener.addheaders = [("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")]
import os
import urllib.request

def url_open(url):
    req = urllib.request.Request(url)
    req.add_header('User-Agent','M....')
    #此处可以加代理
    response = urllib.requet.urlopen(url)
    html = response.read()
    return html

def get_page(url):
    html = url_open(url).decode('utf-8')
    a = html.find('current.comment.page' + 2)
    b = html.find('}',a)

    return html[a:b]

def find_imgs(url):
    html = url_open(url).decode('utf-8')

    img_addrs = []

    a = html.find('img src = ')
    while a != -1:
        b = html.find('.jpg',a,a+255)
        if b != -1:
            img_addrs.append(html(a+9))
        else:
            b = a+9
            
    a = html.find('img','src=',b)
def save_imgs(img_addrs):
    pass

def download_me():
    os.mkdir()
    os.chdir()

    url = "http://jandan.net/ooxx"
    page_num = int(get_page(url))
   

    for i in range(pages):
        page_num -= i
        page_url = url + 'page' + str(page_num) + 'accomments'
        img_addrs = find_imgs(page_url)
        save_imgs(img_addrs)

if __name__ == '__main__':
    download_me()
  1. 正则表达式
#查找字符串
#正则表达式 匹配字符串  search()
	import re
	re.search(r'正则表达式','字符串')

	re.findall('正则表达式','字符串')#把匹配到的字符串打包成列表返回

	index = re.search(r'fi','i lo fi ')#search()方法用于在字符串中搜索正则表达式模拟第一次出现的位置
	print(index)#<re.Match object; span=(5, 7), match='fi'>

	# . 匹配除了换行符的任意一个字符
	index1 = re.search(r'.','I love you')
	print(index1)#<re.Match object; span=(0, 1), match='I'>
	print(re.search(r'yo.','I love you'))#<re.Match object; span=(7, 10), match='you'>

	#匹配.号,\
	print(re.search(r'\.', 'baidu.com'))#<re.Match object; span=(5, 6), match='.'>

	#\d 匹配任意一个数字
	print(re.search(r'\d\d',"baidu.com234"))#<re.Match object; span=(9, 11), match='23'>
	print(re.search(r'[0-9]','baidu.com234'))#<re.Match object; span=(9, 10), match='2'>

	#匹配字符类 #默认关闭大小写即i匹配不到I
	print(re.search(r'[aeiou]','hello'))#<re.Match object; span=(1, 2), match='e'>
	print(re.search(r'[a-z]','hello'))#<re.Match object; span=(0, 1), match='h'>

	#匹配次数
	print(re.search(r'ab{3}c','aabbbcc'))#<re.Match object; span=(1, 6), match='abbbc'>
	print(re.search(r'ab{3,8}c','abbbbbbc'))#<re.Match object; span=(0, 8), match='abbbbbbc'>

	#匹配0-255 百位个位十位 |或
	print(re.search(r'[01]\d\d|2[0-4]\d|25[0-5]','188'))#<re.Match object; span=(0, 3), match='188'>
	#匹配{0,1}匹配0或者1次

	#匹配ip地址 192.168.1.1 #小括号表示分组(([01]\d\d|2[0-4]\d|25[0-5])\.)表示一组后边3表示前边需要匹配三次
	print(re.search(r'(([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])\.){3}([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])','192.168.1.1'))


正则表达式规则
	详细见图
	元字符
	[]   \

	*	(0,)匹配0或多次
	+	(1,)
	?	(0,1)

	+?表示非贪婪模式,即禁止条件符合尽可能多的匹配


	\A	匹配输入字符串的开始位置
	\Z	匹配输入字符串的结束位置


编译正则表达式:
	p = re.compile(r"[A-Z]")
	p.research("hello")
	p.findall("hello")

正则表达式的使用:
	search()返回的是match对象,对象有对应的方法
	.group()
	.group(1)
	.group(2)
	.start()
	.end()
	.span()

提取页面图片地址
	def open_url(url):
		req = urllib.request.Request(url)
		req.add_header('User-Agent','M...')
		page = urllib.request.urlopen(req)
		html = page.read().decode('utf-8')

		return html

	def get_img(html):
		p = r'<img class= 'DE_image' src = '([^*]\.jpg)'>'
		imglist = re.findall(p,html)

		for each in imglist:
			print(each)

	if __name__ == '__main__':
		url = ''
		get_img(open_url(url))

  1. 异常处理
#urllib.error 处理异常
import urllib.request
import urllib.error

req = urllib.request.Request("http://www.ooxx.bat.com")
try:
    urllib.request.urlopen(req)
except urllib.error.URLError as e:
    print(e.reason)
#[Errno 11001] getaddrinfo failed


#HTTPError
req1 = urllib.request.Request("http://www.baidu.com/bat/bat.html")
try:
    urllib.request.urlopen(req1)
except urllib.error.HTTPError as e:
    print(e.code)
    print(e.read())
#第二种写法
from urllib.request import Request,urlopen
from urllib.error import URLError
req = Request(someurl)
try:
    response = urlopen(req)
except URLError as e:
    if hasattr(e, 'reason'):
        print('We failed to reach a server.')
        print('Reason', e.reason)
    elif hasattr(e,'code'):
        print('The server couldn\`t fulfill the request.')
        print('Error code:',e.code)

    else:
    #everything is fine
  1. Scrapy
Scrapy:
	是一个为了爬取网站数据,提取结构性数据而编写的应用框架。
	可以应用在报考数据挖掘,信息处理或存储历史数据等一系列的程序中。
	
	最初是为了页面抓取(更确切来说,网络抓取设计),也可以用在获取API所返回的数据
	(例如:Amazon Associates Web Services)或者通用的网络爬虫



对于安装时因为系统盘中有中文文件名,导致的编码错误:
在python的lib下的site-packages中写一个py脚本
import sys
sys.setdefaultencoding('gd2312')

#这样python安装时会默认加载这个


在Script目录下执行cmd运行pip install Scrapy即可

Scrapy框架使用
	使用Scrapy抓取一个网站一共分四个步骤:
		1. 创建一个Scrapy项目
		2. 定义Item容器
		3. 编写爬虫
		4. 存储内容
		
目录网站:www.dmoz.org
	cd E:\scrapy\study然后执行下边命令,产生一个tutorial名字的项目
		scrapy startproject tutorial
	文件夹存储的目录:初始文件夹
		tutorial/
			scrapy.cfg
			tutorial/子文件夹
				__init__.py
				items.py 容器,项目中的item文件
				pipelines.py
				settings.py
				spiders/
					__init__.py
					...
	
2. Item时保存爬取到的数据的容器,其hi用方法和python字典类似,并且提供了额外保护机制来
避免拼写错误导致的未定义字段错误
	编写Item.py文件
	
	class DeozItem(scrapy.Item):
	title = scrapy.Field()
	link = scrapy.Field()
	des = scrapy.Filed()
	
3. 编写爬虫
	spider时用户编写用于从网站上爬取数据的类
	其中包含了一个用于下载的初始URL,然后如何跟进网页中的链接一级如何分析网页中
	内容,还有提取生成item的方法
	
	
splid.py

import scrapy

class DeozSpider(scrapy.spider):
	name = "deoz"
	allowed_doeains = ["deoz.org"]
	start_urls = [
		"http://www.deoz.org/...",
		"http://www.deoz.org/..."
	]
	def parse(self, response):
		filename = response.url.split("/")[-2]
		with open(filename,'wb')
			f.write(response.body)
	
保存,然后在tutorial目录下执行cmd
		scrapy crawl deoz#在splider目录下的DeozSpider文件内定义的需要爬虫的名字
		


Selector是一个选择器,四个基本方法:
	xpath():传入xpath表达式,返回该表达式所对应的所有节点的selector list列表
	css():传入CSS表达式,返回该表达式所对应的所有节点的selector list列表
	extract():序列化该节点为unicode字符串并返回list
	re():根据传入的正则表达式对数据进行提取,返回unicode字符串list列表
	

启动 scrapy shell "url" 进入shell的response回应
	response.header
	response.selector.xpath()#XPath是一门在网页中查找特定信息的语言,所以用XPath来筛选数据,要比使用正则表达式容易些
	response.xpath() == response.selector.xpath()
	response.xpath('//title')#返回一个列表
	response.xpath('title').extract()#字符串化
	response.xpath('title/text()').extract<>#节点,查找数据
	sel.xpath('//ul/li')
	sel.xpath('//ul/li/text()')#获取网站的描述内容
	sel.xpath('//ul/li/text()').extract()#看不清转成字符串
	sel.xpath('//ul/li/a/href').extract()
	
	sites = sel.xpath('//ul/li')
	for site in sites:
		title = site.xpath('a/text()').extract()
		print(title)



#以上是爬和取得过程 接下来就是存到容器中
from tutorial.item import DeozItem

class DeozSpider(scrapy.spider):
	name = "deoz"
	allowed_doeains = ["deoz.org"]
	start_urls = [
		"http://www.deoz.org/...",
		"http://www.deoz.org/..."
	]
	
	def parse(self, response):
            sel = scrapy.selector.Selector(response)
            sites = sel.xpath('//ul[@class="directory-url"]/li')
            items= []
            for site in sites:
                item = DeozItem()
                title = site.xpath('a/text()').extract()
                link = site.xpath('a/@href').extract()
                desc = site.xpath('text()').extract()
                print(title,link,desc)
                items.append(item)

            return items

导出json格式
scrapy crawl daoz -0 items.json -t json

posted @ 2021-07-15 20:23  白玉神驹  阅读(116)  评论(0)    收藏  举报