find:从左往右,只要遇到一个符合的就返回位置,如果没有找到合适的就返回-1
rfind:从右往左找
index:也是查找,但是找不到会报错,所以一般用find
count:用于计数 src.count('.')查找.的个数
判断: startwith,endwith,isalpha,isdigit,isalnum,isspace(返回的都是布尔值)
字母数字组合
filename = '' s = "qqwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890" name = '' for i in range(6): name += s[random.randint(0, len(s)-1)] filename += name + '.jpg' print(filename)
repalce:替换,(old,new,count),默认全部替换,count为替换的个数
spilt:切割: s.spilt(' ') 以什么为切割 ' ', 后面可以添加 分割次数 ,返回列表 s.spilt(' ', 1)
rsplit:从右开始切割 splitline:按行切割
.upper转换为大写 .title每个单词的首字母转换为 大写 .lower 转换为小写 .capitalize 第一个字母大写
.center(30) 居中对齐 .ljust 左对齐 .rjust 右对齐
.join 字符串拼接 针对列表,返回字符串
两个列表相加: + 或者 .extend
列表删除: .pop() 默认删除最后一个,或者可以用列表的索引删除 , .remove() 删除指定的数据,只删除符合要求 的第一个数据
Insert (位置,元素)插入 index返回的是元素的下标
clear() 清空,之后还能用 del list 直接删除了该表
sort 排序,sort也有resverse ,默认False,升序 resverse :只是简单的翻转
只有count 和 index方法 也有min,max内置函数也可以用
字典:键值对
pop('键') 返回的是值,删除对应键值对 popitem() 删除最后一个,返回的是一个元组(键和值),为空会报错
[key] = values setdefault(只能添加,不能进行修改) update 合并两个键值对
集合:
都是删除元素 .discard() 不是成员不报错 remove() 不是成员会报错
Intersection 交集 union 并集 差集 difference
列表推导式对列表进行分组:
list = [i for i in range(1, 101)] #创建一个1-100的列表 list1 = [list[x:x+3] for x in range(0, 101, 3)] # 进行切割,3个一个组 print(list1)
取出两个含e的数组:
names = [['Tom', 'Billy', 'Jeffernson', 'Andrew', 'Wesley'], ['Alice', 'Jill', 'Ana', 'Wendy'] ] list = [m for i in names for m in i if m.count('e') >= 2] print(list)
可变参数:*args **kwargs
在调用的时候加一个*,用于拆包(拆列表,元组的包) *args 又用于打包
可变参数 **kwargs, 需要关键字上传 (bookname = '红楼梦',author = '曹雪芹')类似
** 拆的是字典的包
def show_book(**kwargs): for m, n in kwargs.items(): print(m, n) show_book(name='西游记', author='吴承恩', price=48) book = {'name': '红楼梦', 'author': '曹雪芹', 'price': 48} show_book(**book) #book是字典,进行拆包,否则会报错
不可变类型:当改变变量的值的时候,地址发生了改变
int,str,float,bool,tuple
可变类型:内部的值发生改变,但是地址没有改变
list ,dict,set
可变类型不需要加global,不可变的需要添加
全局与局部变量:
申明在函数外面的称为全局变量,声明在函数内部的变量称做局部变量
在函数内部,无法修改全局变量,要在函数内部修改全局变量,需要用关键字global
sys.getrefcount() 检测多少个指针指向某个变量,检测本身也要算一个
没有指针指向就会被回收
python中,值是靠引用得到的
函数只是一段可执行代码,编译后就固化,每个函数内存中只存在一份实例,得到的函数入口便可以执行函数,函数还可以嵌套定义,即一个函数内部可以定义另外一个函数,有了嵌套结构,就会出现闭包问题。
嵌套函数:locals() 表示查看函数中的局部变量(字典的形式),内部函数可以使用外部函数的变量,但是无法修改,只能修改自己的参数,需要修改外部函数的变量时,关键字 nonlocal
查看全局变量 用 globals()
内存——外层——全局——系统(变量和函数查找路径)
闭包: 1、嵌套函数 2、内部函数引用外部函数的变量 3、返回值是内部函数
装饰器:
遵循开放封闭原则,不改变原函数扩展函数功能
def decorater(func): def wrapper(*args,**kwargs): func(*args,**kwargs) #调用原函数,所以会先打印毛坯房 print('装修房子') return wrapper # 返回内部函数(是闭包) @decorater #house = decorater(house) def house(address): print('毛坯房') house()
装饰器作用:
1、引入日志记录 2、函数执行时间的统计 3、在执行函数前的预备处理 4、执行函数后的清理功能
5、权限校验等场景 6、缓存
带参的装饰器:如果原函数有参数,则装饰器内部函数也要有参数
但是调用函数可能传的值的个数不固定,用*args,**kwargs
装饰器带参数:
def outer_check(time): print('-------------------1') def inter_check(action): print('----------2') def check(): if time > 23: return action() else: print('权限不足') print('---------3') return check return inter_check @outer_check(24) def play(): return '开始' print(play())
匿名函数:lambda函数,一般作为参数来使用
高阶函数:一个函数的参数是另外一个函数
list = [('lily', 12), ('rose', 23), ('tony', 18)] print(max(list, key=lambda i: i[1])) # 年龄最大
filter:
list1 = [('lily', 25), ('rose', 23), ('tony', 18)] s = list(filter(lambda i: i[1] > 20, list1)) # 要求返回值是布尔值,条件为True,需要强转为list print(s)
map:
h = map(lambda i: i[1] + 1, list1) # 提取list1中符合条件的内容,保存为列表 print(list(h))
reduce:
from functools import reduce r = reduce(lambda x, y: x * y, [1, 2, 3, 4, 5, 6]) # 用于计算 print(r)
纯文本:r,w 纯文本、图片、音乐、电影: rb 或者wb
文件复制:
with open(r'C:\Users\DELL\Desktop\截屏\R-C (1).jpg', 'rb') as photo: # 读取文件内容 container = photo.read() with open(r'C:\Users\DELL\Desktop\R-C (1).jpg', 'wb') as copyphoto: # 将文件写入 copyphoto.write(container) print('文件复制完成')
os.path.join() # 文件拼接,后面可以添加多个
s = r'C:\Users\DELL\Desktop\截屏\R-C (1).jpg' # print(s) r = os.path.split(s) # 切割,只切一刀在文件名前,返回元组
splitext() # 分割文件与扩展名 os.path.getsize() # 获取文件大小,单位字节
os.getcwd() 获取当前目录 dirname(_ _file __) 获取当前文件路径(绝对)
isabs() 是否是绝对路径 isfile() 是否是文件 isdir()
删除文件夹:
path = r'C:\Users\DELL\Desktop\p1\p2' list1 = os.listdir(path) for i in list1: # 删除文件,先删除文件夹里的东西 path1 = os.path.join(path, i) s = os.remove(path1) m = os.rmdir(path) # 然后在删除文件夹本身 print(m)
s = os.listdir(r'C:\Users\DELL\Desktop\概率论与数理统计') # 展示文件下的东西,并保存到列表 print(s) if not os.path.exists(r'C:\Users\DELL\Desktop\hhhhh'): m = os.mkdir(r'C:\Users\DELL\Desktop\hhhhh') # 创建文件夹 d = os.rmdir(r'C:\Users\DELL\Desktop\hhhhh') # 只能删除空的文件夹 print(d) f = os.removedirs(r'C:\Users\DELL\Desktop\hhhhh')
切换文件夹:
path = r'C:\Users\DELL\Desktop\p1' path2 = os.chdir(path) # 用于切换路径chdir m = os.getcwd() print(m)
文件夹的复制:
import os path = r'C:\Users\DELL\Desktop\概率论与数理统计' path2 = r'C:\Users\DELL\Desktop\p1' def copy(src, target): if os.path.isdir(src) and os.path.isdir(target): filelist = os.listdir(src) # 获取文件夹里的内容 for file in filelist: # 遍历文件夹列表 path = os.path.join(src, file) # 拼接成完整的路径 if os.path.isdir(path): # 判断是文件夹还是文件 target_path = os.path.join(target, file) os.mkdir(target_path) # 创建文件夹 copy(path, target_path) # 是文件夹,进行递归调用 else: with open(path, 'rb') as restream: # 否则读取文件内容 container = restream.read() path1 = os.path.join(target, file) with open(path1, 'wb') as wstream: # 将读取的文件复制过去 wstream.write(container) else: print('复制完毕')
在循环过程中不断的推断后续的元素,不必创建完整的list,从而节省大量的空间,在python中,一边循环一边计算的机制称为生成器,generator
1、列表推导式
list2.__next__() # __next__得到一个元素(下一个) next(list2) # 或者系统内置的函数,调一次产生一个数字
只要函数中出现了yield关键字,说明函数不是函数,是生成器
调用函数并接收,得到的结果就是生成器
def fib(length): a, b = 0, 1 n = 0 while n < length: yield b a, b = b, a + b n += 1 return '没有更多的元素' # return 用于stop后面的提示信息 g = fib(5) print(next(g)) print(next(g)) print(next(g)) print(next(g)) print(next(g))
def task(n): for i in range(n): print('在搬{}块砖'.format(i)) yield def task2(n): for i in range(n): print('在听第{}首歌'.format(i)) yield g2 = task(10) g3 = task2(5) while True: try: next(g2) next(g3) except StopIteration as e: break
应用:协程
可迭代对象:生成器,元组,列表,集合,字典,字符串
1、迭代器是访问集合元素的一种方式,迭代器是一个可以记住遍历位置的对象,2、迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问结束。 3、迭代器只能往前不会后退,
可以被next()函数调用并不断的返回下一个值的对象成为迭代器
判断是否可迭代 isinstance()
正在上传…重新上传取消
类方法
1、定义依赖装饰器@classmethod
2、类方法的参数不是一个对象,而是类
print(cls)
3、类方法只可以使用类属性
4、类方法不能使用普通方法
类方法的作用:
只能访问类属性和类方法,可以在对象创建之前,如果需要完成一些动作(功能)
静态方法
1、需要修饰装饰器@staticmethod
2、静态方法是无需传递参数(cls,self)
3、只能访问类的属性和方法,无法访问对象的
4、加载时机同类方法
类方法和静态方法的区别
1、装饰器不同 2、类方法有参数,静态方法没有参数
魔术方法
1、__ init __:初始化魔术方法,触发时机:初始化对象时触发(不实例不触发)
2、__ new __:实例化的魔术方法 触发时机:在实例化时触发
3、__ call __:对象调用方法, 触发时机:把对象当成函数使用时,会默认调用该函数
4、__ del __:析构魔术方法 触发时机:当对象没有用的时候触发
5、__ str __: 触发时机:打印对象名,自动触发调用里面的内容,一定要加 return 想看到的内容
正在上传…重新上传取消
def __call__(self, *args, **kwargs): # __call__ 用于把对象当成函数使用 p = person('rose') p() # 执行的是call里面的函数
@property
@property装饰器,用于私有属性,使在外面可以正常的访问该属性,又达到私有的特点,要对私有属性进行修改时,直接在@属性.setter,但是必须先有@property
class Student: def __init__(self, name, age): self.name = name self.__age = age @property # 类似于getter的作用 def age(self): return self.__age @age.setter # 在上面一个函数上加setter ,同名 def age(self, age): if age > 0 and age < 10: self.__age = age else: print('年龄不在规定中。。。') def __str__(self): return '{}的年龄是{}'.format(self.name, self.__age) student = Student('小张', 7) student.age = 3 print(student.age) # 加装饰器,将私有的属性可以进行普通的访问
继承
class Staff: def __init__(self, sid, name, salary): self.sid = sid self.name = name self.salary = salary def __str__(self): msg = '工号:{},姓名:{},工资:{}'.format(self.sid, self.name, self.salary) return msg def calulator(self): return self.salary class Worker(Staff): def __init__(self, sid, name, salary, hours, hours_wage): self.hours = hours self.hours_wage = hours_wage super(Worker, self).__init__(sid, name, salary) # 继承上面的 def calulator(self): # 重写calulator方法 money = int(self.hours) * int(self.hours_wage) self.salary += money return '{}工人的工资为{}元'.format(self.name, self.salary)
多继承
python允许多继承,从左至右,深度优先
.__ mro __ 查看搜索执行顺序
isinstance() 实现多态,由于不同的类都可以传进去,进行判断,不是pet类的无法通过
def feed_pet(self, pet): if isinstance(pet, Pet): print('{}养了宠物{},今年{}岁了'.format(self.name, pet.nickname, pet.age)) else: print('不适合饲养哦!!!')
单例模式:通过重写__ new __函数每次调用该函数时,如果已经开辟过了,则不重新开辟空间,共用之前开辟的空间,内存的优化,不是所有的都需要单例模式
正在上传…重新上传取消
导包
__ init __,只要导入该包的时候,就会默认执行
# import sys # # print(sys.path) # print(sys.argv) import time # 时间戳 t = time.time() print(t) # 将时间戳转换为字符串 s = time.ctime(t) print(s) # 转换为元组 s1 = time.localtime(t) print(s1) # 元组转为时间戳 t2 = time.mktime(s1) print(t2) # 将元祖转换为字符串 t3 = time.strftime('%Y-%m-%d') print(t3) # 将字符串转为元组的方式 t4 = time.strptime('2022-05-03', '%Y-%m-%d') print(t4)
hashlib加密算法包
md5、sha256等算法都是不可逆的,将加密后的存入数据库,将用户输入的进行加密在与数据库的内容进行对比
msg = '你好' md5 = hashlib.md5(msg.encode('utf8')) print(md5.hexdigest()) shal = hashlib.sha256(msg.encode('utf8')) print(shal.hexdigest())
正则表达式:
re模块
match:从开头进行匹配 search:只匹配一次 findall :查找所有
sub(相当于replace) split(切割)
result = re.split(r'[,:]' ,'java:90,c:89') # 遇到, 或者:就切一下
res1 = re.match(r"<(\w+)>(.+)\1>$", msg) # \1匹配的是分组一,成对出现
phone = '010-12345678' res = re.match(r'(\d{3}|\d{4})-(\d{8})$', phone) print(res.group(1)) # group(1)表示的是第一组 print(res.group(2)) # group(2)表示的是第二组 msg = 'world
' msg1 = 'world
' res1 = re.match(r"<(\w+)><(\w+)>(.+)\2>\1>$", msg) print(res1.group(3))
基础:.任意字符 []范围 |或者 ()一组
量词: * >=0 + >=1 ? 0,1 {m}=m {m,}>=m {m,n} >=m ,<=n
预定义: \s space \S not space \d digit \w word [0-9a-zA-Z_] \W not word
引用: (\w+)(\d*) \1 \2 表示引用前面的内容
起名 (?P< name >\w+) (?P= name) 和引用的方法类似
贪婪和非贪婪
# 默认模式,贪婪模式 s = 'abc1233abc' res = re.match(r'abc(\d+?)', s) # 加上?就是非贪婪模式了 print(res.group(1))
自定义进程:(重写run方法)
from multiprocessing import Process class Myprocess(Process): def __init__(self, name): super(Myprocess, self).__init__() self.name = name # 重写run方法 def run(self): n = 1 while True: print('进程名字:', self.name) print('{}========='.format(n)) n += 1 if __name__ == '__main__': P = Myprocess('天天') P.start() P1 = Myprocess('张张') P1.start()
from multiprocessing import Process
Process(target=函数, name='名字',args = (给函数传递的参数))
对象调用方法:
process.start() 启动并执行线程
process.run() 只是执行,不会启动线程
terminate() 终止
非阻塞式
Pool :进程池
# 非阻塞式 def task(task_name): print('开始任务', task_name) start = time.time() time.sleep(random() * 2) end = time.time() return '线程名字:{},用时{},进程id:{}'.format(task_name, (end - start), os.getgid()) def callback_func(n): print(n) if __name__ == '__main__': pool = Pool(5) list1 = ['听音乐', '做作业', '洗衣服 ', '打游戏', '看书', '跳舞', '散步'] for i in list1: pool.apply_async(task, args=(i,), callback=callback_func) # apply_async用的非阻塞模式 pool.close() # 添加任务结束 pool.join() # 阻塞 print('over')
特点: 全部添加到队列中,执行完毕,立刻返回,并没等待其他进程执行完毕,但是回调函数callback要等待任务完成后才进行调用
阻塞式
if __name__ == '__main__': pool = Pool(5) list1 = ['听音乐', '做作业', '洗衣服 ', '打游戏', '看书', '跳舞', '散步'] for i in list1: pool.apply(task, args=(i,)) # 和apply_async类似,只有用的函数为apply pool.close() # 添加任务结束 pool.join() # 阻塞 print('over')
特点:添加一个执行一个,一个任务不结束,另外一个任务进不来
进程池:
pool = Pool(max) 创建一个进程池
pool.apply() 阻塞的
pool.apply_async() 非阻塞的
pool.close()
pool.join () 阻塞主线程,让主线程等执行完之后在执行
进程之间的通讯
import time from multiprocessing import Process def download(q): images = ['aaa.jpg', 'cat.jpg', 'dog.jpg'] for image in images: print('正在下载:{}....'.format(image)) time.sleep(0.3) q.put(image) def getfile(q): while True: try: file = q.get(timeout=3) # 设置超时用于结束循环 print('{}保存成功'.format(file)) except: print('保存完毕') break if __name__ == '__main__': q = Queue(5) # 通过队列进行通讯 p1 = Process(target=download, args=(q,)) p2 = Process(target=getfile, args=(q,)) p1.start() p1.join() p2.start() p2.join()
t = threading.Thread(target=download, name='aa', args=(1,)) # 启动和进程类似 t.start()
GIL:全局解释器 线程:'伪线程'‘(所以过分的强调速度时,python尽量用进程)
def task(): # 获取线程锁,如果已经上锁,其他的只能等待 lock.acquire() # 阻塞,上锁 for i in range(len(list1)): list1[i] = 2 time.sleep(0.3) lock.release() # 释放 if __name__ == '__main__': t1 = threading.Thread(target=task()) t2 = threading.Thread(target=task2()) t1.start() t2.start()
死锁:
在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并同时等待对方的资源,就会造成死锁,
a拿到一把锁,进入休眠,b拿到另外一把锁,两个锁又相互的依赖,两把锁被不同的线程占有,相互等待
避免死锁:解决办法:(资源先后使用不当)
1、重构代码 2、设置超时timeout解决
生产者与消费者:两个线程之间的通信(queue进行通信)
协程:微线程
进程>线程>协程 ——(协程是用生成器)
协程:耗时操作
耗时操作:网络请求,网络下载(爬虫), IO:文件的读写 阻塞
greenlet包,进行人工切换
import time from greenlet import greenlet def task(): for i in range(3): print('a>>>>>>>', i) g1.switch() # ,进入休眠,切换到task1 time.sleep(0.3) def task1(): for i in range(4): print('b>>>>>>>', i) g2.switch() time.sleep(0.3) if __name__ == '__main__': g = greenlet(task) g1 = greenlet(task1) g.switch()
gevent包:
import time import gevent from gevent import monkey monkey.patch_all() # 猴子补丁,gevent无法感知原生的sleep,猴子补丁会在运行前将它进行替换 def task(): for i in range(3): print('a>>>>>>>', i) time.sleep(0.3) def task1(): for i in range(4): print('b>>>>>>>', i) time.sleep(0.3) def task2(): for i in range(4): print('c>>>>>>>', i) time.sleep(0.3) if __name__ == '__main__': g = gevent.spawn(task) g1 = gevent.spawn(task1) g2 = gevent.spawn(task2) g.join() g1.join() g2.join()
yum search 软件名 查找有没有指定的软件 yum install 软件名 安装软件 yum remove 软件名 删除软件 yum info 软件名 查看已经安装的软件 xz -d 解压缩 tar -xvf 解归档
vim的三种模式 命令模式 i/a
编辑模式 ESC
-ctrl+y /ctrl+e 移动一行
ctrl+f/ ctrl+b 翻一页
0 光标到首行 $ 光标到尾行 /w 光标到下一个单词
dd 删除本行 100dd 删除100行
yy 复制光标所在行
p 粘贴 5p 粘贴五遍
u 撤销 ctrl+r 恢复
多文件模式: :ls :查看所有打开的文件 :b 数字 显示指定的文件
分屏 :vs 垂直拆分 :sp 水平拆分
:qa 全部退出 :wqa 保存退出
(ctrl +w两次)切换到不同的
vim -d 文件1 文件2 同时打开两个窗口并进行版本比较差异
git init 将文件夹初始化为git仓库
git add
将工作区的指定文件放入暂存区 git status 查看工作区和暂存区的状态
git commit -m '提交原因' # 将暂存区的内容添加到仓库
git log 查看提交日志(历史提交记录)
git checkout --
将暂存区的文件恢复到工作区 git reset --hard HEAD^ 回到上一个版本
git reset --hard
回到指定版本 git reflog 查看所有的历史和未来的版本,包括删除的版本
国内托管平台 :码云gitee /coding
git clone
git push 将本地代码推(上传)到服务器上
git pull 将服务器更新同步到本地
数据库:
索引:index 可以加速查询索引在用于经常查询筛选条件的列上建立索引
explain 执行计划 ,判断执行的效率
systemctl status mysql 启动数据库
restrict 不允许操作 cascade 级联操作
事务:要么全都不做,要么全部都做
begin; # 开启事务环境 delet from ... commit; # 提交,所有的操作全部成功 rollback # 回滚,事务的操作全部撤销
pip freeze > requirements.txt 输出重定向,将当前项目的依赖项放到requirements里面
装依赖包里面的文件里面的项目 pip install -r requirements.txt
import pymysql def mian(): conn = pymysql.connect(host='192.168.43.153', port=3306, user='root', password='539433', db='liangqiong', charset='utf8') try: with conn.cursor() as cursor: result = cursor.execute( "insert into student values ('S200','张召忠','男','19','计算机', 179)") if result == 1: print('添加成功') conn.commit() except pymysql.MySQLError as e: print(e) conn.rollback() finally: conn.close() if __name__ == '__main__': mian()
result = cursor.execute( "update student set 年龄 =%s where 学号=%s", (input('请输入年龄:'), input('请输入学号:'))))
完整性:实体的完整性:每一个实体都是独一无二的,没有冗余
参照的完整性:外键
域完整性:存储的数据都是有效的数据(数据类型、非空约束,默认值约束,检查约束)
ACID特性:
A atomicity 原子性: 不可分割
c Consistency一致性 事物前后状态一致
I Isolation 隔离性 多个事务不知道彼此的中间状态
D Duration 持久性 事物完成后反映带物理存储上
非关系性数据库: NO SQL
-文档数据库 MongoDB/ ElasticSearch
\键值对数据库 Redis
\图数据库\列族数据库
Redis KV数据库 -放内存 -单线程+异步I/O(多路io复用)
计算密集型应用 ——多进程+多线程
I/0密集型应用 ——单线程+异步I/O
1、进入redis安装目录,执行下面命令启动redis服务
./bin/redis-server redis.conf
2、通过redis-cli测试redis是否可用,在redis安装目录执行下面命令:
./bin/redis-cli
1、高速缓存数据 (用户经常使用的数据搬到内存)——热数据
2、实时排行榜 3、投票点赞 4、消息队列
redis-server --port 1234 --requirepass qiqi # 指定端口号和设置口令
redis-server 配置文件 > redis.log & #重定向性log
启动redis客户端
redis-cli -h 主机ip地址 -p 端口
主机:端口> auth 密码
redis-benchmark 基准测试,测试性能
可查看的网站 redisdoc.com
哈希码(数字签名) MD5/SHA1/SHA256