python新手总结(二)

random模块

随机小数

  • random
  • uniform

随机整数

  • randint
  • randrange

随机抽取

  • choice
  • sample

打乱顺序

  • shuffle

random.random() 生成:0<n<1.0

uniform(x,y) 一定范围的随机浮点数 (包左包右)

random.uniform(x,y)

randint(x,y) 随机整数 (包左包右)

randrange(x,y,z) 随机整数(包左不包右)

random.randrange(10,100,4) #输出为10到100内以4递增的序列[10,14,18,22...]

choice(seq) 从序列中获取一个随机元素,参数seq表示有序类型,并不是一种特定类型,泛指list tuple 字符串等

import random
random.choice(range(10)) #输出0到10内随机整数
random.choice(range(10,100,2)) #输出随机值[10,12,14,16...]
random.choice("I love python") #输出随机字符I,o,v,p,y...
random.choice(("I love python")) #同上
random.choice(["I love python"]) #输出“I love python”
random.choice("I","love","python") #Error
random.choice(("I","love","python")) #输出随机字符串“I”,“love”,“python”
random.choice(["I","love","python"]) #输出随机字符串“I”,“love”,“python”

shuffle(list) 用于将一个列表中的元素打乱

sample() 从指定序列中随机获取k个元素作为一个片段返回,sample不会改变原有序列

a='1232445566'
b=[1,2,3,4,4,5]
print(random.sample(b,2))
print(random.sample(a,2))

time 时间模块

time.strftime('%Y-%m-%d %H:%M:%S')

sys模块

sys 是与python解释器相关的

sys.path 寻找文件的路径

sys.modules 导入多少路径

在编译器不能运行

name=sys.argv[1]    # 有点类似input() 不过input是阻塞的
pwd=sys.argv[2]
if name='alex' and pwd =='alex3714':
print('执行以下代码')
else:
	exit()

os模块

print(os.getcwd()) # 在哪个地方执行这个文件,getcwd的结果就是哪个路径

removedirs
递归向上删除文件夹,只要删除当前目录之后,发现上一级目录也为空了,就把上一级目录删除
如果发现上一级目录有其他文件,就停止
os.listdir() (重要)列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方法打印

print(os.path.dirname(os.path.dirname(__file__)))#上一级再上一级目录,也就是工作区

序列化

得到一个字符串的结果,过程就叫序列化

字典/列表/数字/对象 -序列化-->字符串

为什么要序列化

  • 要把内容写入文件
  • 网络传输数据

eval不能随便用

dump dumps load loads

import json
dic={'aaa':'bbb','ccc':'ddd'}
str_dic=json.dumps(dic)  # 序列化
print(dic)
print(str_dic,type(str_dic))
with open('json_dump','w') as f:
# f.write(str_dic)       # 反序列化
        json.dump(dic,f)
ret=json.loads(str_dic)  # 反序列化
print(ret,type(ret))

with open('json_dump1') as f:
    print(type(json.load(f)))

json的限制

  • json格式的key必须是字符串数据类型,如果是数字为key那么dump之后会强行转成字符串数据类型

  • json格式中的字符串只能是双引号

  • json是否支持元祖,对元组做value的字典会把元组强制转换成列表

  • dic={'abc':(1,2,3)}
    str_dic=json.dumps(dic)
    print(str_dic)
    
  • json是否支持元组做key,会报错

pickle

  • pickle 支持几乎所有对象
dic={1:(12,3,4),('a','b'):4}
pic_dic=pickle.dumps(dic)# 序列化 看不见   bytes类型
print(pic_dic)
new_dic=pickle.loads(pic_dic)# 反序列化

对于对象的序列化需要这个对象对应的类在内存中
dump的结果是bytes, dump用的f文件句柄需要以wb的形式打开,load所用的f是'rb'模式
with open('pickle_demo','wb') as f:
    pickle.dump(alex,f)
with open('pickle_demo','rb') as f:
    wangcai=pickle.load(f)
    print(wangcai.name)
    
 with open('pickle_demo','rb') as f:
    while True:    # 不知道循环几次不能用for 用while
        try:
            print(pickle.load(f))
        except EOFError:
            break
            
import shelve  # 不建议使用
# 存值
f=shelve.open("shelve_demo")
f['key']={'k1':(1,2,3),'k2':'v2'}
f.close()
# 取值
f=shelve.open('shelve_demo')
content=f['key']
f.close()
print(content)

加密md5 sha1

# hashlib.md5()
# hashlib.sha1()
#md5是一个算法,32位的字符串 ,每个字符串是一个十六进制
# sha1也是一个算法,40位的字符串,每个字符都是一个十六进制
# 算法相对复杂  计算速度也慢
md5_obj=hashlib.md5()
md5_obj.update(s.encode('utf-8'))
res=md5_obj.hexdigest()
print(res,len(res),type(res))
# 数据库 撞库

# 加盐
md5_obj=hashlib.md5("加盐".encode('utf-8'))
md5_obj.update(s.encode('utf-8'))
# 动态加盐
username=input('username:')
passwd=input('passwd')
md5obj=hashlib.md5(username.encode('utf-8'))
md5obj.update(passwd.encode('utf-8'))
print(md5obj.hexdigest())

configparser模块

logging 模块

功能

  • 日志格式的规范
  • 操作的简化
  • 日志的分级管理

logging 模块的使用

logging.basicConfig(level=logging.DEBUG)  #级别
logging.debug('debug message') #调试模式
logging.info('info message') # 基础信息
logging.warning('warning message')# 警告
logging.error('error message') # 错误
logging.critical('critical message') # 严重错误
basicConfig
不能将一个log信息既能输出到屏幕上有输出到文件上

# logger 对象的形式来操作日志文件
# 创建一个logger对象
logger=logging.getLogger()
# 创建一个文件管理操作符
fh=logging.FileHandler()
# 创建一个屏幕管理操作符
sh=logging.StreamHandler()
# 创建一个日志输出的格式
format1=logging.Formatter('%(asctime)s-%(name)s-%(lecelname))

# 文件管理操作符 绑定一个格式
sh.setFormatter(format1)
# 屏幕管理操作符 绑定一个格式


# logger对象 绑定 文件管理操作符
# logger对象 绑定 屏幕管理操作符

网络编程

由于不同机器上的程序要通信,才产生了网络

server 服务端

client 客户端

b/s 架构 ----> 统一入口 (解耦分支)

b/s 和c/s 架构的关系

  • b/s架构师c/s架构的一种

网关的概念

  • 局域网中的机器想要访问局域网外的机器,需要通过网关
  • 端口 找到的程序
  • 在计算机上,没一个需要网络通信的程序,都会开一个端口
  • 在同一时间只会有一个程序占用一个端口
  • 不可能在同一时间有两个程序占用同一个端口
  • 端口的范围0-65545,一般情况下8000之后的端口
  • ip 确定唯一一台机器
  • 端口--- 确定唯一的一个程序
  • ip+端口 找到唯一的一台机器上的唯一的一个程序

tcp协议和udp协议

这个全双工的通信将占用两个计算机之间的通信线路,直到它被一方或双方关闭为止

arp地址 通过ip找mac

ip协议属于网络osi 七层协议中的哪一层,网络层

tcp协议 udp协议属于传输层

arp 协议 属于数据链路层

黏包问题 不知道客户端发送的数据的长度

大文件的传输一定要按照字节读,每一次读固定的字节

> 实现一个大文件的上传或者下载---
server端
import json
import socket
import struct

sk=socket.socket()
sk.bind(('127.0.0.1',8090))
sk.listen()
buffer=1024
conn,addr=sk.accept()# 接受
head_len=conn.recv(4)
head_len=struct.unpack('i',head_len)[0]
json_head=conn.recv(head_len).decode('utf-8')
head=json.loads(json_head)
filesize=head['filesize']
with open(head['filename'],'wb') as f:
    while filesize:
        if filesize>=buffer:
            content=conn.recv(buffer)
            f.write(content)
            filesize-=buffer
        else:
            content=conn.recv(filesize)
            f.write(content)
            filesize=0
            break
conn.close()
sk.close()

client端
import json
import socket
import os
import struct

buffer = 1024
sk = socket.socket()
sk.connect(('127.0.0.1', 8090))

head = {# 发送文件
    'filepath': r'文件路径',
    'filename': r'文件名',
    'filesize': None
}
file_path = os.path.join(head['filepath'], head['filename'])
filesize = os.path.getsize(file_path)
head['filesize'] = filesize
json_head = json.dumps(head)  # 字典转成字符串
bytes_head = json_head.encode('utf-8')  # 字符串转成bytes
print(json_head)
print(bytes_head)

head_len = len(bytes_head)# 计算head长度
pack_len = struct.pack('i', head_len)
sk.send(pack_len)  # 先发报头的长度
sk.send(bytes_head)
with open(file_path, 'rb') as f:
    while filesize:
        if filesize > buffer:
            content = f.read(buffer)  # 每次读出来的内鹅绒
            sk.send(content)
            filesize -= buffer
        else:
            content = f.read(filesize)
            f.read(content)
            break

# 解决黏包问题
    # 为什么会会出现黏包现象
    # 首先 只有在TCP协议中才会出现黏包现象
    # 是因为TCP协议是面向流的协议
    # 在发送的数据传输的过程中还有缓存机制避免数据丢失
    # 因此在连续发送小数据的时候,以及接受大小不符的时候都容易出现黏包现象
    # 本质还是因为我们在接受数据的时候不知道发送的数据的长短
# 解决黏包问题
    # 在传输大量数据之前先告诉接受端要发送的数据大小
    # 如果想更漂亮的解决问题,可以通过struct模块来定制协议

# struct 模块
    # pack  unpack
    # 模式:   'i'
    # pack之后的长度: 4个字节
    #unpack之后拿到的数据是一个元组:元组的第一个元素才是pack的值

进程

只有在运行当中的程序--进程

进程是操作系统中资源分配的最小单位

进程是怎么被调度的

  • 先来先服务算法 FCFS
  • 短作业优先算法
  • 时间片轮转算法
  • 多级反馈算法

进程

  • 异步 只管调度 不等结果
  • 同步 调度之后 还一定要等到结果

进程的状态

  • 就绪 运行 阻塞 

多进程

  • 进程与进程之间是完全的数据隔离的

  •     # from multiprocessing import Process
        #
        # n=100
        # def func():
        #     global n
        #     n=n-1
        #     print(n)
        #
        # if __name__=='__main__':
        #     for i in range(10):
        #         p=Process(target=func)
        #         p.start()
        #     print('主进程:',n)
    

start 开启一个进程

join 用join 可以让主进程等待子进程结束

守护进程p.daemon=True

  • 守护进程会随着主进程的代码执行结束而结束

  • 正常的子进程没有执行完的时候主进程要一直等着

  •     # 守护进程的进程的作用: 会随着主进程的代码的执行结束而结束,不会等待其他子进程
        # 守护进程 要在start之前设置
        # 守护进程中不能再开启子进程
        def cal_time():
            while True:
                time.sleep(1)
                print("过去了10秒")
        if __name__=='__main__':
            p=Process(target=cal_time())
            p.daemon=True  # 一定在开启进程之前设置 
            p.start()
            for i in range(100):
                time.sleep(0.1)
                print('*'*i)
    
    # p.is_alive() # 是否活着 True 代表进程还在False代表进程不在了
    # p.terminatr() # 结束一个进程但是这个进程不会立刻被杀死
    import time
    from multiprocessing import Process

    def func():
        print('wahaha')
        time.sleep(4)
        print('qqxing')
    if __name__=='__main__':
        p=Process(target=func)
        p.start()
        print(p.is_alive())
        p.terminate()       # 关闭进程 异步
        print(p.is_alive())
# 属性
# pid 查看这个进程  进程id
# name 查看这个进程的名字
class MyProcess(Process):
    def run(self):
        print('wahaha',self.name,self.pid)
        time.sleep(5)
        print('qqxing',self.name,self.pid)
if __name__=='__main__':
    p= MyProcess()
    p.start()
    print(p.pid)

 lock.acquire() # 需要锁  拿钥匙
 lock.release() # 释放锁  还钥匙
 买票
import random
import time

from multiprocessing import Lock
from multiprocessing import Process
def search(i):
    with open('ticket') as f:
        print(i,json.load(f)['count'])
def get(i):
    with open('ticket') as f:
        ticket_num=json.load(f)['count']
    time.sleep(random.random())
    if ticket_num>0:
        with open('ticket','w') as f:
            json.dump({'count':ticket_num-1},f)
        print('%s买到票了'%i)
    else:
        print('%s没票'%i)
def task(i,lock):
    search(i) #查看票
    lock.acquire()
    get(i)   #抢票
    lock.release()


if __name__=='__main__':
    lock=Lock()
    for i in range(20):
        p=Process(target=task,args=(i,lock))
        p.start()

信号量

# 信号量
import random
import time
from multiprocessing import Semaphore, Process


# sem.acquire() # 需要钥匙
# print(0)
# sem.acquire() # 需要钥匙
# print(1)
# sem.acquire() # 需要钥匙
# print(2)
# sem.acquire() # 需要钥匙
# print(3)
# sem.acquire() # 需要钥匙
# print(4)
# 迷你唱吧 20个人 同一时间只能有4个人进去唱歌
def sing(i,sem):
    sem.acquire()
    print('%s:进入 ktv'%i)
    time.sleep(random.randint(1,10))
    print('%s: 出来 ktv'%i)
    sem.release()
if __name__=='__main__':
    sem = Semaphore(4)
    for i in range(20):
        Process(target=sing,args=(i,sem)).start()

事件

from multiprocessing import Event # 事件
e=Event() # 实例化一个事件  标志/交通信号灯
e.set()    # 将标志变成非阻塞/交通灯变绿
e.wait()    # 刚实例化出来的一个事件对象,默认的信号是阻塞信号/默认是红灯
            # 执行到wait,要先看灯,绿灯行红灯停,如果在停的过程中,灯绿了,就变成非阻塞的
e.clear() # 将标志又变成阻塞/交通灯变红
e.is_set() # 是否则色 True 就是绿灯 False 就是红灯 
# 红绿灯
import time
import random

def triffic_lifht(e):
    while True:
        if e.is_set():
            time.sleep(3)
            print('红灯亮')
            e.clear()  # 绿变红
        else:
            time.sleep(3)
            print('绿灯亮')
            e.set()  # 红变绿

def car(i, e):
    e.wait()
    print('%s车通过' % i)


if __name__ == '__main__':
    e = Event()  # 立一个红灯
    tra = Process(target=triffic_lifht, args=(e,))
    tra.start()  # 启动一个进程来控制红绿灯
    for i in range(100):
        if i % 6 == 0:
            time.sleep(random.randint(1, 3))
        car_pro = Process(target=car, args=(i, e))
        car_pro.start()

队列 Queue 管道+锁 双向通信 数据安全

# 进程之间通信  可以使用multiprocessing 的Queue模块
# 队列有两种创建方式 第一种不传参数 这个队列就没有长度限制;
# 传参数,创建一个有最大长度限制的队列
# 提供两个重要方法:put  get
# qsize  不怎么准确

def q_put(q):
    q.put('hello')

def q_get(q):
    print(q.get())
if __name__=='__main__':
    q=Queue()
    p=Process(target=q_put,args=(q,))
    p.start()
    p1=Process(target=q_get,args=(q,))
    p1.start()
#通过队列实现了 主进程与子进程的通信 子进程与子进程之间的通信
# 生产者消费者模型
# 我要生产一个数据 然后给一个函数 让这个函数依赖这个数据进行运算,拿到结果--同步过程

# 做包子和吃包子
def producer(q):# 生产者
    for i in range(100):
        q.put('包子%s'%i)

def couseumer(q): #消费者
    for i in range(100):
        time.sleep(1)
        print(q.get())

if __name__=='__main__':
    q=Queue(10) # 托盘
    p=Process(target=producer,args=(q,))
    p.start()
    c=Process(target=couseumer,args=(q,))
    c.start()
    c1 = Process(target=couseumer, args=(q,))
    c1.start()
首先 对于内存空间来说  每次只有很少的数据会在内存中
对于生产与消费之间的不平衡来说
* 增加消费者或者增加生产者来调用效率

生产者-消费者模型(很重要)

joinableQueue putget 的一个技术机制,每次get数据之后发送task_done.put端接收

记数-1,直到计数为0就能感知到

# # 消费者已经把生产的所有数据都处理完了
# # 主进程 producer.join() 等待生产者结束
# # 设置消费者为守护进程
import time
import random
from multiprocessing import Process, JoinableQueue


def produceer(q,food):
    for i in range(5):
        q.put('%s-%s'%(food,i))
        print('生产了%s'%food)
        time.sleep(random.random())
    q.join()  # 等待消费者把所有数据处理完
def consumer(q,name):
    while True:
        food=q.get() # 生产者不生产还是生产的慢
        if food==None:break
        print('%s吃了%s'%(name,food))
        q.task_done()
if __name__=='__main__':
    q=JoinableQueue()
    p1=Process(target=produceer,args=(q,'泔水'))
    p1.start()
    p2=Process(target=produceer,args=(q,'骨头'))
    p2.start()
    c1=Process(target=consumer,args=(q,'alex'))
    c1.daemon=True
    c1.start()
    c2=Process(target=consumer,args=(q,'sun'))
    c2.daemon=True
    c2.start()
    p1.join() # 等待p1执行完毕
    p2.join() # 等待p2执行完毕

# 生产者生产的数据全部被消费---生产者进程结束
# 主进程执行结束----消费者守护进程结束

管道(不懂) Pipe 管道 双向通信 数据不安全

# 用管道 也能实现 生产者消费者模型
# socket  接受  
# 等待数据
# 数据发送到操作系统
# 从操作系统copy到进程中

# 队列=管道+锁
# 双向通信
# 数据不安全 ,没有锁的机制
# 基于管道和锁 实现了队列---队列 用在同一台机器的多个进程之间通信

进程之间的数据共享Manager

  • 但是数据是不安全的

进程池 Pool

    # 进程池
    # 造一个池子 放4个进程(员工)来用来完成工作
    # 发任务
    # 循环使用池子中进程完成任务
    进程池为什么出现:开过多的进程1.开启进程浪费时间2.操作系统调度太多的进程也会影响效率
    开进程池: 有几个现成的进程在池子里,有任务来了,就用这个池子中的进程处理任务
    当所有的任务都处理完了,进程池关闭,回收所有的进程
    from multiprocessing import Pool
    # apply
    def func(i):
        i+=1
        return i
    if __name__=='__main__':
        p=Pool(5)
        res_l=[]
        for i in range(20):
            # p.apply(func,args=(i,)) # apply是同步提交任务的机制(几乎不用)
            res=p.apply_async(func,args=(i,)) # apply_async 是异步提交任务的机制
            res_l.append(res)
            print(res.get()) # 阻塞:等待着任务的结果
        p.close()# close必须加在join之前,不允许在添加新的任务了
        p.join()  # 等待子进程结束在往下执行
        [print(i.get()) for i in res_l]
    #apply_async
    import time
    from multiprocessing import Pool
    def func(i):
        time.sleep(1)
        i+=1
        return i

    if __name__=='__main__':
        p=Pool(4)
        res_l=[]
        for i in range(10):
            res=p.apply_async(func,args=(i,))# apply target
            res_l.append(res)
        p.close() # 不能再往进程池中添加新的任务
        p.join() # 阻塞等待 执行进程池中的所有任务直到执行结束
        [print(res.get()) for res in res_l]
    # map
    def fun(i):
        time.sleep(1)
        i+=1
        return i
    if __name__=='__main__':
        s=time.time()
        p=Pool(4)
        ret= p.map(fun,range(10)) # func(next(range(10))
        print(ret)
        print(time.time()-s)
    # 参数  概念 回调函数   主进程执行, 参数是子进程执行的函数的返回值
    # os.getpid()获取当前进程id     os.getppid()获取父进程id
    def func(i):  # 多进程中的io多
        print('子进程%s:%s'%(i,os.getpid))
        return i*'*'

    def call(arg):# 回调函数是在主进程中完成的,不能传参数,只能接受多进程中函数的返回值
        print('回调:',os.getpid())
        print(arg)

    if __name__=='__main__':
        print('---->',os.getpid())
        p=Pool(5)
        for i in range(10):
            p.apply_async(func,args=(i,),callback=call)
        p.close()
        p.join()

线程

进程是资源分配的最小单位,线程是CPU调度的最小单位

每一个进程中至少有一个线程

进程包含着线程

GIL 全局解释器锁 Cpython解释器

去掉GIL 保证数据安全 细粒度的锁 效率更低

一个程序中可以开启多进程多线程

    import time
    from threading import Thread
    import os
    class MyThead(Thread):
        count = 0  # 静态属性
        def __init__(self,arg1,arg2):
            super().__init__()
            self.arg1=arg1
            self.arg2=arg2
        def run(self):
            MyThead.count += 1
            time.sleep(1)
            print('%s,%s,hello world,%s'%(self.arg1,self.arg2,os.getpid()))


    for i in range(10):
        t = MyThead(i,i*'*')
        t.start()
    # 计算开启的线程数量
    # 多个子线程 共享 这个数据
    import threading
    def func(i):
        time.sleep(0.5)
        print(i,threading.currentThread().name,threading.currentThread().ident)
        # 查看线程的默认名字,查看ident 线程id
        # currentThread 查看线程的默认属性
    for i in range(10):
        t=threading.Thread(target=func,args=(i,))
        t.start()

    print(threading.enumerate()) # 返回正在运行着线程列表
    print(threading.activeCount())# 统计当前有多少个线程
    # 守护线程
    import time
    from threading import Thread
    def func():
        print('开始执行子线程')
        time.sleep(3)
        print('子线程执行完毕')

    t=Thread(target=func)
    t.setDaemon(True)  # 进程设置守护进程,是一个属性 daemon=True
    t.start()
    t2=Thread(target=func)
    t2.start()
    t2.join()
    # 守护线程 守护进程都是等待主线程中的代码 执行完毕
    # t2=Thread(target=func)
    # t2=start() -->代码执行完毕
    # 守护线程就结束了
    # 主线程还没结束 等待t2继承执行
    from threading import RLock # 递归锁
    from threading import Lock # 互斥锁
    lock=RLock()  # 递归锁  可以被两次acquire
    # lock=Lock()
    lock.acquire() # 等着钥匙
    lock.acquire() # 等着钥匙
    print(123)
    lock.release()
    lock.release()
    # 递归锁 可以解决死锁问题 
    在多线程并发的情况下,同一个线程中,如果出现多次acquire 就可能产生死锁线程现象

信号量

        面试题
    [[0, 0, 0, 0, 0], [0, 1, 2, 3, 4], [0, 2, 4, 6, 8], [0, 3, 6, 9, 12]]
    ret = [[i * j for j in range(5)] for i in range(4)]
    print(ret)

    面试题
    '''
    有一个文本
    https://y.qq.com/
    https://www.baidu.com/index.html
    https://www.bilibli.com/imd.html
    https://m.taobao.coom/cc.html
    https://y.qq.com/
    https://www.baidu.com/index.html
    https://www.bilibli.com/imd.html
    https://m.taobao.coom/cc.html
    https://qq.lol.com/index.html
    https://qq.lol.com/index.html
    '''
    '''
    脚本输出
    倒序次数 www.bilibilicom
    '''
    import re
    from collections import Counter
    with open('re.log') as f:
        data = f.read()
    ym_list=re.findall(r'https://(.*?)/.*?',data)
    tm_dict=dict(Counter(ym_list))
    #排序
    ret=sorted(ym_list.items(),key=lambda x:x[1],reverse=True)
    for i in ret:
        print(i[1],i[0])
    import random
    import time
    from threading import Semaphore, Thread

    sem=Semaphore(5)# 一把锁有5把钥匙
    def func(n,sem):
        sem.acquire()
        print('thread -%s'%n)
        time.sleep(random.random())
        print('thread -%s start'%n)
        sem.release()
    for i in range(20):
        Thread(target=func,args=(i,sem)).start()

    # 信号量和线程池有什么区别
    # 相同点
        #在aacquire之后,和线程池一样,同时在执行的只能有n个
    # 不同点
        #开的线程数不一样,线程池来说,一共就只能开5个线程,信号量有几个任务就开几个线程
    # 对有信号量限制的程序来说,可以同时执行很多线程么
    # 实际上 信号量并不影响线程或者进程的并发,只是在加锁的阶段进行流量限制

事件

    # Event
    # flag标志
    # 刚刚创建的时候 flag=False
    # wait() flag=False 阻塞
    #       # flag=True 非阻塞
    # set() Fasle--> True
    # clear() True-->False
    # 连接mysql数据库
    # 我连接三次数据库
    # 每0.5秒连接一次
    # 创建一个事件,来标志数据库的连接情况
    # 如果连接成功就显示成功
    # 否则就报错

    def conn_mysql():  # 连接数据库
        count=0
        while not e.is_set():
            if count>3:
                raise TimeoutError
            print('尝试连接第%s次'%count)
            count+=1
            e.wait(0.5) # 一直阻塞变成了只阻塞0.5
        print('连接成功')
    # 检测数据库的连接是否正常
    def check_conn():
    # 模拟连接检测的事件
        time.sleep(random.randint(1,2))# 检测
        e.set() # 告诉事件的标志数据库可以连接

    e=Event()
    check = Thread(target=check_conn)
    check.start()
    conn=Thread(target=conn_mysql)
    conn.start()
	定时器
    from threading import Timer

    def hello():
        while True: # 这个线程一直在
            time.sleep(1)
            print("hello,world")
    while True: # 每隔一段时间要开启一个线程
        t=Timer(1,hello()) # 定时开启一个线程 ,执行一个任务
                        #定时: 多久之后,单位是s
                        # 要执行的任务: 函数名

    t.start()
    #sleep的时间
    # sleep的时间短 就在线程内while True
    # sleep的时间长 就在主线程while True 
    # 条件    condition  notify_all notify 
    def run(n):
        con.acquire()
        con.wait() # 等着
        print("run the thread :%s"%n)
        con.release()
    if __name__=='__main__':
        con=threading.Condition()
        for i in range(10):
            t=threading.Thread(target=run,args=(i,))
            t.start()

        while True:
            inp=input('>>>')
            if inp=='q':
                break
            con.acquire()# condition中的锁是递归锁
            if inp=='all':
                con.notify_all()
            else:
                con.notify(int(inp)) #传递信号notify(1) 可以放行一个线程
            con.release()
	# 优先级
    import queue
    # q=queue.Queue() # 队列 线程安全的
    #q.get()
    #q.put()
    #q.qsize()

    lfq=queue.LifoQueue() # 后进先出 :栈
    lfq.put(1)
    lfq.put(2)
    lfq.put(3)
    lfq.put(4)
    print(lfq.get())
    print(lfq.get())
    print(lfq.get())
    print(lfq.get())

    pq=queue.PriorityQueue() #值越小越优先,值相同就先进先出
    pq.put((10,'a'))
    pq.put((5,'b'))
    pq.put((4,'c'))
    pq.put((6,'d'))

    print(pq.get())

线程池

    # 线程池
    # 线程池和进程池
    # 是用来做池操作的最近新的模块

    # 开启线程需要成本 成本就开启进程要低
    # 高IO的情况下 开多线程
    # 所以我们不能开启任意多个线程
    # 开启线程池

    # futures.ThreadPoolExecutor # 线程池
    # futures.ProcessPoolExecutor #进程池

    from concurrent import futures
    def funcname(n):
        print(n)
        time.sleep(random.randint(1,3))
        return n*'*'


    threading_pool=futures.ThreadPoolExecutor(5)
    # threading_pool.map(funcname,range(10)) # map天生异步,接受可迭代对象的数据,不支持返回值
    # f_lst=[]
    # for i in range(10):
    #     f=threading_pool.submit(funcname,i) # submit 合并了创建线程对象和start的功能
    #     f_lst.append(f)
    # threading_pool.shutdown() #close() join()
    # [print(i.result()) for i in f_lst] # 一定按照顺序出结果
    #                             #f.result() 阻塞 等f执行完得到结果
    # 回调函数 add_done_callback(回调函数的名字)
    def call(args):
        print(args.result())
    threading_pool.submit(funcname,1).add_done_callback(call)
    # 统一了入口和方法,简化了操作,降低了学习的时间成本

(gevent先放放,3.7安装不上)

    协程
    # from greenlet import greenlet  # 在单线程中切换状态的模块
    # import time
    #
    # def eat1():
    #     print("吃鸡腿1")
    #     g2.switch()
    #     time.sleep(5)
    #     print("吃鸡翅2")
    #     g2.switch()
    #
    #
    # def eat2():
    #     print("吃饺子1")
    #     g1.switch()
    #     time.sleep(3)
    #     print('白切鸡')
    #
    #
    # g1 = greenlet(eat1)
    # g2 = greenlet(eat2)
    # g1.switch()
    # gevent 内部封装了greenlet模块
    # 切换不能规避IO时间
    # 协程的切换与正常程序的执行那个效率高

IO模型

阻塞IO: 工作效率低

非阻塞IO:工作效率高,CPU的负担

IO多路复用: 在有多个对象需要IO阻塞的时候,能够有效的减少阻塞带来的时间消耗,且能够在一定程度上减少CPU的负担(比较好的)

异步IO: asyncio 异步IO 工作效率高 CPU的负担少


MySQL

mysql: 是用于管理文件的一个软件

  • 服务器软件
    • socket服务器
    • 本地文件操作
  • 客户端软件
    • socket客户端
    • 发送指令

初始化:

  • 服务端 mysqld -- initialize-inzecure
  • 用户名root 密码:空

启动服务端

  • mysqld

客户端连接

  • mysql -u root -p

发送命令:

show databases;
create database db1;

配置环境变量: 安装包的 bin配置

安装window服务

H:\mysql-5.7.24-winx64\bin\mysqld --install

H:\mysql-5.7.24-winx64\bin\mysqld --remove

启动服务

net start mysql

net stop mysql

操作文件夹
	create database db2;
	create database db2 default charset utf8;
	show databases;
	drop database db2;
操作文件
	show tables;
	create table t1(
		列名 类型 null,
		列名 类型 not null,
		列名 类型 not null default 1,
		列名 类型 not null auto_increment primary key,
        id int,
        name char(10)
	) default charset=utf8;
	create table t1(id int,name char(10)) engine=innodb default charset=utf8;
	#innodb 支持事物
	auto_increment 表示:自增
	primary key: 表示 约束(不能为空) 加速查找
	数字:
		tinyint
		int
		bigint
		FLOAT(float)
		DOUBLE(double)
		decimal(底层原理 按字符串存的数字 标准)
	字符串:
		char(长度)  速度快
		varchar(长度) 节省空间
		ps: 创建定长char的列往前方,
		text
清空表
	delete from t1;
	truncate table t1;
删除表:
	delete from t1 where id<6;
	drop table t1;
修改:
	update t1 set age=18;
操作文件中内容
	插入数据
		insert into t1(id,name) values(1,'alex')
查看数据库
select * from t1;
时间类型:
DATETIME(datetime)
enum(多选一)
set(多选多)
外键:
	create table userinfo(
		uid bigint auto_increment prinmary key,
		name varchar(32),
		department_id int,
		constranint fk_user_depar foreign key ("department_id",) references department('id')
	)
	create table department(
		id bigint auto_increment primary key,
		title char(15)
	)engine=innodb default charset=utf8;

bootCDN

小马哥

武sir

where

  • 关键字like 模糊查询

  • % _

  • in(100,200,300) not and or

  • between 9000 and 100
    

group by 分组查询

  • 聚合函数

    max()最大值

    min() 最小值

    avg() 平均值

    sum() 求和

    count() 求总个数

    必须使用group by 才能使用group_concat()函数,将所有的name值连接

having 过滤

优先级   where>group by> having

order by 查询排序

select * from employee order by age ASC  升序
select * from employee order by age DESC 降序

limit 限定查询记录数(分页查询)

SELECT * FROM employee ORDER BY salary DESC
        LIMIT 0,5; #从第0开始,即先查询出第一条,然后包含这一条在内往后查5条

查看表结构和数据

desc 表名;
select * from  表名;

多表查询

表名1 join 表名2 on 条件

select employee.id,employee.name,employee.age,employee.sex,department.name from employee inner join department on employee.dep_id=department.id;

exists 关键字查询表示存在,

  • 当返回True时,外层查询语句进行查询,当返回值为false时,外层查询语句不进行查询
posted @ 2018-11-19 18:59  猫神甜辣酱  阅读(663)  评论(0编辑  收藏  举报