导图社区 Python基础
学习python必备,一张思维导图带你畅游python的世界。PYthon是初学者的语言:Python对初级程序员而言,是一种伟大的语言,它支持广泛的应用程序开发,从简单的文字处理到 WWW 浏览器再到游戏。简单易学。
编辑于2020-12-07 20:11:30Python基础
1. 变量
变量名必须是一个有效的标识符。 变量名不能使用Python中的保留字。 慎用小写字母1和大写字母O。 应选择有意义的单词作为变量名。 数字 字母下划线组成 为变量赋值可以通过等号(=)来实现
保留字
标识符
区分大小写
2. 数据类型
数字类型
整数int
浮点数float
复数complex
进制
布尔类型bool
在Python中, 所有的对象都可以进行真值测试。其中, 只有下面列出的几种情况得到的值为假, False或None。 数值中的零,包括0、0.0、虚数0。 *空序列,包括字符串、空元组、空列表、空字典。 *自定义对象的实例, 该对象的__bool__方法返回False, 或__len_方法返回0.
字符串
增
jion
+
删
replace
str.replace(old, new[, max]) old -- 将被替换的子字符串。 new -- 新字符串,用于替换old子字符串。 max -- 可选字符串, 替换不超过 max 次(默认是全部,可以指定次数)
改
upper、把所有的字母转成大写 lower、把所有的字母转成小写 strip (lstrip,rstrip)、去除空格、 带参数去除指定元素的开头和结尾的相同的元素 capitalize、把第一个字母转换成大写 title、把单词的首字母进行大写转换 split、没有参数默认以空格来切割、有参数
查
count、计算出现了多少次 find、 如果包含子字符串返回开始的索引值,否则返回-1。 index、返回指定值的下标,没有会报错 isdigit、判断一个字符串里的数据是不是都是数字 isalpha、判断每个元素是不是字母 endswith、比较结尾的元素是否相同 startswith、比较结尾的元素是否相同 islower、判断字符串中的值是否全是小写的 isupper、判断字符串中的值是否全是大写的
方法
切片
字符串编码
encode decode
格式化输出
%占位符
%s %d %f 等等 了解: %d %数字 %f %浮点数 %c %ASCII字符 %o %8进制 %x %16进制 %e %科学计数法 %.if 保留i位小数 %xf 确定总长度不足用空格不全 ' %-6.3f '% 10.3 左对齐 ' %+6.3f'% 10.3 显示正负 ' %5s ' % 'ab' 格式化长度 掌握: print(‘%s’%’123’) print(‘%d’%’123’)
>>> '%f'%2.3# 6位 '2.300000' >>> '%.2f'%2.3 '2.30' >>> '%.2f'%2.3666 '2.37' >>> '%.2f'%2.3555# 五舍六入 '2.36' >>> print("PI=%10.3f"%3.142) PI= 3.142 >>> print("PI=%-10.3f"%3.142) PI=3.142
format
format 了解: '{:.2f}'.format(12.333) 保留小数点后两位 '{a:.2f}'.format(a=12.333) '{:.2%}'.format(0.333) 百分比格式 '{:x}'.format(20) 转换成十六进制 '{:o}'.format(20) 转换成八进制 进制转换的时候用{0:进制} ' {a:<10}’.format(a=12.3,b=13.44) 左对齐,长度为10 ' {a:0<10}'.format(a=12.3,b=13.44) 数字补x (填充右边, 宽度为4) ' {a:0>10}’.format(a=12.3,b=13.44) 右对齐... ' {a:0^10}'.format(a=12.3,b=13.44) 两边对齐...
深浅复制
不可变类型(数字、字符串、元组、不可变集合) 可变类型(列表、字典、可变集合)
不可变类型(immutable):修改其中一个,另一个不会变。可变类型(mutable):修改其中一个,另一个必定改变。
浅复制
浅复制
`特点:数据半共享` `copy.copy()` 复制其数据独立内存放,但是只复制成功第一层
**结论:对于浅拷贝,数字和字符串在内存当中用的也是同一块地址。**
深复制
`copy.deepcopy()` `特点:深拷贝就是完完全全复制了一份,且数据不会互相影响,因为内存不共享 `
**结论:对于深拷贝,字典、列表、元组等类型,它里面嵌套多少层,就会拷贝多少层出来,但是最底层的数字和字符串地址不变。**
bytes和bytearray
序列
列表
增
append,将元素追加到末尾
insert,添加到指定的位置
extend,将序列中的每个元素追加到末尾
+ 也可以合并添加
删
pop、不带参数弹出最后一个元素、带参数指定下标值
remove,移除指定的元素
clear、删除列表中的所有值
del 列表名称
改
li[0] = ' list '
查
index,在列表中从左至右查找指定元素,找到了放回该值的下标
count、计算列表中指定元素出现的次数
元组
增
+ 也可以合并添加
删
del 列表名称
查
index,在列表中从左至右查找指定元素,找到了放回该值的下标
count、计算列表中指定元素出现的次数
方法
索引
切片
sname[start:end:step]
序列相加
乘法* in not in len max min sum sorted reversed enumerate cmp(tuple1, tuple2) 比较两个元组元素
散列
字典
定义
di = {'name':'浩天', 'height':'183cm'} 键值对形式 di2 = dict(a=1, b=2) 使用dict函数
增
copy
` dict.fromkeys(key,value) 返回新字典、是第一个参数的拆分:新字典的值是第二个参数
>>> c=a.fromkeys(('v','vc'),[1,2,3]) >>> c {'v': [1, 2, 3], 'vc': [1, 2, 3]}
setdefault 有则查,无则增
>>> a.setdefault('a') 2 >>> a.setdefault('c') >>> a {'a': 2, 'b': 3, 'c': None} >>> a.setdefault('d',3) 3 >>> a {'a': 2, 'b': 3, 'c': None, 'd': 3}
删
clear 清空字典 pop 弹出指定key的键值对 popitem 返回并删除字典中的最后一对键和值
改
update 更新字典、将原字典和新字典整合,key重复新的覆盖老的
查
get 获取指定key 对应的value,如果key不存在放回none keys 取出所有的key values 取出所有的值 items 取出所有的键值对
集合
增
s1.add('f')
删
pop remove
改
`update(可迭代对象) 目前理解为序列类型,把每一个元素拆开添加`
查
isdisjoint 有交集返回False issubset 判断是否包含于 issuperset 判断是否包含
三种运算
s1 & s2 交集 s1 | s2 并集 s1 - s2 差集
数据类型转换
list str set
查看对象类型
type(object) 注意:object后面会讲的 isinstance(object,对象类型)
3. 运算符
算数运算符
+ - * / % // **
赋值运算符
= += -= *= /= %= **= //=
比较(关系)运算符
> < == != >= <=
逻辑运算符
and or not
位运算符
运算符的优先级
运算符 描述 ** 幂运算 +、- 一元运算符(正负号) %、/、* 算术运算符 +、- <、>、<=、>=、==、!= 比较运算符 =、/=、-=、+=、*=、%=、**=、//= 赋值运算符 is、is not 身份运算符 in、not in 成员运算符 not > and > or 逻辑运算符
4. 流程控制语句
条件语句
if语句
if a > 80: if b > 90: print('优秀') else: print('及格') else: print('差')
if 判断条件: 执行语句…… else: 执行语句……
if 判断条件1: 执行语句1…… elif 判断条件2: 执行语句2…… elif 判断条件3: 执行语句3…… else: 执行语句4……
三目运算符
# 三目运算符 print(True) if a>5 else print(False) b = True if a > 5 else b = False # 值1 if 判断语句 else 值2
循环语句
while循环
# 计算1-100 的和。高斯求和 count = 1 sum1 = 0 while count<=100: sum1 = sum1+ count count = count + 1 print(sum1) 1
**while 循环嵌套语法**
`for … else`
for迭代循环
for letter in 'Hello 两点水': print(letter)
**for 循环嵌套语法**
`while … else`
range()函数
for i in range(3): print(i)
`range(0,10,2)` , 它的意思是:从 0 数到 10(不取 10 ),每次间隔为 2 。
判断是否是闰年
# 判断是否是闰年 year = int(input("请输入一个年份: ")) if (year % 4) == 0 and (year % 100) != 0 or (year % 400) == 0: print('{0} 是闰年' .format(year)) else: print('{0} 不是闰年' .format(year))
跳出语句
break
continue
pass
5. 函数
函数的定义
def 函数名(参数): pass return 表达式
函数名命名规则: 字母、数字和下划线组成,和变量命名规则一致 pass在这里表示什么都没有,不执行任何操作 return 后面可以返回任意表达式,但不能是赋值语句
函数调用
函数名(参数)
说明
return: return没有写返回值的话,默认None 注意 return 和 print 的区别,return是函数的返回值,返回值可以赋值给变量,而print只是打印出来
函数参数
必备参数
def func(x): print(x) func(1)
默认参数
def func(x, y=None): print(x) print(y) func(1) func(1, 2) 注意:默认参数要位于必备参数 列表的后面
不定长参数
def func(*args, **kwargs): print(args) print(kwargs) 调用1:func(1, 2, 3, a=4, b=5, c=6) 调用2:func(*(1, 2, 3), **{'a': 4, 'b': 5, 'c': 6})
关键字参数
def func(x): print(x) func(x=1)
内置对象查看
dir(__builtins__)
常见函数
len 求长度 min 求最小值 max 求最大值 sorted 排序 reversed反向 sum 求和
高级内置函数
enumerate 返回一个可以枚举的对象 exec 执行字符串编译过的字符串 map() 跟filter差不多,它拿到的是放回值 对于参数iterable中的每个元素都应用fuction函数,并将结果作为列表返回 eval 取出字符串中的内容 将字符串str当成有效的表达式来求指并返回计算结果,不能赋值 filter 过滤器 zip 将对象逐一配对
进制转换函数
bin 转换为二进制 oct 转换为八进制 hex 转换为十六进制 ord 字符转ASCII码 chr ASCII码转字符
匿名函数
匿语法规则: lambda 参数 : 表达式
print(list(filter(lambda x:x>4, [1,2,3,4,5,6,7,8,9])))
函数作用域
外部不能访问函数内部变量 函数内部能够访问函数外部变量: 函数里面不能修改函数外部变量 函数里面和函数外部变量名相同
global(全局变量)
x = 123 def fun1(): global x x += 1 return x
nonlocal(局部变量)
def fun2(): x = 123 def fun3(): nonlocal x x += 1 return x return fun3()
闭包
闭包是函数里面嵌套函数,外层函数返回里层函数,这种情况称之为闭包 闭包是概念,不是某种函数类型,和递归的概念类似,就是种特殊的函数调用 闭包可以得到外层函数的局部变量,是函数内部和函数外部沟通的桥梁
闭包: def fx(x): x += 1 def fy(y): return x*y return fy
递归
递归中可以函数自身调用自身,但是使用时类似于条件循环一样,要有递归的终止条件
阶乘: def factorial(n): if n == 1: return 1 return factorial(n-1)*n
回调函数
回调函数: 自身是一个函数,只是被传入到另一个函数当中,供其调用 回调函数不一定会被调用,是否调用由被传入函数的内部逻辑决定
示例: def choice(callback, ch): if ch: callback() else: print('OK') def play(): print('hahahaha') choice(play, 1)
6. 类和对象
类
类的定义
# class 定义类的关键字 类名首字母大写(约定俗成的) class 类名: pass 大驼峰命名:单词的首字母大写 TestTimePerson 小驼峰 首字母小,之后的大写 变量名,都是小写。单词之间下划线隔开 示例: class Person: pass
类的三要素
`类名 ` ` 属性---变量 ` ` 方法---函数`
class Person: name = 'aaa' # 定义 类属性 print(Person.name) # 访问类属性 Person.name2 = 'xxx同学' # 类外--添加类属性 print(Person.name2) 人类---> 小明同学 ---> 小明女朋友
子主题 2
实例化
实例化
实例名 = 类名()
实例也是一个独立存放变量的空间
audi.owner='剑南春' # 对象添加的属性,空间是独立的,其他的访问不到,(改装车) print(audi.owner)# 有 print(Car.owner)# 没有 # 实例化对象既能访问实例属性,也能访问类属性 # 类只能访问类属性
私有属性(了解)
一个、两个下划线# 私有属性 不要在外边调用(一个下划线可以调用,但是不要去调用(约定俗称))
class Car: boon = 4 _height = 220# 私有属性 可以调用,约定俗成的私有属性 __aaa = 'hello'# 强制私有属性 print(Car.aaa)# 不可用
方法
class Person: #定义一个名字是Person的类 def eat(self): #在Person类中定义eat方法 print('吃鸡腿') ht=Person() #Person类的一个实例 ht.eat() #调用eat方法
初始化
以双下划线开头且以双下划线结尾的固定方法,他们会在特定的时机被触发执行,__init__就是其中之一,它会在实例化之后自动被调用,以完成实例的初始化。
class Person: def __init__(self,name): #两个下划线,初始化方法 self.name=name def eat(self): #在Person类中定义eat方法 print('%s吃鸡腿'%self.name) #调用实例wum的name属性 wum=Person('茅台') #实例化时需要传一个参数 wum.eat() #调用eat方法
析构方法
__del__
当使用del 删除对象时,会调用他本身的析构函数
class Person: #定义一个名字是Person的类 def __init__(self,name): #初始化方法 self.name=name def __del__(self): #析构方法(销毁方法) print(self.name,'被销毁了。。') wum=Person('无名') del wum #打印出被销毁
继承
class子类名(基类名1,基类名2.…)基类写在括号里。
super 函数可以调用父类的方法
`issubclass(A,B),判断A类是否是B类的子类`
`isinstance(a,A),判断a是否是A类的实例对象
print(Base.mro()) 或 print(Son.__mro__) #可以查看继承顺序
print(Son.__bases__) #查看Son类的直接基类(父类)
Mix-in设计模式
魔法方法
__add__(self,other) # x+y __sub__(self,other) # x-y __mul__(self,other) # x*y __mod__(self,other) # x%y __iadd__(self,other) # x+=y __isub__(self,other) # x-=y __radd__(self,other) # y+x __rsub__(self,other) # y-x __imul__(self,other) # x*=y __imod__(self,other) # x%=y 运算方法大家了解一下即可,在实际中应用并不多
class A def __init__(self,num,num2) self.num=num self.num2=num2 def __add__(self, other) #self 实例 other 另外一个实例 sum1=self.num + other.num sum2=self.num2+other.num2 return sum1,sum2 # return self.num+other.num # a=A(4,6) # b=A(2,1) # c=A(3,6) # print(a+c)
class Pig def __str__(self) return '这是模式方法' def __repr__(self) return '这是一个repr魔术方法' a=Pig() print(a) #会先调用这个str方法 如果没有 调用repr方法 如果还是没有 会打印地址 #交互模式下不会打印str方法,
#def __call__(self,*args,**kwargs): return 'hello world' a = Rectangle(10,20) print(a()) #call方法就是可以让实例去调用他
new方法
class Base: def __init__(self): print('这是初始化方法里面') def __new__(cls, *args, **kwargs): print('这个cls是:',cls) # cls 就是Base类 print('这是在new方法里面') return object.__new__(cls) # 必须有返回值 #实例的时候会先调用_new_方法,然后再调用初始化方法 test = Base()
单例模式
class Person: pass xiaoming = Person() xiaohong = Person() print(id(xiaoming)) print(id(xiaohong)) 地址是不是都是不一样的 # 单例模式要实现的效果就是--- 每一次实例化所创建的实例都是同一个,内存地址都是一样的 class A: _instance = None # 实例 def __new__(cls,*args, **kwargs): if cls._instance == None: cls._instance = object.__new__(cls) return cls._instance else: return cls._instance a = A() b = A() print(id(a)) print(id(b)) ---------------------------------- class Person: def __new__(cls, *args, **kwargs): # self 实例本身 cls 类本身 if not hasattr(cls,'instance'): cls.instance = super().__new__(cls) return cls.instance def __init__(self, name): self.name = name xiaoming = Person('小明') laowang = Person('老王') print(id(xiaoming)) print(id(laowang)) print(laowang.name) print(xiaoming.name)
定制属性
关于属性的增删改查
hasattr(xiaoming,'name')
getattr(xiaoming,'name')
setattr(xiaoming,'name','老王')
setattr(xiaoming, 'age',19) # 有则改 无则增
delattr(xiaoming,'name') 等价于 del.xiaoming.name
描述符(难点)
class MyClass: def __get__(self, instance, owner): print('获得S级武器') def __set__(self, instance, value): print('This is %s' % value) def __delete__(self, instance): print('武器已经损坏') class Control: attr = MyClass() # 类的实例化,类属性 c = Control() c.attr # 调用属性,回去我们MyClass类里面执行__get__方法 c.attr = 10 # 重新赋值 调用__set__方法 del (c.attr)# 调用__delete__方法
装饰器(重、难点)
概念
不改变原有函数的基础上,给函数增加一些新的功能
def modify(func): def wrapper(): result = func() return result + ',三里桃花不及卿' return wrapper g = modify(girl) print(g()) # print(girl()) 现在只剩下最后一步了 就是名字不一样 我们改一下是不是就行了 girl = modify(girl) print(girl()) # 使用的原理 # 用法 @ 语法糖 @modify # 只会影响这一行 def girl(): # 会把 girl传到 装饰器里面去 return '春风十里不如你' a = girl() print(a)
`类当做装饰器必须使用 __ call __`
class Test_Class: def __init__(self, func): self.func = func def __call__(self,*args,**kwargs): print('类----cal----') return self.func() @Test_Class def fun_test(): print('这是个测试函数') fun_test()
拓展(高阶函数)
内置装饰器
class Rectangles: name = 'bbbb' def __init__(self, length, width): self.length = length self.width = width def area(self): areas = self.length * self.width return areas @property # 就像访问属性一样 调用可以不用括号 def areas(self): return self.width * self.length @staticmethod # 静态方法 和class类断开联系 不加self def func(): # self 在调用的时候会报错 print('staticmethod func') @classmethod # 类方法 传递类本身 直接类方法 def show(cls): # cls 代表类本身 print(cls.name) print('show fun') a1 = Rectangles(20,30) print(a1.area()) print(a1.areas)# 装饰器 property Rectangles.func()# 不用实例化,不能使用类属性和方法,类中的函数 Rectangles.show()# 不用实例化,可以使用类属性和方法
类查询
1、__class__ 查看类名 格式: 实例.__class__ 2、__dict__ 查看全部属性,返回属性和属性值键值对形式 格式:实例.__dict__ 3、__doc__ 查看对象文档,即类中(用三个引号引起来的部分) 格式:类名.__dict__ 4、__bases__ 查看父类 格式:类名.__base__ 5.__mro__ 查看多继承的情况下,子类调用父类方法时,搜索顺序 格式:子类名.__mro__ 实例.__class__.__mro__
**作业:代码运行时间案例**
import time def run_time(func): def new_fun(*args,**kwargs): t0 = time.time() back = func(*args,**kwargs) print('函数运行的时间: %s'%(time.time() - t0)) return back return new_fun @run_time def aaa(): time.sleep(5) aaa()
7. 文件
实例: f = open(r'test2.txt','w+') # 先清空在写 print(f.read()) f.close() f = open(r'test2.txt','w+') print(f.wrtie('hello world')) # 11 print(f.wrtie('hello world\n')) # 12 print(f.wrtie('hello world')) # 11 print(f.tell()) 指针所在的位置 print(f.seek()) 两个参数 一个是偏移量 f.close() # 注意 但在Windows系统中 一行结束的标志是\r\n 他会把\n转化成\r\n
**其他模式:`rb rb+ wb wb+ ab ab+` 加b的作用,以二进制的格式打开文件,进行上述操作** r w a
**操作****方法**读取指定大小的内容f.read()读取一行的内容f.readline()读取多行内容f.readlines()写入内容f.write(data)写入多行(需要自己加换行符)f.writelines(lines)立即刷新缓冲f.flush()获得游标位置f.tell()调整游标位置f.seek(position)
`with open...as...`
with open('myfile.txt') as f: # 赋值给 f这个变量 print(f) 一旦条跳出这个语句块 就自动就帮你关掉了 这就是上下文管理器 with能够自动关闭文件,不需要执行close方法 with open('text.txt','w+') as f: print(f.write('hello world\n')) print(f.write('hello world\n')) f.flush() print(f.tell()) f.seek(0,0) print(f.read()) Python 文件 flush() 方法是用来把文件从内存buffer(缓冲区)中强制刷新到硬盘中,同时清空缓冲区。 一般情况下,文件关闭后会自动刷新到硬盘中,但有时你需要在关闭前刷新到硬盘中,这时就可以使用 flush() 方法。 with open('text.txt','r+') as f: # 多行读取 print(f.readlines()[2]) # 可以切片 with open('text.txt','w+') as f: # 多行写入 f.writelines(['hello\n','world']) 怎么读出来 就怎么写进去 f.seek(0) 读写都会导致指针的移动 print(f.read()) 如果使用二进制写入 能否不用二进制读取? with open('test1.txt','wb+') as f: f.write('我们永远记得你'.encode()) f.seek(0) a =f.read() print(a) # print(a.decode()) 图片操作 with open(r"D:\Windows 10 Documents\Desktop\03.jpg",'rb+') as f: a = f.read() with open(r"test3.jpg",'wb+') as f1: f1.write(a) ---------------------------------------------------------------- # 一个with能不能打开多个文件? with open(r'test2.txt','w+') as f,\ open(r'test1.txt','a+') as f1: f.writelines(['hello\n','world']) f.seek(0) f1.seek(0) print(f1.read()) print(f.read()) with open(r'test1.txt','r') as f1: with open(r'test2.txt','w') as f2: a = f1.read() print(a) f2.write(a)
文件的编码处理(了解)
errors='ignore' (忽略报错) with open(r'C:\Users\lilulu\Desktop\第6课.md','r',encoding='gbk',errors='ignore') as f: print(f.read()) with open(r'test2.txt','w',encoding='utf-8') as f: f.write('哈哈') 加‘,,,,,,’ f.flush() with open(r'test2.txt',encoding='ascii',errors='ignore') as f1: print(f1.read())
stringIO与bytesIO
io Input/Output 输入,输出 假的文件 临时文件 内存中读数据是非常快的 # io可以临时储存一些东西 ------字符串 import io myio = io.StringIO() # 创建一个对象进行保存读取 myio.write('hello') # myio.seek(0) print(myio.readlins()) print(myio.getvalue()) 临时的 myio.close() # 就没有了 一次性 ------字节 bio = io.BytesIO() bio.write(b'fdsfdsafds') print(bio.getvalue()) # 了解一下 运用场景 简单来说,就是在内存中虚拟一个文件的感觉 譬如以前要从某个接口中下载一个文件,然后读取这个文件写入到数据库中。总要在本地随机一个文件名,然后写,读 ,删,现在则没有那么麻烦,直接内存中就搞定
8. 异常
异常基础
在 Python 中所有的异常都是继承自 BaseException 直接分为四大类: SystemExit:Python退出异常 KeyboardInterrupt: 键盘打断(Ctrl+C) GeneratorExit: 生成器退出 Exception: 普通异常(只会使用这部分的异常)
异常处理
try: with open('test.txt','r'): pass except:# File print('发生了异常') # 捕获具体的异常 try: a # 1/0 # print(‘nihao’) # 语法错误捕获不到 except NameError:# 只能捕获具体异常 漏写的会打印出来 print('类型错误') except ZeroDivisionError: print('分母不能为0') except Exception:# 代码里边异常的一个基类 print('未知错误') else: print('没有错误,触发else') finally: print('不管有没有错误,都会执行')
raise
try: raise TypeError except Exception: print('未知错误类型') if name=='name':# 自己制造错误, raise TypeError('这是错误的') ------------------------------------------------
自定义 异常类型 当存在的异常类型满足不了我们的需求是 我们是不是可以自己定义异常类型 class ZhiyouError(Exception): pass def func(name): if name == 'haha': print("非常好") else: raise ZhiyouError('buxing') try: func() except ZhiyouError as e: print(e) as 相当于取别名
断言
>>>a=1 >>>b=2 >>>a > b# False >>>a < b# True >>>assert a > b # 只要不是TRUE就报错,不满足就报错 1、assert 1 == 1 assert 1 == 2,'报错了' 2、断言语句是将调试断言插入程序的一种便捷方式 assert 的语法规则是: 表达式返回 True 不报错 表达式返回 False 报错 报 AssertionError def func(): # raise 类似,返回的是布尔值 FALSE报错,TRUE正常执行 assert name!='name'# 等于就报错 def func(a): assert isinstance(a, list), '输入内容必须是列表' # 下面的操作都是基于前提:input 必须是 list if len(a) == 1: print(1) elif len(a) == 2: print(2) else: print(3) func((1,2,3))
9. 迭代器和生成器
迭代器
迭代
for迭代变量in 迭代变量
迭代器=iter(可迭代对象)
下个值=next(迭代器)
StopIteration
生成器
def my_gen(): print('111') yield 1 print('22') yield 2 print('333') yield 3 g= my_gen() print(next(g)) print(next(g)) print(next(g)) print(next(g)) # 第四次抛出StopIteration异常
10. 正则
方法
findall方法
import re aaa='123456@163.com' my = re.findall(r'^[a-zA-Z0-9]+@[a-zA-Z0-9]+\.com$',aaa) # 去掉@或者cn 不能匹配到 # 通过自己写的规则,匹配想要的字符串 # python取消转义:\? 取消正则表达式语法的转义
在字符串中找到正则表达式所匹配的所有子串,并返回一个列表 ,如果没有找到匹配的,则返回空列表
match方法
re.match 尝试从字符串的起始位置匹配一个模式,匹配成功 返回的是一个匹配 对象(这个对象包含了我们匹配的信息),如果不是起始位置匹配成功的话, match()返回的是空, 注意:match只能匹配到一个
a = "python123123java" print(re.match('python',a)) print(re.match('python',a).group())# 查看匹配的字符 print(re.match('123',a)) print(re.match('python',a).span())# 匹配字符的下标取值区间
search方法
re.search 扫描整个字符串,匹配成功 返回的是一个匹配对象(这个对象包含了我们匹配的信息) 注意:search也只能匹配到一个,找到符合规则的就返回,不会一直往后找
print(re.search('123',a))# yes print(re.search('cc',a))# None print(re.search('python',a).group()) print(re.search('python',a).span())
re.match与re.search的区别
re.match只匹配字符串的开始位置找,如果字符串开始不符合正则表达式,则匹配失败, re.search:匹配整个字符串,如果一直找不到则,返回是空的,没有结果
元字符
单字符匹配
.匹配任意1个字符(除了\n)
[]匹配 [] 中列举的字符
\d匹配数字,即0-9
\D匹配非数字,即不是数字
\s匹配空白,即 空格,tab键
\S匹配非空白
\w匹配单词符,即a-z、A-Z、0-9、_
\W匹配非单词字符
代表数量的元字符
*匹配前一个字符出现0次或者无限次,即可有可无
+匹配前一个字符出现1次或者无限次,即至少有1次
?匹配前一个字符出现0次或者1次,即要么有1次,要么没有
{m}匹配前一个字符出现m次
{m,}匹配前一个字符至少出现m次
{m,n}匹配前一个字符出现从m到n次
代表边界的元字符
^匹配字符串开头
$匹配字符串结尾
\b匹配一个单词的边界
\B匹配非单词边界
分组匹配
| 匹配左右任意一个表达式
(ab)将括号中的字符作为一个分组
贪婪和非贪婪
正则默认都是用贪婪模式去匹配数据的,就是尽可能多的匹配符合要求的数据, 在非贪婪模式下,始终找最短匹配
a = '' b = '000 ddd ' print(re.findall(r'',b))# 贪婪 print(re.findall(r'',b))# 加上?变成非贪婪 print(re.findall(r'-(\d+)(.+-)','-123456789-')) print(re.findall(r'-(\d+?)(.+-)','-123456789-'))
import re aa = '<img src="https://rpic.douyucdn.cn/live-cover/roomCover/2019/02/14/7205b97c8db9ddf9109153f294f14b21_big.jpg?x-oss-process=image/format,webp" class="DyImg-content is-normal ">' a = re.search(r"https://.*?\.jpg", aa) b = a.group() import requests rc = requests.get(b) qiye = rc.content with open('test.jpg', 'wb') as f: f.write(qiye) -------------------------------------- a = '''<img src="https://img.tupianzj.com/uploads/allimg/202005/9999/184cb9395c.jpg" id="bigpicimg" alt="">''' b = re.findall(r'src="(https:.*?\.jpg)"', a) # qiye = re.findall(r'<img src="(.*?\.jpg)"', a) r'<img src="([^"]+\.jpg)"' print(b) import requests rc = requests.get(b[0]) qiye = rc.content with open('test.jpg', 'wb') as f: f.write(qiye) -------------------------------------------- import re # 1----9 \d # 10----99 [1-9]\d # 100----199 1\d{2} # 200----249 2[0-4]\d # 250---255 25[0-5] for i in range(256): a = str(i) a = re.match(r"^(25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$", a) print(a.group()) ------------------------------------------ 手机号 bb = '18390970027' bbb = re.match(r'1[35678]\d{9}',bb) print(bbb.group())
列子
b = '张三天在玩4399小游戏,张三 hello 玩的.很开心' ress = re.findall(r'张三.',b)# .任意一个字符 ress1 = re.findall(r'[54]',b) ress1 = re.findall(r'\d',b)# 匹配数字,单个字符,单个元素 ress1 = re.findall(r'\D',b)# ress1 = re.findall(r'4*',b)# 匹配前一个字符出现0次或者无限次,即可有可无 ress1 = re.findall(r'4+',b)# 匹配前一个字符出现1次或者无限次,即可有可无 ress1 = re.findall(r'三{2}',b)# 匹配前一个字符出现m次 ress1 = re.findall(r'三{1,}',b)# 匹配前一个字符出现从m到n次 ress1 = re.findall(r'三{1,2}',b)# 匹配前一个字符出现从m到n次 ress1 = re.findall(r'^张三',b)# 匹配字符串开头 ress1 = re.findall(r'心$',b)# 匹配字符串结尾 ress1 = re.findall(r'\bhello\b',b)# 匹配一个单词的边界 ress1 = re.findall(r'he\Bll',b)# 匹配一个单词的边界 ress1 = re.findall(r'he\Bll',b)# 匹配一个单词的边界 print(ress1)
11. 数据库
MySQL
库操作
进入与退出
mysql –uusername -ppassword
exit
查看当前在哪个数据库
select database;
显示所有的库
show databases;
创建库
create database [if not exists] db_name;
删除库
drop database [if exists] db_name;
进入数据库
use db_name;
表操作
显示所有的表
show tables;
显示创建表的信息
show create table tb_name;
desc tb_name;
创建表
create table [if not exists] tb_name (create definition…);
数值类型
TINYINT
SMALLINT
MEDIUMINT
INT
BIGINT
FLOAT(M,N)
DOUBLE(M,N)

字符类型
char(size)
VARCHAR(SIZE)
TINYTEXT/TINYBLOB
TEXT/BLOB
LONGTEXT/LONGBLOB
ENUM

时间日期类型
date
time
datetime
timestamp
year
CREATE TABLE `mytest` ( `text` varchar(255) DEFAULT '' COMMENT '内容', `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间' ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

约束条件
1. default
插入数据的时候,如果没有明确为字段赋值, 则自动赋予默认值
在没有设置默认值的情况下,默认值为NULL
CREATE TABLE tb( id int default ‘a’ , name varchar(20) );
2. not null
限制一个字段的值不能为空, Insert的时候必须为该字段赋值
字符不等于NULL
CREATE TABLE tb( id int not null, name varchar(20) );
3. unique key
限制一个字段的值不重复, 该字段的数据不能出现重复的
确保字段中值的唯一
CREATE TABLE tb( id int unique key, name varchar(20) );
4. primary key
通常每张表都需要一个主键来体现唯一性 每张表里面只能有一个主键
主键 = 非空 + 唯一
CREATE TABLE tb( id int primary key, name varchar(20) );
5. auto_increment
自动编号,和主键组合使用, 一个表里面只能有一个自增长
auto_increment 要求用在主键上
CREATE TABLE tb( id int auto_increment, name varchar(20) );
6. 外键约束
保持数据的一致性 我有的你一定有, 你没有的, 我绝对没有
1. B表中的id_b字段,只能添加 id_a中已有的数据。 2. A表中id_a 被参照的数据, 不能被修改和删除
CREATE TABLE a( id_a int primary key, name varchar(20) );
CREATE TABLE b( id_b int primary key, name varchar(20), foreign key (id_b) references a(id_a) );

删除表
drop table tb_name;
表结构修改
修改表名:alter table 表名 rename to 新表名;
修改字段名:alter table tb_name change name new_name data_type;
修改字段类型:ALTER TABLE tb_name MODIFY field_name data_type;
加字段:ALTER TABLE tb_name ADD [COLUMN] field_name data_type;
删除字段:ALTER TABLE tb_name DROP [COLUMN] field_name;
表关系
一对一关系
用外键的方式, 把两个表的主键关联
#建立详细学生表: create table student_details( id int primary key, sex varchar(20) not null, age int, address varchar(20) comment '家庭住址', parents varchar(20), home_num varchar(20), foreign key (id) references student(s_id) );
一对多关系
通过外键关联来实现这种关系。
##创建学院表 create table department( d_id int primary key auto_increment, # 学院id d_name varchar(20) not null # 学院名);
#创建学生表 create table student( s_id int primary key auto_increment, # 学生id s_name varchar(20) not null, # 学生名字 dept_id int not null, # 所属学院 id foreign key(dept_id) references department(d_id) #外键 );
多对多关系
对于多对多关系,需要创建中间表实现。
#建立课程表: create table cours( cours_id int primary key auto_increment, cours_name varchar(20) not null );
#建立学生表表: Create table student( s_id int primary key auto_increment,s_name varchar(20) not null );
# 选课表 (中间表) create table middle( s_id int, #用来记录学生id cours_id int, #用来记录 课程id primary key(s_id,cours_id), # 联合主键 foreign key(s_id) references student(s_id), # 关联学生id foreign key(cours_id) references cours(cours_id) # 关联 课程id );
insert into cours values (1, ’python编程’), (2, ’大学英语’), (3, ‘音乐鉴赏’); insert into `select` values(1,3); 表示学号为一的同学选择了音乐鉴赏这门课程
表中数据操作
C(Create)
指定字段插入
INSERT INTO tb_name(field_name) VALUES (field_values);
全字段插入
INSERT INTO tb_name VALUE (all_values);
多行插入
INSERT INTO tb_name(field_name) VALUES (value_1), (value_2), …;
R(Read)
指定字段查询
SELECT field_names FROM tb_name;
全字段查询
SELECT * FROM tb_name;
带条件的查询
SELECT field_names FROM tb_name WHERE conditions;
筛选条件
比较运算符
等于: =
不等于: != 或 <>
大于: >
大于等于: >=
小于: <
小于等于: <=
IS NULL
IS NOT NULL
逻辑运算符
AND 与
OR 或
NOT 非
其他操作
排序(order by)
SELECT columns FROM tb_name ORDER BY col [asc/desc] ;
正序:asc(默认)
倒序:desc
限制(limit)
SELECT columns FROM tb_name LIMIT start, count ;
LIMIT count;
LIMIT start, count;
去重(distinct)
SELECT DISTINCT FROM tb_name;
模糊查询 like ‘%’
任意多个字符: %
任意一个字符: _
范围查询
连续范围: BETWEEN a AND b
a <= value <= b
间隔返回: IN
a in (10, 20, 30 […])
聚合与分组
分组查询
统计个数:COUNT(column)
最大值:MAX(column)
平均值:AVG(column)
求和:SUM(column)
最小值:MIN(column)
列出字段全部值:GROUP_CONCAT(column)
Select 字段 from 表 group by 字段;
Select 字段,count(*) from 表 group by 字段
在分组的情况下,只能够出现分组字段和聚合字段 其他的字段没有意义,会报错!
聚合筛选
Select 字段1 from 表名 group by 字段1,字段2 having 字段2>=80;
加having条件表达式,可以对输出的结果做出限制
聚合筛选执行过程
先是执行:where
然后执行:聚合函数和别名
最后执行:having
子查询
将一个查询的结果留下来用于下一次查询 ( select 中嵌套 select )
1)嵌套在查询内部 2)必须始终出现在圆括号内
#将求出的平均年龄的SQL语句用于查找大于平均年龄的语句中 select * from students where age > (select avg(age) from students);
连接查询
内连接
无条件内连接
第一张表种的每一项会和另一张表的每一项依次组合
无条件内连接,又名交叉连接/笛卡尔连接
select * from student [inner] join scoren
有条件内连接
有条件内连接: 在无条件内链接的基础上,加上一个on子句 当连接的时候,筛选出那些有实际意义的记录来进行组合
Mysql> select * from student inner join scoren -> on dept_id = id;
外连接
左外连接: (以左表为基准)
两张表做连接的时候,在连接条件不匹配的时候 留下左表中的数据,而右表中的数据以NULL填充
mysql> select * from student left join department -> on dept_id= d_id;
右外连接: (以右表为基准)
对两张表做连接的时候,在连接条件不匹配的时候 留下右表中的数据,而左表中的数据以NULL填充
mysql> select * from student right join department -> on dept_id= d_id;
U(Update)
注意:一定要写where条件,不然会修改表中全部数据
修改所有数据
UPDATE tb_name SET field_1=value_1;
修改多个
UPDATE tb_name SET field_1=value_1, field_2=value_2 …;
修改满足条件的数据
UPDATE tb_name SET field_1=value_1 WHERE conditions;
D(Delete)
删除表中所有数据
DELETE FROM tb_name;
删除表中满足条件的数据
DELETE FROM tb_name WHERE conditions;
python与MySql交互
连接
导入模块:import pymysql
建立连接:pymysql.connect(**dbconfig) 连接是不能操作数据库的,需要用连接生成游标来操作 db_config = { ‘host’:’ip’, ‘port’:port, 'user': '账号', 'password': '密码', 'db': '数据库名', 'charset': 'utf8', }
创建游标: connection.cursor()
执行SQL语句:cursor.execute(sql) SQL语句都是通过这个方法执行
获取结果:cur.fetchall()
案例

Redis
库操作
进入与退出
连接redis:redis-cli、端口号6379
退出:exit
切换数据库:select n
数据库没有名称,默认有16个,通过0-15来标识,连接redis默认选择第一个数据库
操作服务端:sudo service redis start/stop/restart
数据操作
通用
查看所有的key:keys *
删除键值对:del key,exists key 查看key是否存在
改名:rename key new_key
设置过期时间:expire key seconds
ttl 查看时间 persist key 删除过期时间
String类型
string是redis最基本的类型,一个key对应一个value
设置数据:set key value
设置多个 mset key1 val1 key2 val2
查看数据:get key
获取多个mget key1 key2
追加数据:append key value
删除数据:del key
运算
incr num +1 decr num -1 incrby num 100 decrby num 100
List类型
List类型是一个字符串列表,可以在列表头部或尾部添加、删除数据,在插入数据时,如果该键并不存在,redis将为该键创建一个
添加数据:rpush key value [value…],lpush key value [value…] ---- 头部添加数据
查看数据:lrange key start stop,lindex key index ---- 查看某个数据
修改数据:lset key index value
删除数据:rpop key,lpop key ---- 头部删除数据
指定删除 lrem key count value
Hash类型
添加数据:hset key field value
查看域值:hget key field hgetall key ---- 查看所有的field和value
查看所有的value:hvals key
查看所有的field:hkeys key
删除 hdel user field
查看长度 hlen user
查看类型 type user
设置多个 hmset user name xiaohua age 12
获取多个hmset user name age
Set类型
Set类型为无序的字符集合,元素具有唯一性,不重复。
添加数据:sadd key member [member …]
查看数据:smembers key
随机删除:spop key
指定删除:srem key member [member …]
移动制定元素 smove set1 set2 2
判断集合是否存在 val smembers key val
获取集合的个数 scard key
随机选取 srandmember key
交集 sinter set1 set2 sinterstore newset set1 set2
并集 sunion set1 set2 sunionstore newset set1 set2
差集sdiff set1 set2 sdiffstore newset set1 set2
Zset类型
每一个成员都会有一个分数与之关联,成员是唯一的,但是分数可以重复
添加数据: zadd key score member [score2 member2 …] zrangebyscore key min max -- 通过scores值查看
查看数据: zrange key start stop 反序查看zrevrange set1 0 -1 正序查看 zrank set1 0 -1
zrangebyscore key min max -- 通过scores值查看 查看权值 zscore set1 member
删除数据:zrem key member [member …]
通过索引删除多个数据:zremrangebyrank key min max zremrangebyscore key min max -- 通过scores值删除
python与Redis交互
连接
安装python包redis: pip install redis
连接redis:Redis.StrictRedis(连接数据库的配置)
在程序操作的数据为bytes类型,加入decode_responses=True,写入的数据为str类型
数据操作
MongoDB
库操作
进入与退出
连接mongodb :mongo、端口号27017
退出:exit
显示所有库: show dbs
查看所在库: db
切换/创建数据库: use 数据库名称
删除库:db.dropDatabase()
集合操作
显示当前数据库的集合: show collections
创建集合: db.createCollection(name)
删除集合: db.集合名称.drop()
文档操作
添加文档
db.集合名称.insert(document)
例: db.student.insert({'_id':1, name:'xiaoming', age:18}) 添加多条文档 db.student.insert([ {name:xiaoming', sex:'男', age:16}, {name:’xiaobai', sex:'男', age:18}, {name:’moran‘, sex:’女', age:18}, ])
查询文档
db.集合名称.find([conditions])
db.集合名称.find([conditions]) 查看集合中全部数据: db.student.find() 格式化显示: db.student.find().pretty() 查看满足条件的数据: db.student.find({name:'xiaoming'},{age:1/0}) 条件: and条件 {$and:[{expression1}, {expression1}, ...] } or条件 {$or:[{expression1}, {expression1}, ...] } and和or混用 db.table.find({$or:[{$and:[{sex:'女'}, {age:18}]},{$and:[{sex:'男'}, {age:{$gt:18}}]}]}) 操作符 $ne 不等于 $gt 大于 $lt 小于 $gte 大于等于 $lte 小于等于 例子:db.user.find({'age': {'$ne': 45}})
修改文档
db.集合名称.update(<query>, <update>, {multi:<boolean>})
db.集合名称.update(<query>, <update>, {multi:<boolean>}) 修改一条数据: db.table.update({sex:'男'}, {age:20}) 指定属性修改: { $set: {age:20} db.table.update({name:'xiaoming'}, {$set: {age:666, sex: 'xx'}} ) 更新集合中所有满足条件的文档: { multi: true } db.table.update({sex:'男'}, {$set:{sex:'女'}}, { multi:true} )
删除文档
db.集合名称.remove(<query>, {justOne:<boolean>})
db.集合名称.remove(<query>, {justOne:<boolean>}) 删除集合中所有的文档: db.table.remove({}) 删除集合中满足条件的所有文档 db.table.remove({sex: '男'}) 只删除集合中满足条件的第一条文档: { justOne: true} db.table.remove({sex:'男'}, { justOne:true} )
python与MangoDB交互
连接
pip install pymongo
建立连接:client = pymongo.MongoClient()
指定数据库:db = client[数据库名
指定集合:collection=db[集合名]
操作
查找一条文档: find_one() 查找所有:find() 只是一个对象 可以用for 遍历出来
添加一条文档:insert_one 添加多条:insert_many()
修改一条文档: update_one 修改多条:update_many()
删除一条文档:delete_one 删除多条:delete_many()
12. Linux常用命令
查看和跳转
ls :查看当前目录下的文件和目录(我能看到什么) pwd :查看当前路径(我在哪) whoami :当前用户(我是谁) cd :跳转路径(可以接相对路径和绝对路径) cd .. :返回上一级路径 cd / :回去跟目录 cd ~ :回到当前用户的家目录 cd - :返回上一次所在的目录
文件操作
touch :新建文件 cat 文件名 :打开文件 cp 源文件 目标文件 :复制文件 mkdir 文件夹名 :创建文件夹 rm 文件名 :删除文件 rmdir 文件夹名 :删除文件夹 mv test1 test2 :把test1移到test2(对于文件夹的操作) mv file1 file2 :用file1的内容覆盖掉file2的内容
Vim使用
命令模式:操作文档
命令模式下: 移动光标 gg 到文件第一行 G 到文件最后一行 (Shift + g) ^ 非空格行首(和I的区别是不会进入输入模式) 0 行首(数字0) $ 行尾 home 行首 end 行尾 shift+zz保存并退出 操作文档:复制和粘贴 yy 复制整行内容 3yy 复制3行内容 yw 复制当前光标到单词尾内容, 复制一个单词,和符号区分 p 粘贴
输入模式:编辑文档
进入编辑模式,命令模式下: i 从光标所在位置前面开始插入 I 在当前行首插入 a 从光标所在位置后面开始输入 A 在当前行尾插入 o 在光标所在行下方新增一行并进入输入模式 O 在当前上面一行插入 进入输入模式后,在最后一行会出现--INSERT—的字样
末行模式:保存或退出文档
退出 :w 末行模式, w保存. :wq 末行模式,wq 保存退出 :q 末行模式,q 直接退出 :q! 末行模式,q! 强制退出,不保存 x保存并退出
进入 vim filename
删除
dd 剪切 dw 删除从光标开始的一个单词 x 删除光标所在字符 u 撤销上一次操作 ctrl + r 撤销 u
查找
/ 命令模式下输入:/ 搜
移动光标
h 光标前移 l 光标后移 j 光标下移 k 光标上移
块操作
v 块选择,可以对文档操作 ctrl + v 列块选择
替换 末行模式
:s/s1/s2 替换当前行第一个s1为s2 :s/s1/s2/g 替换当前行中所有s1为s2 :%s/s1/s2/g 替换文中所有s1为 s2
13. 常用模块
导入模块
import …
import … as …
from … import …
`OS`模块
os.getcwd()显示当前路径
listdir(path)展示当前目录内容
os.chdir(path)改变当前路径
os.mkdir(文件名)创建目录
os.rmdir(文件名)删除目录
os.system()使用Linux命令
os.remove(文件名)删除文件
os.rename重命名
os.path.join(path1,path2......)路径拼接
os.path.dirname所在的目录、父级目录
os.path.basename基本短路径
os.path.abspath绝对路径
os.path.relpath相对路径
os.path.getsize资源大小
os.path.exists路径是否存在
so.path.isdir是否是目录
os.path.isfile是否是文件
os.path.isabs是否是绝对路径
os.path.getctime、getatime、getmtime、资源时间:创建、访问、修改
# 绝对路径 # 相对路径 # 路径拼接操作 b = os.path.join('C:Users','qiye') print(b) os.mkdir('woshizhu') # 新建文件夹 os.rename('woshizhu','haha') # 修改文件夹 print(dir(os)) # 查看它的一些用法 import shutil shutil.move('haha',r'C:\Users\lilulu\Desktop\python讲义') # 移动文件 # 一定不要跟模块名重名 a = '0' for i in range(1000): os.mkdir(a) # 一直自动创文件夹
json
注意事项
操作
hashlib

base64

datetime


logging
日志等级
formatter格式
组件使用

14. 进程和线程
创建线程
实例Thread类

继承Thread类

Join & setDaemon
join : 阻塞调用程序 , 直到调用join () 方法的线程执行结束, 才会继续往下执行

setDaemon() 与 join() 基本上是相对的 , join会等子线程执行完毕 ; 而setDaemon则不会等

线程间的通信
线程间全局变量的共享

共享内存间存在竞争问题

使用锁来控制共享资源的访问


队列
基本概念一个入口,一个出口 先入先出(FIFO)
线程池
线程池的实线

效果演示

内置线程池

池的其他操作
操作一: close - 关闭提交通道,不允许再提交任务
操作二: terminate - 中止进程池,中止所有任务