From 1ab56cb5aef4e69caf9f0ed8eb1ce2c6c962f735 Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: 2018年2月26日 11:53:32 +0800 Subject: [PATCH 01/29] =?UTF-8?q?=E7=BB=83=E4=B9=A0=E5=A4=9A=E8=BF=9B?= =?UTF-8?q?=E7=A8=8B=E5=92=8C=E8=BF=9B=E7=A8=8B=E9=97=B4=E9=80=9A=E4=BF=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test32.py | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 test32.py diff --git a/test32.py b/test32.py new file mode 100644 index 0000000..4792c79 --- /dev/null +++ b/test32.py @@ -0,0 +1,79 @@ +#!/ussr/bin/env python 3 +# -*- coding: utf-8 -*- + +'练习多进程与进程间通信' + +__author__ = 'sergiojune' +from multiprocessing import Process, Pool, Queue +import os +import time +from random import random + + + +# print('parent process(%s) is running' % os.getpid()) +# 定义子进程需要运行的函数 +# def run(name): +# print('I am runing,I is process(%s)' % os.getpid()) +# 在使用这个进程时,需要使用if __name__ == '__main__这个语句来开父进程,要不会出错 +# if __name__ == '__main__': +# # 创建子进程 +# p = Process(target=run, args=('test',)) +# # 开启进程 +# p.start() +# # 让子进程运行完再运行下面的父进程 +# p.join() +# print('End...........') + + + +# 使用进程池批量开启进程 +# def run(name): +# print('task %s is running, process %s' % (name, os.getpid())) +# start = time.time() +# time.sleep(random()*3) +# end = time.time() +# print('%s is run %0.2f seconds process %s' % (name, (end - start), os.getpid())) +# +# +# if __name__ == '__main__': # 开启多进程这个语句是必须的 +# print('parent process %s is running' % os.getpid()) +# # 创建进程池 +# p = Pool(4) +# for x in range(5): +# p.apply_async(run, args=(x,)) +# # 关闭进程池,不能再添加进程 +# p.close() +# # 要实现这个方法之前必须关闭进程池 +# p.join() +# print('parent process %s end' % os.getpid()) + + + +# 实现进程间通信 +def write(q): + print('process %s is writing' % os.getpid()) + for x in 'ABC': + q.put(x) + print(' %s write %s' % (os.getpid(), x)) + + +def read(q): + print('process %s is read' % os.getpid()) + while True: + value = q.get(True) + print('info is %s' % value) + + +if __name__ == '__main__': + q = Queue() + print('parent is running') + pw = Process(target=write, args=(q,)) + pr = Process(target=read, args=(q,)) + # 开启进程 + pw.start() + pr.start() + pw.join() + # 由于read方法不能自行停止,所以需要强制tingz + pr.terminate() + print('end------') From 2f991912f369df3bfa8585d98a400bc259333b8a Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: 2018年2月26日 14:29:12 +0800 Subject: [PATCH 02/29] =?UTF-8?q?=E7=BB=83=E4=B9=A0=E5=A4=9A=E7=BA=BF?= =?UTF-8?q?=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test33.py | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 test33.py diff --git a/test33.py b/test33.py new file mode 100644 index 0000000..8837229 --- /dev/null +++ b/test33.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +'练习多线程' + +__author__ = 'sergiojune' +import threading +import multiprocessing + + +def run(): + print('thread %s is running' % threading.current_thread().name) + for x in range(5): + print('thread %s ==> %d' % (threading.current_thread().name, x)) + print('thread %s end' % threading.current_thread().name) + + +print('thraed %s is running' % threading.current_thread().name) +t = threading.Thread(target=run, name='loopthread') +# 开启线程 +t.start() +t.join() +print('thread %s is end' % threading.current_thread().name) + + +# 多线程的锁 +balance = 0 +def change(n): + global balance + balance = balance + n + balance = balance - n + print(balance) + + +def run_thread(): + l = threading.Lock() + for x in range(1, 100000): + try: + # 获取锁 + l.acquire() + change(x) + finally: + # 释放锁 + l.release() + + +t1 = threading.Thread(target=run_thread) +t2 = threading.Thread(target=run_thread()) +t1.start() +t2.start() +t1.join() +t2.join() +print('end') + + +def loop(): + x = 0 + while True: + x = x ^ 1 + + +for x in range(multiprocessing.cpu_count()): # 根据cpu的数量来开线程 + t = threading.Thread(target=loop) + t.start() + From 467266a0b0ef252b5be6ca4ec8b438900943af52 Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: 2018年2月26日 18:10:54 +0800 Subject: [PATCH 03/29] =?UTF-8?q?=E7=BB=83=E4=B9=A0=E6=AD=A3=E5=88=99?= =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test37.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 test37.py diff --git a/test37.py b/test37.py new file mode 100644 index 0000000..8b37da8 --- /dev/null +++ b/test37.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +'练习正则表达式' + +__author__ = 'sergiojune' +import re + + +# 作业:尝试写一个验证Email地址的正则表达式。版本一应该可以验证出类似的Email +a = 'someone@gmail.com' +b = 'bill.gates@microsoft.com' +# 匹配邮箱的正则表达式,返回一个正则对象 +re_mail = re.compile('[\.\w]*@[\w]+.[\w]+') +m = re_mail.match(a) +print(m.group()) +g = re_mail.match(b) +print(g.group()) + From 3e2457ac0a7de3cec12708dc58131f2b38e8a8ab Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: 2018年2月26日 18:11:28 +0800 Subject: [PATCH 04/29] =?UTF-8?q?=E7=BB=83=E4=B9=A0=E5=88=86=E5=B8=83?= =?UTF-8?q?=E5=BC=8F=E8=BF=9B=E7=A8=8B=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test35.py | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 test35.py diff --git a/test35.py b/test35.py new file mode 100644 index 0000000..31e0daf --- /dev/null +++ b/test35.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +'练习分布式进程' + +__author__ = 'sergiojune' +import queue, random +from multiprocessing.managers import BaseManager +# 此文件用来发送和接受结果,test36.py用于处理结果 + +# 创建通信工具 +# 发送任务 +post_task = queue.Queue() +# 接受结果 +result_task = queue.Queue() + + +class QueueManager(BaseManager): + pass + + +# 定义的函数解决下面的坑 +def posttq(): + return post_task + + +def resulttq(): + return result_task + + +def start(): + # 注册任务 + # 这里有个坑,在window系统下callable不能为匿名函数,原因是不能被序列化,所以在这里我们需要定义函数 + QueueManager.register('post_task_queue', callable=posttq) # 第一个参数为注册名字 + QueueManager.register('result_task_queue', callable=resulttq) + + # 绑定窗口,设置验证码 + manager = QueueManager(address=('127.0.0.1', 500), authkey=b'abc') # 第一个参数为地址和端口,第二个参数为验证码,防止别人骚扰 + + # 启动管理 + manager.start() + # 通过管理器获取通信 + post = manager.post_task_queue() + result = manager.result_task_queue() + + # 进行发送数据 + print('try post data') + for x in range(10): + n = random.randint(1, 1000000) + print('put %d' % n) + post.put(n) + + # 接受结果 + print('try get result') + for x in range(10): + # timeout表示超时获取数的最长时间 + value = result.get(timeout=10) + print('get result', value) + + # 关闭管理器 + manager.shutdown() + print('master end') + + +if __name__ == '__main__': + start() From 6d426bfd4e4caf3845956b9f79ae31d9b0cd46a6 Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: 2018年2月26日 18:12:21 +0800 Subject: [PATCH 05/29] =?UTF-8?q?=E7=BB=83=E4=B9=A0=E5=88=86=E5=B8=83?= =?UTF-8?q?=E5=BC=8F=E8=BF=9B=E7=A8=8B=EF=BC=88win10=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=EF=BC=8C=E9=85=8D=E5=90=88=E7=89=B9=E6=AE=8A=E5=9B=BE=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From f3c86bc381e2bc7eb5cb3d98a9c3d76fe8be6422 Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: 2018年2月26日 18:12:54 +0800 Subject: [PATCH 06/29] =?UTF-8?q?=E5=A4=84=E7=90=86=E5=88=86=E5=B8=83?= =?UTF-8?q?=E5=BC=8F=E8=BF=9B=E7=A8=8B=E5=8F=91=E9=80=81=E7=9A=84=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=EF=BC=88win10=E7=8E=AF=E5=A2=83=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test36.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 test36.py diff --git a/test36.py b/test36.py new file mode 100644 index 0000000..843fabc --- /dev/null +++ b/test36.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +'处理分布式进程发送的数据' + +__author__ = 'sergiojune' +from multiprocessing.managers import BaseManager +import time, queue + + +class QueueManager(BaseManager): + pass + + +# 注册到网络上 +QueueManager.register('post_task_queue') # 由于只是从网络上获取queue,所以不需要写callable方法 +QueueManager.register('result_task_queue') +# 连接到网络 +address = '127.0.0.1' # 这个是网络地址 +manager = QueueManager(address=(address, 500), authkey=b'abc') # 这些必须与发送的一致,要不会连不上 +# 连接 +manager.connect() +# 获取queue +post = manager.post_task_queue() +result = manager.result_task_queue() + +# 处理数据 +print('tyr get value') +for x in range(10): + try: + v = post.get(timeout=10) + print('get value %d' % v) + r = v*v + print('put value %d to result' % r) + time.sleep(1) + result.put(r) + except queue.Empty as e: + print('Queue is empty') +print('work exit') From 87ae9ad4422cccc44573049f3234338da4047d55 Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: 2018年2月26日 18:14:04 +0800 Subject: [PATCH 07/29] =?UTF-8?q?=E7=BB=83=E4=B9=A0=E5=88=86=E5=B8=83?= =?UTF-8?q?=E5=BC=8F=E8=BF=9B=E7=A8=8B=EF=BC=88win10=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=EF=BC=8C=E4=B8=8Etest36=E9=85=8D=E5=90=88=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test35.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test35.py b/test35.py index 31e0daf..c208150 100644 --- a/test35.py +++ b/test35.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -'练习分布式进程' +'练习分布式进程 ' __author__ = 'sergiojune' import queue, random From 079619190d3198619433bd1803acfd3974183016 Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: 2018年2月26日 18:22:22 +0800 Subject: [PATCH 08/29] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=89=88=E4=BA=8C?= =?UTF-8?q?=E7=9A=84=E4=BD=9C=E4=B8=9A=E7=9A=84=E6=AD=A3=E5=88=99=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test37.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test37.py b/test37.py index 8b37da8..4940645 100644 --- a/test37.py +++ b/test37.py @@ -17,3 +17,12 @@ g = re_mail.match(b) print(g.group()) + +# 版本二: +a = ' tom@voyager.org => Tom Paris' +b = 'bob@example.com => bob' +mail = re.compile('([\w]+|[\w\s]+)@[\w]+.[\w]+') +aa = mail.match(a) +bb = mail.match(b) +print(aa.group()) +print(bb.group()) From 0d87c87dc464b1554ca2b5b7f6226d764ad12e14 Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: 2018年2月26日 23:38:38 +0800 Subject: [PATCH 09/29] =?UTF-8?q?=E7=BB=83=E4=B9=A0=E5=86=85=E5=BB=BA?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E4=B9=8Bdatetime?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test38.py | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 test38.py diff --git a/test38.py b/test38.py new file mode 100644 index 0000000..61ce759 --- /dev/null +++ b/test38.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +'练习内建模块致datetime' + +__author__ = 'sergiojune' +from datetime import datetime, timedelta, timezone +import re + +# 获取现在时间 +dt = datetime.now() +print(dt) +print(type(dt)) + +# 获取指定某日的时间,即是创建实例 +ddt = datetime(2017, 10, 15, 12, 35, 56) +print(ddt) # 类型为datetime.datetime + +# 将datetime转为timestamp +ts = dt.timestamp() +print(ts) +print(type(ts)) # 类型为float +# 将timestamp转为datetime +d = datetime.fromtimestamp(ts) +print(d) +# 将timestamp转为标准的utc时间,比北京时间少了八小时 +d = datetime.utcfromtimestamp(ts) +print(d) + +# 将字符串转为时间 +s = '2017:12:12 11:11:11' +sd = datetime.strptime(s, '%Y:%m:%d %H:%M:%S') # 第二个参数为字符串的时间格式 +print(sd) +print(type(sd)) + +# 将时间转为字符串,参数为转为字符串的格式 +ds = sd.strftime('%Y:%m:%d %H:%M:%S') +print(ds) +print(type(ds)) + + +# 将时间进行加减 +print('之前:', dt) +dt = dt + timedelta(hours=5,minutes=25) +print(dt) +dt = dt + timedelta(days=5) +print(dt) + +print('-------------------') +# 将本地datetime设一个时区 +tz_local = timezone(timedelta(hours=8)) +d = datetime.now() +print(d) +# 强行设置时区,tzinfo就是时区信息 +now = d.replace(tzinfo=tz_local) +print(now) + +print('----------------------') +# 时区时间任意转换 +# 拿到utc时间,并设置时区 +d = datetime.utcnow().replace(tzinfo=timezone.utc) +print(d) +# 转为北京时间的时区 +bj_utc = d.astimezone(tz=timezone(timedelta(hours=8))) +print(bj_utc) +# 转为东京时间 +dj_utc = d.astimezone(tz=timezone(timedelta(hours=9))) +print(dj_utc) +# 也可以直接利用北京时间转为东京时间 +dj_utc = bj_utc.astimezone(tz=timezone(timedelta(hours=9))) +print(dj_utc) +# 所以用astimezone()这个方法可以任意转换时区 + + +# 作业:假设你获取了用户输入的日期和时间如2015年1月21日 9:01:30,以及一个时区信息如UTC+5:00,均是str,请编写一个函数将其转换为timestamp +def to_timestamp(time, tz): + # 将字符串转为时间 + time = datetime.strptime(time, '%Y-%m-%d %H:%M:%S') + # 设置该时间的时区 + time = time.replace(tzinfo=timezone(timedelta(hours=tz))) + time = time.timestamp() + return time + + +print('---------------') +time1 = '2015-6-1 08:10:30' +utc1 = 'UTC+7:00' +# 用正则匹配出时间 +utc1 = int(re.search('UTC([+-][\d]{1,2}):[\d]{2}', utc1).group(1)) +print(utc1) +time = to_timestamp(time1, utc1) +print(time) + +time2 = '2015-5-31 16:10:30' +utc2 = 'UTC-09:00' +# 用正则匹配出时间 +utc2 = int(re.search('UTC([+-][\d]{1,2}):[\d]{2}', utc2).group(1)) +print(utc2) +time2 = to_timestamp(time2, utc2) +print(time2) From c44f4fd2316d303fb10f2885059a2aaebc978e87 Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: 2018年2月27日 00:26:40 +0800 Subject: [PATCH 10/29] =?UTF-8?q?=E7=BB=83=E4=B9=A0=E5=86=85=E5=BB=BA?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E4=B9=8Bcollections?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test39.py | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 test39.py diff --git a/test39.py b/test39.py new file mode 100644 index 0000000..1455bf0 --- /dev/null +++ b/test39.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +'练习内建模块之collections' + +__author__ = 'sergiojune' +from collections import namedtuple, defaultdict, deque, OrderedDict, Counter + +# 弄一个可以根据名字来取数的元组 +at = namedtuple('Point', ['x', 'y']) # 第一个参数为描述事物类型, 第二个参数为元组的位置名字 +p = at(1, 2) # 新建一个元组 +# 根据名字来取元素 +print(p.x) # 这就可以看作是一个坐标点 +print(p.y) + +# 有默认值的dict +dd = defaultdict(lambda:'not') # 参数为遇到不存在键时的处理的方法 +dd['age'] = 20 +print(dd['age']) # 存在 +print(dd['a']) # 不存在 + + +# 使用队列,比list的插入数据和删除数据快,支持从头或者尾删除或插入 +d = deque([1, 2, 3, 6]) +print(d) +# 从头插入数据 +d.appendleft(5) +print(d) +# 删除头部数据 +d.popleft() +print(d) + +# 让字典保持有序 +od = OrderedDict([('x', 3), ('y', 6), ('z', 6)]) +print(od) +# 还可以添加,与dict用法一样 +ood = OrderedDict() +ood['f'] = 5 +ood['s'] = 9 +ood['e'] = 7 +print(ood) + + +# 用计数器,直接算出某一个字符串里面字符出现的个数 +s = 'mynameissergiojune' +c = Counter(s) +print(c) + + +# 利用OrderedDict实现一个先进先出的字典,超过最大容量的时候就删除 +class LastUpdateDict(OrderedDict): + def __init__(self, max): + super(LastUpdateDict, self).__init__() + self.max = max + + def __setitem__(self, key, value): + # 看看有没有重复键 + contains = 1 if key in self.keys() else 0 + # 判断最大长度 + if len(self) - contains>= self.max: + last = self.popitem(last=False) # last 为false时就删除第一个添加的键值对,否则删除最后的键值对 + print('pop', last) + # 增加元素 + if contains: # 键原来存在,直接修改 + del self[key] + print('update', key, value) + else: + print('add', key, value) + OrderedDict.__setitem__(self, key, value) + + +lud = LastUpdateDict(3) +lud['a'] = 1 +lud['b'] = 2 +lud['c'] = 3 +print(lud) +lud['d'] = 4 +print(lud) +lud['b'] = 5 +print(lud) From 0aaa379602490c6026821ca64f927bdc955f32cc Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: 2018年2月27日 00:57:33 +0800 Subject: [PATCH 11/29] =?UTF-8?q?=E7=BB=83=E4=B9=A0=E5=86=85=E5=BB=BA?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E4=B9=8Bbase64?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test40.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 test40.py diff --git a/test40.py b/test40.py new file mode 100644 index 0000000..1b03856 --- /dev/null +++ b/test40.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +'练习内建模块之base64' + +__author__ = 'sergiojune' +import base64 + +# 进行base64编码,转为字符串 +b = b'binary\x00strg=' +bs = base64.b64encode(b) +print(bs) +# 解码 +b = base64.b64decode(bs) +print(b) + + +# 对于网页的安全编码 +s = b'i\xb7\x1d\xfb\xef\xff' +bs = base64.b64encode(s) +print(bs) +bs = base64.urlsafe_b64encode(s) +print(bs) + + +# 作业:请写一个能处理去掉=的base64解码函数 +def safe_base64_decode(s): + while len(s) % 4 !=0: + s += b'=' + bs = base64.b64decode(s) + return bs + + +# 测试: +assert b'abcd' == safe_base64_decode(b'YWJjZA=='), safe_base64_decode('YWJjZA==') +assert b'abcd' == safe_base64_decode(b'YWJjZA'), safe_base64_decode('YWJjZA') +print('ok') \ No newline at end of file From 9c78944781eed17693948276f12dcfbc0d3ec442 Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: 2018年2月27日 13:35:30 +0800 Subject: [PATCH 12/29] =?UTF-8?q?=E7=BB=83=E4=B9=A0=E5=86=85=E5=BB=BA?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E4=B9=8Bstruct?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test41.py | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 test41.py diff --git a/test41.py b/test41.py new file mode 100644 index 0000000..a32a30a --- /dev/null +++ b/test41.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 +# -*- conding: utf-8 -*- + +'练习内建模块之struct' + +__author__ = 'sergiojune' +import struct,base64 + +# 这个模块是将bytes与其他二进制数据互相转换 +# 将任意数据类型转为bytes +i = 10249999 +b = struct.pack('>I', i) # 第一个参数为处理指令 +print(b) + +s = 123.456 +b = struct.pack('f', s) +print(b) + + +# 将bytes转为其他任意类型 +s = struct.unpack('f', b) +print(s) + +s = b'\x42\x4d\x38\x8c\x0a\x00\x00\x00\x00\x00\x36\x00\x00\x00\x28\x00\x00\x00\x80\x02\x00\x00\x68\x01\x00\x00\x01\x00\x18\x00' +un = struct.unpack(' Date: 2018年2月27日 14:40:50 +0800 Subject: [PATCH 13/29] =?UTF-8?q?=E7=BB=83=E4=B9=A0=E5=86=85=E5=BB=BA?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E4=B9=8Bhashlib?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test42.py | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 test42.py diff --git a/test42.py b/test42.py new file mode 100644 index 0000000..b3d6c13 --- /dev/null +++ b/test42.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python3 +# -*- conding: utf-8 -*- + +'练习内建模块之hashlib' + +__author__ = 'sergiojune' +import random, hashlib # 这个包是用于存储数据,防止别人随意修改数据的类,不能用于加密,因为不支持反推明文 + +s = 'my name is sergiojune' +# 进行MD5保密 +md = hashlib.md5() +md.update(s.encode('utf-8')) # 指定编码方式 +# 获取加密后的值 +print(md.hexdigest()) +# 修改一点内容后 +s = 'my name is june' +md5 = hashlib.md5() +md5.update(s.encode('utf-8')) +print(md5.hexdigest()) # 通常结果是128位的bit,用32位的16进制表示 + + +# 使用sha1,用法与md5一样 +sha = hashlib.sha1() +sha.update(s.encode('utf-8')) +print(sha.hexdigest()) # 结果是160位的bit,用40位的16进制表示 + +# 作业1:设计一个验证用户登录的函数,根据用户输入的口令是否正确,返回True或False +db = { + 'michael': 'e10adc3949ba59abbe56e057f20f883e', + 'bob': '878ef96e86145580c38c87f0410ad153', + 'alice': '99b1c2188db85afee403b1536010c2c9' +} + + +def login(user, passwd): + m = hashlib.md5() + m.update(passwd.encode('utf-8')) + return db[user] == m.hexdigest() + + +# 测试: +assert login('michael', '123456') +assert login('bob', 'abc999') +assert login('alice', 'alice2008') +assert not login('michael', '1234567') +assert not login('bob', '123456') +assert not login('alice', 'Alice2008') +print('ok') + + +# 作业2:根据用户输入的登录名和口令模拟用户注册,计算更安全的MD5 +def get_md5(s): + return hashlib.md5(s.encode('utf-8')).hexdigest() + + +class User(object): + def __init__(self, username, password): + self.username = username + self.salt = ''.join([chr(random.randint(48, 122)) for i in range(20)]) + self.password = get_md5(password + self.salt) + + +db = { + 'michael': User('michael', '123456'), + 'bob': User('bob', 'abc999'), + 'alice': User('alice', 'alice2008') +} + + +def login(username, password): + user = db[username] + password = password + user.salt + return user.password == get_md5(password) + + +# 测试: +assert login('michael', '123456') +assert login('bob', 'abc999') +assert login('alice', 'alice2008') +assert not login('michael', '1234567') +assert not login('bob', '123456') +assert not login('alice', 'Alice2008') +print('ok') From 166f791df6209311752221feb90ec0d8cdf586f2 Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: 2018年2月27日 15:05:57 +0800 Subject: [PATCH 14/29] =?UTF-8?q?=E7=BB=83=E4=B9=A0=E5=86=85=E5=BB=BA?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E4=B9=8Bhmac?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test43.py | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 test43.py diff --git a/test43.py b/test43.py new file mode 100644 index 0000000..db8a3b6 --- /dev/null +++ b/test43.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 +# -*- conding: utf-8 -*- + +'练习内建模块之hmac' + +__author__ = 'sergiojune' +import random, hmac # 这个模块是可以根据口令进行加密保存数据,相当于md5加slat的效果,还比他强 +message = b'hello world' +key = b'key' +# 第一个和第二个参数都必须是bytes类型 +p = hmac.new(key, message, digestmod='md5') # 指定md5算法,一个参数为口令,第二个为加密的信息 +print(p.hexdigest()) + + +# 作业:将上一节的salt改为标准的hmac算法,验证用户口令 +def hmac_md5(key, s): + return hmac.new(key.encode('utf-8'), s.encode('utf-8'), 'MD5').hexdigest() + + +class User(object): + def __init__(self, username, password): + self.username = username + self.key = ''.join([chr(random.randint(48, 122)) for i in range(20)]) + self.password = hmac_md5(self.key, password) + + +db = { + 'michael': User('michael', '123456'), + 'bob': User('bob', 'abc999'), + 'alice': User('alice', 'alice2008') +} + + +def login(username, password): + user = db[username] + return user.password == hmac_md5(user.key, password) + + +# 测试: +assert login('michael', '123456') +assert login('bob', 'abc999') +assert login('alice', 'alice2008') +assert not login('michael', '1234567') +assert not login('bob', '123456') +assert not login('alice', 'Alice2008') +print('ok') From 1c44c4428972cf62836e4f801c8b81248fd78e5c Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: 2018年2月27日 16:32:03 +0800 Subject: [PATCH 15/29] =?UTF-8?q?=E7=BB=83=E4=B9=A0=E5=86=85=E5=BB=BA?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E4=B9=8Bitertools?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test44.py | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 test44.py diff --git a/test44.py b/test44.py new file mode 100644 index 0000000..c9c32b2 --- /dev/null +++ b/test44.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 +# -*- conding: utf-8 -*- + +'练习内建模块之itertools' + +__author__ = 'sergiojune' +import itertools # 操作可迭代对象的 + +# # 无限迭代列表,这是个自然数列表,参数为起始数字,第二个参数为步长 +# c = itertools.count(1) +# for x in c: +# print(x) + +# 无限循环迭代一个列表 +# for x in itertools.cycle('abc'): +# print(x) + +# 重复迭代元素n次 +# for x in itertools.repeat('abc', 6): # 第二个参数为迭代次数 +# print(x) + +# 用takewhile()方法停止无限循环的迭代 +c = itertools.count(1,2) +l = list(itertools.takewhile(lambda x: x<10, c)) # 第一个为接受函数,返回False就停止迭代,第二个为无限迭代的列表 +print(l) + +# 把一组可迭代的对象连接起来 +l1 = [x for x in range(5)] +l2 = {1, 3, 5} # 不同类型也可以 连接起来 +i = list(itertools.chain(l1, l2)) +print(i) + +# 将相同的元素分到同一组 +for x, y in itertools.groupby('aaabbbccc'): + print(x, list(y)) + +# 可以设置不区分大小写 +for x in itertools.groupby('AABBCCaAcdb',lambda x: x.lower()): + print(list(x)[0], list(list(x)[1])) + + +# 作业:计算圆周率可以根据公式:利用Python提供的itertools模块,我们来计算这个序列的前N项和 +def pi(N): + ' 计算pi的值 ' + # step 1: 创建一个奇数序列: 1, 3, 5, 7, 9, ... + odd_list = (x for x in itertools.count(1,2)) + # step 2: 取该序列的前N项: 1, 3, 5, 7, 9, ..., 2*N-1. + n_list = [next(odd_list) for x in range(N)] + # step 3: 添加正负符号并用4除: 4/1, -4/3, 4/5, -4/7, 4/9, ... + calc_list = list(map(lambda x: (4/x) if (x-1)/2 % 2 == 0 else (-4/x), n_list)) + # step 4: 求和: + s = sum(calc_list) + return s + + +# 测试: +print(pi(10)) +print(pi(100)) +print(pi(1000)) +print(pi(10000)) +assert 3.04 < pi(10) < 3.05 +assert 3.13 < pi(100) < 3.14 +assert 3.140 < pi(1000) < 3.141 +assert 3.1414 < pi(10000) < 3.1415 +print('ok') From d0600a2bd5f1905872e787d0eedc35eca562353d Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: 2018年2月27日 17:22:54 +0800 Subject: [PATCH 16/29] =?UTF-8?q?=E7=BB=83=E4=B9=A0=E5=86=85=E5=BB=BA?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E4=B9=8Bcontextlib?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test45.py | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 test45.py diff --git a/test45.py b/test45.py new file mode 100644 index 0000000..ff89e51 --- /dev/null +++ b/test45.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +# -*- conding: utf-8 -*- + +'练习内建模块之contextlib' + +__author__ = 'sergiojune' +import contextlib # 这个模块是用来设置上下文管理器的,里面有两个很好用的装饰器 +import requests + +class Query(): + def __init__(self, name): + self.name = name + + def query(self): + print('query data is %s' % self.name) + + +@contextlib.contextmanager +# 这个方法不是类的 +def create_query(name): + q = Query(name) + yield q # 生成器,用with就是返回这个东西 + print('end') # 当语句块执行完时就执行这个语句 + + +with create_query('bob') as q: + q.query() + print('query end') + + +# 可以用上面的装饰器实现在运行代码之前自动运行某些代码 +class Html(object): + def __init__(self, name): + self.name = name + + def put_start(self): + print('<%s>' % self.name, end='') + + def put_end(self): + print('' % self.name) + + +@contextlib.contextmanager +def create(name): + h = Html(name) + h.put_start() + yield h + h.put_end() + + +with create('h1') as h: + print('我是标题', end='') + + +# 如果一个对象没有实现上下文方法,我们还可以用colsing这个方法 +with contextlib.closing(requests.get('https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001478651770626de401ff1c0d94f379774cabd842222ff000')) as f: + print(f.text) + + + From c765f1a288be70232f28c6196b103e426a6c8dfb Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: 2018年2月27日 19:53:17 +0800 Subject: [PATCH 17/29] =?UTF-8?q?=E7=BB=83=E4=B9=A0=E5=86=85=E5=BB=BA?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E4=B9=8BHTMLParser?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test46.py | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 test46.py diff --git a/test46.py b/test46.py new file mode 100644 index 0000000..3ef2473 --- /dev/null +++ b/test46.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python3 +# -*- conding: utf-8 -*- + +'练习内建模块之HTMLParser' + +__author__ = 'sergiojune' +from html.parser import HTMLParser +import requests + + +class MyHTMLParser(HTMLParser): + + def handle_starttag(self, tag, attrs): # 这个是处理开始标签 + print('<%s>' % tag, list(attrs)) + + def handle_endtag(self, tag): # 这个是处理结束标签 + print('' % tag) + + def handle_data(self, data): # 这个是处理标签里的内容 + print(data) + + def handle_comment(self, data): # 这个是处理注释 + print('') + + def handle_entityref(self, name): # 这个是处理特殊字符,比如 + print('&%s;' % name) + + def handle_charref(self, name): # 这个是处理特殊字符,比如Ӓ + print('&#%s;' % name) + + +parser = MyHTMLParser() +parser.feed(''' + +
+ +

Some html HTML tutorial...
END

+

AltStyle によって変換されたページ (->オリジナル) /

''') + + +# 作业:找一个网页,例如https://www.python.org/events/python-events/,用浏览器查看源码并复制,然后尝试解析一下HTML,输出Python官网发布的会议时间、名称和地点。 +class DealHTML(HTMLParser): + def __init__(self): + super(DealHTML, self).__init__() + self.thing = 0 + self.time = 0 + self.address = 0 + + def handle_starttag(self, tag, attrs): + if len(attrs) == 1: + if 'python-events' in list(attrs)[0][1]: # 获取工作事件 + print('' % list(attrs)[0][1], end='') + self.thing = 1 + if 'datetime' in list(attrs)[0][0]: # 获取工作时间 + print('<%s>' % list(attrs)[0][0], end='') + self.time = 1 + if 'location' in list(attrs)[0][1]: # 获取工作地点 + print('<%s>' % list(attrs)[0][1], end='') + self.address = 1 + + def handle_data(self, data): + if self.thing: + print(data, end='') + if self.time: + print(data, end='') + if self.address: + print(data, end='') + + def handle_endtag(self, tag): + if self.thing: + print('' % tag) + self.thing = 0 + if self.time: + print('' % tag) + self.time = 0 + if self.address: + print('' % tag) + print('') + self.address = 0 + + +response = requests.get('https://www.python.org/events/python-events/').text +dh = DealHTML() +dh.feed(response) From 736228fc41e2ac4e2b62b55a459d96e871586791 Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: 2018年2月28日 00:00:11 +0800 Subject: [PATCH 18/29] =?UTF-8?q?=E7=BB=83=E4=B9=A0=E7=AC=AC=E4=B8=89?= =?UTF-8?q?=E6=96=B9=E6=A8=A1=E5=9D=97=E4=B9=8Bpillow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test47.py | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 test47.py diff --git a/test47.py b/test47.py new file mode 100644 index 0000000..360161a --- /dev/null +++ b/test47.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +# -*- conding: utf-8 -*- + +'练习第三方模块之pillow' + +__author__ = 'sergiojune' +from PIL import Image, ImageFilter, ImageDraw, ImageFont +import random +# 对图像进行缩小 +im = Image.open('test.jpg') +w, h = im.size # 获取图片的宽高 +print('origin image width is %d, height is %d' % (w, h)) +# 进行缩小一倍 +im.thumbnail((w//2, h//2)) # 参数是一个元组,对应的是宽高 +im.save('suoxiao.png', 'png') +print('now width is %d, height is %d' % (im.size[0], im.size[1])) + +# 还可以对图像进行模糊化 +im2 = im.filter(ImageFilter.BLUR) +im2.save('muhu.png', 'png') + + +# 利用这个模块产生验证码 +def rndchar(): # 产生随机字符 + return chr(random.randint(65, 90)) + + +def rndcolor(): # 随机颜色 + return (random.randint(64, 255), random.randint(64, 255), random.randint(64, 255)) + + +def rndcolor2(): + return (random.randint(32, 127), random.randint(32, 127), random.randint(32, 127)) + + +width = 240 +height = 40 +# 创建图像对象 +im = Image.new('RGB', (width, height), (255, 255, 255)) +# 创建字体 +font = ImageFont.truetype(r'E:\python_project\Lib\site-packages\matplotlib\mpl-data\fonts\ttf\cmsy10.ttf', 36) +# 创建画笔 +draw = ImageDraw.Draw(im) +# 填充图片 +for x in range(width): + for y in range(height): + draw.point((x, y), fill=rndcolor2()) +# 写文字 +for x in range(4): + draw.text((60*x+10, 10), rndchar(), font=font, fill=rndcolor()) + +# mohu +im.filter(ImageFilter.BLUR) +# 保存图片 +im.save('yan.png', 'png') From 0166a0b2d38fc298058fe1de2799e385488d9974 Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: 2018年2月28日 00:12:55 +0800 Subject: [PATCH 19/29] =?UTF-8?q?=E7=BB=83=E4=B9=A0=E7=AC=AC=E4=B8=89?= =?UTF-8?q?=E6=96=B9=E6=A8=A1=E5=9D=97=E4=B9=8Bchardet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test48.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 test48.py diff --git a/test48.py b/test48.py new file mode 100644 index 0000000..64ee6ab --- /dev/null +++ b/test48.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +# -*- conding: utf-8 -*- + +'练习第三方模块之chardet' + +__author__ = 'sergiojune' +import chardet # 这个库是用来猜测字节码的编码方式的 + +s = b'hello world' +c = chardet.detect(s) +print(c) +# 结果:{'encoding': 'ascii', 'confidence': 1.0, 'language': ''},可以看出是ascii编码,第二个为概率,1.0表示百分百 + +s = '中国中文我爱你' +c = chardet.detect(s.encode('gbk')) +print(c) + +c = chardet.detect(s.encode('utf-8')) +print(c) + +# 看看日语的 +s = '最新の主要ニュース' +c = chardet.detect(s.encode('euc-jp')) +print(c) + +# encode()为编码,将字符串变为字节码,decode()为解码,将字节码转为字符串 From c565b3841aa342dbce3f0ad9abe5191f5a3432f6 Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: 2018年2月28日 22:33:09 +0800 Subject: [PATCH 20/29] =?UTF-8?q?=E7=94=A8=E4=BA=8E=E7=BB=83=E4=B9=A0?= =?UTF-8?q?=E7=BD=91=E7=BB=9C=E7=BC=96=E7=A8=8BTCP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test49.py | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 test49.py diff --git a/test49.py b/test49.py new file mode 100644 index 0000000..ec6e3a6 --- /dev/null +++ b/test49.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +'用于练习网络编程TCP' + +__author__ = 'sergiojune' +import socket, threading, time + +# 创建socket +# s = socket.socket(socket.AF_INET , socket.SOCK_STREAM) # 第一个参数为指定ipv4模式, 第二个参数指定为tup模式的面向流 +# # 建立连接 +# s.connect(('www.sina.com.cn', 80)) +# # 发送请求 +# s.send(b'GET / HTTP/1.1\r\nHost: www.sina.com.cn\r\nConnection: close\r\n\r\n') # 发送get请求,http协议 +# # 处理返回来的数据 +# buffer = [] +# while True: +# # 指定最大接受1024个字节 +# d = s.recv(1024) +# if d: +# buffer.append(d) +# else: +# break +# data = b''.join(buffer) +# # 关闭连接 +# s.close() +# 取出请求头和内容 +# header, body =data.split(b'\r\n') +# print(header) +# print(body) + + +# 建立服务器端 +s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +# 绑定端口和地址,当有信息从这个端口发送过来时就捕捉 +s.bind(('127.0.0.1', 9999)) # 这个为本机ip,这个服务器只能接受本地的 +# 监听窗口 +s.listen(5) # 传入参数为最大的等待连接数 +print('await for connect') +def tcplink(sock, add): + print('here is a connector from %s:%s' % add) + # 向客户端发送数据 + sock.send(b'Welcome') + # 处理客户端发送来的数据 + while True: + d = sock.recv(1024) + time.sleep(1) + if not d or d == b'exit': + break + sock.send(('hello %s !' % d.decode('utf-8')).encode('utf-8')) + # 关闭连接 + sock.close() + print('connect is closed') + +# 用永久循环来等待客户端连接 +while True: + # 这个函数会返回一个客户端连接 + sock, add = s.accept() + # 创建线程来处理客户端的数据 + t = threading.Thread(target=tcplink, args=(sock, add)) + # 开启线程 + t.start() From 2b818eab3a7d64065d4791af5dd98fa4ba881427 Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: 2018年2月28日 22:33:29 +0800 Subject: [PATCH 21/29] =?UTF-8?q?=E9=85=8D=E5=90=88test49=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E7=9A=84=E6=9C=8D=E5=8A=A1=E5=99=A8=EF=BC=8C=E8=BF=99?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=BD=93=E4=BD=9C=E5=AE=A2=E6=88=B7=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test50.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 test50.py diff --git a/test50.py b/test50.py new file mode 100644 index 0000000..721bcf3 --- /dev/null +++ b/test50.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +'配合test49文件的服务器,这文件当作客户端' + +__author__ = 'sergiojune' +import socket + +# 建立socket +s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +# 连接地址 +s.connect(('127.0.0.1', 9999)) +# 接受返回的数据 +print(s.recv(1024).decode('utf-8')) +# 发送数据 +for x in [b'bob', b'amy', b'june']: + print('send %s' % x) + s.send(x) + print(s.recv(1024).decode('utf-8')) +# 发送退出数据 +s.send(b'exit') +s.close() +print('connect is closed from kehuuduan') From 96c3cd6b58e8c7c7aea513f38a459bf6874ff541 Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: Thu, 1 Mar 2018 21:14:37 +0800 Subject: [PATCH 22/29] =?UTF-8?q?=E7=BB=83=E4=B9=A0python=E7=9A=84?= =?UTF-8?q?=E5=8D=8F=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test53.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 test53.py diff --git a/test53.py b/test53.py new file mode 100644 index 0000000..d7f37b8 --- /dev/null +++ b/test53.py @@ -0,0 +1,37 @@ +#!/usr.bin.env python 3 +# -*- coding: utf-8 -*- + +''' +练习python的协程0 +next(方法和next()方法在一定意义上是相同用法的,只不过next不能传递特定的值而next可以传递特定的值 +next() 和send(None) 方法是等价的,都是用于启动生成器返回值 +''' + +__author__ = 'sergiojune' + + +# 消费者 +def consumer(): + r = '' + while True: + n = yield r # 接受调用者发送的数据 + if not n: + return + print('consumer consume is %s' % n) + r = '200 OK' + + +def producer(c): # 这个函数先被执行 + c.send(None) # 这个语句必须写,而且参数固定,作用是启动上面的生成器 + x = 0 + while x < 5: + x = x+1 + print('producer is produce %d' % x) + r = c.send(x) # 发送数据,生成器接受数据,赋值给n变量 + print('consumer is return %s' % r) + # 关闭 + c.close() + + +c = consumer() +producer(c) From 28081d9d3705f3f9f171a737adeac39aa2291048 Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: Thu, 1 Mar 2018 21:54:48 +0800 Subject: [PATCH 23/29] =?UTF-8?q?=E7=BB=83=E4=B9=A0python=E7=9A=84asyncio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test54.py | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 test54.py diff --git a/test54.py b/test54.py new file mode 100644 index 0000000..46b6db3 --- /dev/null +++ b/test54.py @@ -0,0 +1,55 @@ +#!/usr.bin.env python 3 +# -*- coding: utf-8 -*- + +''' +练习python的asyncio +''' + +__author__ = 'sergiojune' +import asyncio,threading + + +@asyncio.coroutine # 这个装饰器是把生成器标记成为coroutine +def hello(): + r = '' + print('hello world(%s)' % threading.current_thread()) + n = yield from asyncio.sleep(1) # 这个方法也是个coroutine,执行到这里后会等待该方法返回数给这个coroutine + print('hello again(%s)' % threading.current_thread()) + + +# 这是练习一个协程的 +# # 获取事件循环,就是eventloop +# loop = asyncio.get_event_loop() +# # 执行coroutine,参数是需要运行的协程 +# loop.run_until_complete(hello()) +# # 关闭 +# loop.close() + + +# 这个执行两个hello +# l = asyncio.get_event_loop() +# # 把协程放到eventloop里面 +# # 这两个方法是并发执行的 +# l.run_until_complete(asyncio.wait([hello(), hello()])) # wait()是将参数里的协程转为一个包括他们在内的单独协程 +# l.close() + + +# 练习用异步连接新浪搜狐和网易云 +def wget(host): + print('ready ro connect %s' % host) + connect = asyncio.open_connection(host, 80) + reader, writer = yield from connect # 这个io操作比较耗时,所以会执行下个协程 + header = 'GET/HTTP/1.1\r\nHost:%s\r\n\r\n' % host + writer.write(header.encode('utf-8')) + yield from writer.drain() # 用于刷新缓存区的内容,确保将内容提交上去 + while True: + line = yield from reader.readline() # 这个io操作有时不耗时,会直接运行整个循环 + if line == b'\r\n': + break + print('%s header>%s' % (host, line.decode('utf-8').strip())) + writer.close() + + +loop = asyncio.get_event_loop() +loop.run_until_complete(asyncio.wait([wget(host) for host in ['www.sina.com.cn', 'www.sohu.com', 'www.163.com']])) +loop.close() From b47fb5f60742040885c3581250a83891dd3534a5 Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: Thu, 1 Mar 2018 21:58:38 +0800 Subject: [PATCH 24/29] Delete test54.py --- test54.py | 55 ------------------------------------------------------- 1 file changed, 55 deletions(-) delete mode 100644 test54.py diff --git a/test54.py b/test54.py deleted file mode 100644 index 46b6db3..0000000 --- a/test54.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr.bin.env python 3 -# -*- coding: utf-8 -*- - -''' -练习python的asyncio -''' - -__author__ = 'sergiojune' -import asyncio,threading - - -@asyncio.coroutine # 这个装饰器是把生成器标记成为coroutine -def hello(): - r = '' - print('hello world(%s)' % threading.current_thread()) - n = yield from asyncio.sleep(1) # 这个方法也是个coroutine,执行到这里后会等待该方法返回数给这个coroutine - print('hello again(%s)' % threading.current_thread()) - - -# 这是练习一个协程的 -# # 获取事件循环,就是eventloop -# loop = asyncio.get_event_loop() -# # 执行coroutine,参数是需要运行的协程 -# loop.run_until_complete(hello()) -# # 关闭 -# loop.close() - - -# 这个执行两个hello -# l = asyncio.get_event_loop() -# # 把协程放到eventloop里面 -# # 这两个方法是并发执行的 -# l.run_until_complete(asyncio.wait([hello(), hello()])) # wait()是将参数里的协程转为一个包括他们在内的单独协程 -# l.close() - - -# 练习用异步连接新浪搜狐和网易云 -def wget(host): - print('ready ro connect %s' % host) - connect = asyncio.open_connection(host, 80) - reader, writer = yield from connect # 这个io操作比较耗时,所以会执行下个协程 - header = 'GET/HTTP/1.1\r\nHost:%s\r\n\r\n' % host - writer.write(header.encode('utf-8')) - yield from writer.drain() # 用于刷新缓存区的内容,确保将内容提交上去 - while True: - line = yield from reader.readline() # 这个io操作有时不耗时,会直接运行整个循环 - if line == b'\r\n': - break - print('%s header>%s' % (host, line.decode('utf-8').strip())) - writer.close() - - -loop = asyncio.get_event_loop() -loop.run_until_complete(asyncio.wait([wget(host) for host in ['www.sina.com.cn', 'www.sohu.com', 'www.163.com']])) -loop.close() From 1681b049208fcf2956ab5835bf24e7a4021a873a Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: Thu, 1 Mar 2018 21:58:58 +0800 Subject: [PATCH 25/29] =?UTF-8?q?=E7=BB=83=E4=B9=A0python=E7=9A=84asyncio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test54.py | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 test54.py diff --git a/test54.py b/test54.py new file mode 100644 index 0000000..5b29d01 --- /dev/null +++ b/test54.py @@ -0,0 +1,56 @@ +#!/usr.bin.env python 3 +# -*- coding: utf-8 -*- + +''' +练习python的asyncio +yield form 语句返回的值是后面表达式迭代后遇到StopIteration后再return(这个语句) 的值,无这个语句是返回None +''' + +__author__ = 'sergiojune' +import asyncio,threading + + +@asyncio.coroutine # 这个装饰器是把生成器标记成为coroutine +def hello(): + r = '' + print('hello world(%s)' % threading.current_thread()) + n = yield from asyncio.sleep(1) # 这个方法也是个coroutine,执行到这里后会等待该方法返回数给这个coroutine + print('hello again(%s)' % threading.current_thread()) + + +# 这是练习一个协程的 +# # 获取事件循环,就是eventloop +# loop = asyncio.get_event_loop() +# # 执行coroutine,参数是需要运行的协程 +# loop.run_until_complete(hello()) +# # 关闭 +# loop.close() + + +# 这个执行两个hello +# l = asyncio.get_event_loop() +# # 把协程放到eventloop里面 +# # 这两个方法是并发执行的 +# l.run_until_complete(asyncio.wait([hello(), hello()])) # wait()是将参数里的协程转为一个包括他们在内的单独协程 +# l.close() + + +# 练习用异步连接新浪搜狐和网易云 +def wget(host): + print('ready ro connect %s' % host) + connect = asyncio.open_connection(host, 80) + reader, writer = yield from connect # 这个io操作比较耗时,所以会执行下个协程 + header = 'GET/HTTP/1.1\r\nHost:%s\r\n\r\n' % host + writer.write(header.encode('utf-8')) + yield from writer.drain() # 用于刷新缓存区的内容,确保将内容提交上去 + while True: + line = yield from reader.readline() # 这个io操作有时不耗时,会直接运行整个循环 + if line == b'\r\n': + break + print('%s header>%s' % (host, line.decode('utf-8').strip())) + writer.close() + + +loop = asyncio.get_event_loop() +loop.run_until_complete(asyncio.wait([wget(host) for host in ['www.sina.com.cn', 'www.sohu.com', 'www.163.com']])) +loop.close() From e8545dd5f50f00cbbeb36af78424bb18c95520cc Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: Thu, 1 Mar 2018 22:14:49 +0800 Subject: [PATCH 26/29] =?UTF-8?q?=E7=BB=83=E4=B9=A0python=E7=9A=84async/aw?= =?UTF-8?q?ait?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test55.py | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 test55.py diff --git a/test55.py b/test55.py new file mode 100644 index 0000000..af91a14 --- /dev/null +++ b/test55.py @@ -0,0 +1,52 @@ +#!/usr.bin.env python 3 +# -*- coding: utf-8 -*- + +''' +练习python的async/await +async:相当于asyncio.coroutine,可以用这个替换这个更加方便 +await:相当于yield form,把这个改成await即可替代 +以上都是在python3.5版本以上才有的 +''' + +__author__ = 'sergiojune' +import asyncio + + +async def hello(): # 这样就是相当于一个coroutine了 + print('hello world') + await asyncio.sleep(1) + print('hello again') + + +# loop = asyncio.get_event_loop() +# loop.run_until_complete(hello()) +# loop.close() + + +# 两个协程 +# loop = asyncio.get_event_loop() +# loop.run_until_complete(asyncio.wait([hello(), hello()])) +# loop.close() + + +# 再用这个方法连接搜狐新浪和网易 +async def wegt(host): + print('wegt %s ' % host) + # 连接 + connect = asyncio.open_connection(host, 80) + reader, writer = await connect + header = 'GET/HTTP/1.0\r\nHost:%s\r\n\r\n' % host + writer.write(header.encode('utf-8')) + await writer.drain() # 相当于刷新缓存 + while True: + line = await reader.readline() + if line == b'\r\n': + print() + break + print('%s header> %s' % (host, line.decode('utf-8').strip())) + connect.close() + + +loop = asyncio.get_event_loop() +loop.run_until_complete(asyncio.wait([wegt(host) for host in ['www.sina.com.cn', 'www.sohu.com', 'www.163.com']])) +loop.close() From fb69443072a552baa30ca3d2e19716a50415a695 Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: Thu, 1 Mar 2018 23:09:57 +0800 Subject: [PATCH 27/29] =?UTF-8?q?=E7=BB=83=E4=B9=A0python=E7=9A=84aiohttp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test56.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 test56.py diff --git a/test56.py b/test56.py new file mode 100644 index 0000000..f414767 --- /dev/null +++ b/test56.py @@ -0,0 +1,38 @@ +#!/usr.bin.env python 3 +# -*- coding: utf-8 -*- + +''' +练习python的aiohttp +练习服务器上的异步操作 +''' + +__author__ = 'sergiojune' +import asyncio +from aiohttp import web + + +async def index(request): # 首页返回一个h1标签 + await asyncio.sleep(0.5) + return web.Response(body=b'

index

', content_type='text/html') + + +async def hello(request): # 根据url参数返回信息 + await asyncio.sleep(0.5) + return web.Response(body=b'

hello %s

' % request.match_info['name'], content_type='text/html') + + +# 初始化服务器,也是一个coroutine +async def init(loop): # 接受协程池 + app = web.Application(loop=loop) + # 添加反应路径 + app.router.add_route('GET', '/', index) + app.router.add_route('GET', '/hello/{name}', hello) + s = loop.create_server(app.make_handler(), '', 80) # 用loop.create_server创建tcp协议 + print('sever is start in 127.0.0.1:80') + return s + + +loop = asyncio.get_event_loop() +loop.run_until_complete(init(loop)) +loop.run_forever() # 服务器永远运行 + From 709aec2648d6bfda3511de004beac9fe5c8ab5ec Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: Thu, 1 Mar 2018 23:10:47 +0800 Subject: [PATCH 28/29] =?UTF-8?q?=E7=BB=83=E4=B9=A0UDP=E7=BD=91=E7=BB=9C?= =?UTF-8?q?=E5=8D=8F=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test51.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 test51.py diff --git a/test51.py b/test51.py new file mode 100644 index 0000000..81a0fac --- /dev/null +++ b/test51.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +'练习UDP网络协议' + +__author__ = 'sergiojune' +import socket + +# 此文件用于当服务器 +# 创建socket +s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 第二个参数为指定udp协议 +# 绑定端口,不需要监听 +s.bind(('127.0.0.1', 9999)) +print('await connect') +while True: + data, addr = s.recvfrom(1024) # 这个直接返回客户端的ip和请求信息 + print('connect form %s:%s' % addr) + # 发送数据回客户端 + s.sendto(b'hello %s' % data, addr) # 第二个参数为发送到的ip From 13d757788d2e654633473efe78deb45a2c038d88 Mon Sep 17 00:00:00 2001 From: sergiojune <2217532592@qq.com> Date: Thu, 1 Mar 2018 23:11:07 +0800 Subject: [PATCH 29/29] =?UTF-8?q?udp=E9=85=8D=E5=90=88test51=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E7=9A=84=E6=9C=8D=E5=8A=A1=E5=99=A8=EF=BC=8C=E8=BF=99?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=BD=93=E4=BD=9C=E5=AE=A2=E6=88=B7=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test52.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 test52.py diff --git a/test52.py b/test52.py new file mode 100644 index 0000000..54ea8f1 --- /dev/null +++ b/test52.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +'udp配合test51文件的服务器,这文件当作客户端' + +__author__ = 'sergiojune' +import socket + +# 创建socket +s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +# UDP协议不需要建立连接 +for x in [b'bret', b'tom', b'sergiojune']: + s.sendto(x, ('127.0.0.1', 9999)) + print(s.recv(1024).decode('utf-8')) +s.close()