hysic / omooc2py Goto Github PK
View Code? Open in Web Editor NEWThis project forked from aihackers/omooc2py
https://www.gitbook.com/book/hysic/hysic-s-python-journey/details
License: MIT License
This project forked from aihackers/omooc2py
https://www.gitbook.com/book/hysic/hysic-s-python-journey/details
License: MIT License
~ 任务需求
- 每次运行时合理的打印出过往的所有笔记
- 一次接收输入一行笔记
- 在服务端保存为文件:
- 在所有访问的客户端可以获得历史笔记
- 支持多个客户端同时进行笔记记录
socket 模块官方文档看的一头雾水, 对于我这样对 socket 没有基本常识的小白来说,通读一遍基本是一头雾水, 只好暂且放下, 留待后面查看.
google python socket udp
, 找到python wiki 中的 UDP Communication, 以及PyMOTW 上的User Datagram Client and Server, 二者的优点都是提供了一个创建 UDP server 和 client 的最小脚手架, 可以在此基础上添加自己需要的功能.
我主要以PyMOTW 上的User Datagram Client and Server为脚手架完成本周的任务.
import socket
# create a UDP server socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# bind the socket to the server address
server_address = ('localhost', 10001)
sock.bind(server_address)
# receive the data and the client address
data, client_address = sock.recvfrom(1024)
import socket
# create a UDP client socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address = ('localhost', 10001)
message = 'This is the message.'
# send the message to the server
sent = sock.sendto(message, server_address)
# close the socket
sock.close()
如此即可完成 server 和 client 之间的一次数据传送, 接下来以此为基础, 增加任务需求功能.
每次运行时合理的打印出过往的所有笔记
sent = sock.sendto(message, client_address)
, client 端增加 data, server = sock.recvfrom(1024)
.一次接收输入一行笔记
while True
无限循环, 利用raw_input()
函数提示用户输入.在服务端保存为文件
在所有访问的客户端可以获得历史笔记
with open("diary.log", "a+") as f:
, 输入一行保存一行.支持多个客户端同时进行笔记记录
接下来就是在 client 端增加一些默认参数, h/help/? 显示帮助, r/sync 显示历史记录, q/quit 退出 socket.然后用 if/elif/else
语句进行条件判断.
具体代码及代码说明见 https://github.com/hysic/OMOOC2py/tree/master/_src/om2py3w/3wex0.
任务需求的功能基本实现了, 下面看看任务代码具体是什么意思.
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
address famlily
, 用来声明 OSI 模型中网络层的协议, 常见的就是 AF_INET
, 即为 IPv4; 第二个是 socket type
, 用来声明 OSI 模型中传输层的协议, 常见的有两种, SOCK_DGRAM
用于 UDP 协议, SOCK_STREAM
用于 TCP 协议.Client/Server 架构(主从式架构), 是一种常见的软件架构模型, 我们日常所接触的网络基本都是 C/S 架构的, 如互联网, E-mail, 网络游戏, 微信.
与之相对的结构方式为 P2P(peer-to-peer)架构.
server 端的 socket 对象需要绑定(bind)一个 socket 地址. 一个 socket 地址包括一个 IP 地址和一个端口号(port number). 比如运行下面的代码:
import socket
print socket.getaddrinfo("www.python.org", "http")
即可得到
[(2, 2, 17, '', ('103.245.222.223', 80)),
(2, 1, 6, '', ('103.245.222.223', 80))]
('103.245.222.223', 80)就是 HTTP 连接 python 官网的 socket 地址.
用户数据报协议(英语:User Datagram Protocol,缩写为 UDP),是一个简单的面向数据报的传输层协议,正式规范为 RFC 768.
UDP只提供数据的不可靠传递,它一旦把应用程序发给网络层的数据发送出去,就不保留数据备份.
~ 本文 gitbook 地址: https://hysic.gitbooks.io/hysic-s-python-journey/content/1sTry/Week_1/Interactive101.html
完成一个极简交互式日记系统,需求如下:
- 一次接收输入一行日记
- 保存为本地文件
- 再次运行系统时,能打印出过往的所有日记
~ 芝麻星中"第一周行动"卡包中已经将任务进行初步分解, 我主要按照分解的任务依次进行, 必要时做进一步任务分解.
.py
文件,每次在CLI中以python main.py
运行之。只有 .py 的文件才是我们应该持续修订的开发容器.
——ZoomQuiet
import sys
python main.py argv1 argv2 ...
main.py
是第一个参数main.py
中定义的个数相同, 参数过多或过少都会产生ValueError
python main.py 中文
未出现异常.一次接收输入一行日记
~ 这里开始解决任务需求, 将任务需求进一步拆分.
~ 这里需要解决两个问题, 一个是持续运行, 等待继续输入或退出; 一个是如何退出.
while True
循环control-C
或 control-D
退出except KeyboardInterupt
之后一定要 break
, 否则无法退出无限循环sys.exit(exit_message)
, 无须 break
control-C
退出时,会在 exit_message
前多了一个^C
字符.保存为本地文件
~ 这里可进一步拆分为文件打开, 文件读取, 文件读入, 文件保存关闭.
open(file_name, mode)
file.write(message)
file.write
并不会写入换行符'\n'
file.close()
再次运行系统时,能打印出过往的所有日记
~ 任务进一步分解: 确认文件内容不为空, 文件读取并print
确认文件不为空
import os
if os.stat(file_name).st_size != 0:
pass
文件读取
f.read()
a+
方式打开的文件, 确认文件不为空后, 但 f.read()
输出却为空
a+
方式打开的文件, file position(我理解为文件中的光标)位于文件末尾, 这样当然读不出东西来了f.seek(0)
将 file position 放在文件开头, 然后再f.read()
就行了简单实现
import time
print time.asctime() # or time.ctime()
~ 任务需求
- 通过网页访问系统:
- 每次运行时合理的打印出过往的所有笔记
- 一次接收输入一行笔记
- 在服务端保存为文件
- 同时兼容 3w 的 Net 版本的命令行界面进行交互
~ 任务代码及说明: https://github.com/hysic/OMOOC2py/tree/master/_src/om2py4w/4wex0
上下班路上通读Bottle 官网 tutorial, 只是对 bottle 的功能有个大概的印象, 但对本周作业如何实现依然没什么思路.
requests
模块的官方文档, 则比较对我的胃口, 显示 Quickstart, 帮助你快速上手, 然后是 Advanced Usage, 讲一些进阶用法, 适合于不同程度的用户. 所以我目前的看法是, 官方文档不可不看, 但若不对口味, 可以 google 寻找其他对口味的教程, 先入门了再说.Bottle 框架的几个函数
~ 创建网页, 简单地说就是URL地址 + 网页内容(HTML+CSS+JS), 再就是与服务器的数据交互, Bottle 框架有几个函数分别做这几项事情.
route
路由, Bottle 中最重要的一个函数, 将 URL 与一个函数关联, 该函数的返回值则是这个 URL 对应网页的显示内容. 更重要的是, 这个 URL 可以是动态的, 可以用正则表达式涵盖好多类似的 URL 地址. route
还可以指定http 请求方法, 默认是 GET
.
@route('/diary')
def show_diary():
return template("write_diary.tpl", diary_file=filename)
比如这段代码对应的 URL 就是/diary
, 网页显示的内容就是 write_diary.tpl
这个模板里面的内容.
template
模板, 将 html 分离成一个单独的文件, 可以多次使用, 可以缓存, 同时还可以传入一些需要修改的参数. Bottle 内置了 Simple Template 引擎, 足够完成本周任务. 大妈推荐的 Jinja2
模板引擎, 留待后续使用.
<form action='/diary' method="POST">
<input type="text" size="100" maxlength="100" name="new_line" autofocus>
<input type="submit" name="save" value="保存">
</form>
<div id="diary_content">
%with open(diary_file) as f:
%for line in f:
<p>{{line[0: -1]}}</p>
%end
%end
</div>
这段代码就是我实现本周任务使用的模板, 注意到最后一个 div
里还有几行以%
开头的 python 代码, 模板是允许这种写法的, 可以在模板内插入 if
, for
等语句.
request
, 用于服务器端和客户端之间交换数据, 比如 new_line = request.POST.get('new_line', '')
用于从网页中名为 new_line
的 input 元素中获取客户端的输入内容.run
, 服务器运行, 默认地址是 localhost
, 默认端口是 8080
. 添加 reloader=True
参数可以在在修改代码后不用重启服务器, 对调试代码很有用, 但在上线后一定要删除.debug
, 调试, 可以在网页端直接显示报错信息.同时兼容 3w 的 Net 版本的命令行界面进行交互
localhost:8080/diary
, 然后 recv
数据, 可以毫无动静. 因为我服务器端并没有设置要向客户端 send
数据, 一切都是 bottle 封装好的 http 协议.requests
模块, google 之, 很diao.Requests: HTTP for Humans
import requests
# get the request data from the server page
r = requests.get("127.0.0.1:8080/diary")
print r.content
# post data to the server
rw = requests.post("127.0.0.1:8080/diary", data = {'new_line': "some_message"})
python html
, 找到 Python Guide 的这个页面, 里面介绍了 requests
模块, 还有 lxml
模块, 刚好就是我需要的!! 而且, lxml
模块一共介绍了三行代码, 刚好可以完成我的要求, 太赞了!import requests
from lxml import html
# get the request data from the server page
r = requests.get(server_address)
# parse the page content into a nice tree structure
tree = html.fromstring(r.content)
# use XPath to get to the html section you want
diary_content = tree.xpath('//div[@id="diary_content"]/p/text()')
print diary_content
get
和 post
方法分别对应什么. 虽然最后只用了一个 URL, 但那是因为网站本身不复杂, 要是复杂一点, 比如做一个 todo list 网站, 就需要像大妈那样做 URI 设计了.A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.