<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Development on 古思乱想</title><link>https://blog.gusibi.site/categories/development/</link><description>Recent content in Development on 古思乱想</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Sun, 01 Mar 2020 20:47:11 +0800</lastBuildDate><atom:link href="https://blog.gusibi.site/categories/development/index.xml" rel="self" type="application/rss+xml"/><item><title>Facilitating Technical Writing Courses</title><link>https://blog.gusibi.site/post/google-facilitating-technical-writing-courses/</link><pubDate>Sun, 01 Mar 2020 20:47:11 +0800</pubDate><guid>https://blog.gusibi.site/post/google-facilitating-technical-writing-courses/</guid><description>description</description></item><item><title>Technical Writing Courses</title><link>https://blog.gusibi.site/post/google-technical-writing-courses/</link><pubDate>Sun, 01 Mar 2020 20:46:40 +0800</pubDate><guid>https://blog.gusibi.site/post/google-technical-writing-courses/</guid><description>description</description></item><item><title>学习单元测试，告别祈祷式编程</title><link>https://blog.gusibi.site/post/unit-test/</link><pubDate>Mon, 07 Oct 2019 09:48:04 +0800</pubDate><guid>https://blog.gusibi.site/post/unit-test/</guid><description>单元测试编写指南</description></item><item><title>如何通过MD5反查身份证号？</title><link>https://blog.gusibi.site/post/id-md5-search/</link><pubDate>Sun, 18 Aug 2019 14:22:26 +0800</pubDate><guid>https://blog.gusibi.site/post/id-md5-search/</guid><description>如何通过MD5反查身份证号？</description></item><item><title>Redis 选择hash还是string 存储数据？</title><link>https://blog.gusibi.site/post/redis-string-or-hash-to-represent-json/</link><pubDate>Sat, 22 Jun 2019 11:29:15 +0800</pubDate><guid>https://blog.gusibi.site/post/redis-string-or-hash-to-represent-json/</guid><description>Redis 选择hash还是string 存储数据？</description></item><item><title>markdown中code生成图片的实现</title><link>https://blog.gusibi.site/post/markdown-code-to-image-2/</link><pubDate>Sat, 15 Jun 2019 23:34:53 +0800</pubDate><guid>https://blog.gusibi.site/post/markdown-code-to-image-2/</guid><description>markdown中code生成图片的实现</description></item><item><title>markdown中code生成图片的思路</title><link>https://blog.gusibi.site/post/markdown-code-to-image-1/</link><pubDate>Thu, 13 Jun 2019 23:34:53 +0800</pubDate><guid>https://blog.gusibi.site/post/markdown-code-to-image-1/</guid><description>markdown中code生成图片的思路</description></item><item><title>为什么json 不能使用 int64类型</title><link>https://blog.gusibi.site/post/why-json-unspport-int64/</link><pubDate>Mon, 03 Jun 2019 21:14:10 +0800</pubDate><guid>https://blog.gusibi.site/post/why-json-unspport-int64/</guid><description>json javacript 不能使用int64</description></item><item><title>PostgreSQL jsonb 使用入门</title><link>https://blog.gusibi.site/post/postgresql-json/</link><pubDate>Thu, 30 May 2019 21:05:57 +0800</pubDate><guid>https://blog.gusibi.site/post/postgresql-json/</guid><description>postgresql json jsonb 使用入门</description></item><item><title>创建高质量的代码--软件构建中的设计</title><link>https://blog.gusibi.site/post/design-in-software-construction/</link><pubDate>Wed, 29 May 2019 21:05:57 +0800</pubDate><guid>https://blog.gusibi.site/post/design-in-software-construction/</guid><description>代码大全 软件设计中的构建</description></item><item><title>并发模型：线程与锁</title><link>https://blog.gusibi.site/post/thread-and-lock/</link><pubDate>Sun, 19 May 2019 20:29:39 +0800</pubDate><guid>https://blog.gusibi.site/post/thread-and-lock/</guid><description>并发模型：线程与锁</description></item><item><title>JWT RefreshToken 实践</title><link>https://blog.gusibi.site/post/jwt-refresh-token/</link><pubDate>Mon, 29 Apr 2019 21:05:57 +0800</pubDate><guid>https://blog.gusibi.site/post/jwt-refresh-token/</guid><description>jwt refresh token</description></item><item><title>Golang mod 入门</title><link>https://blog.gusibi.site/post/golang-mod/</link><pubDate>Sat, 16 Mar 2019 19:49:35 +0800</pubDate><guid>https://blog.gusibi.site/post/golang-mod/</guid><description>golang mod</description></item><item><title>python设计模式-状态模式</title><link>https://blog.gusibi.site/post/python-design-pattern-state/</link><pubDate>Mon, 31 Dec 2018 12:59:39 +0800</pubDate><guid>https://blog.gusibi.site/post/python-design-pattern-state/</guid><description>python 状态模式</description></item><item><title>python设计模式-模板方法模式</title><link>https://blog.gusibi.site/post/python-design-pattern-template-pattern/</link><pubDate>Sun, 02 Dec 2018 17:23:56 +0800</pubDate><guid>https://blog.gusibi.site/post/python-design-pattern-template-pattern/</guid><description>python 设计模式 模板方法模式</description></item><item><title>python设计模式-外观模式</title><link>https://blog.gusibi.site/post/python-design-pattern-facade-pattern/</link><pubDate>Sun, 25 Nov 2018 17:23:56 +0800</pubDate><guid>https://blog.gusibi.site/post/python-design-pattern-facade-pattern/</guid><description>python 设计模式 外观模式</description></item><item><title>python设计模式-适配器模式</title><link>https://blog.gusibi.site/post/python-design-pattern-adapter/</link><pubDate>Sat, 03 Nov 2018 21:23:56 +0800</pubDate><guid>https://blog.gusibi.site/post/python-design-pattern-adapter/</guid><description>python 设计模式，适配器模式</description></item><item><title>SQLAlchemy in 空列表问题分析</title><link>https://blog.gusibi.site/post/sqlalchemy_in_empty_list/</link><pubDate>Thu, 04 Oct 2018 21:36:53 +0800</pubDate><guid>https://blog.gusibi.site/post/sqlalchemy_in_empty_list/</guid><description>SQLAlchemy in 空列表问题</description></item><item><title>垃圾回收算法|引用计数法</title><link>https://blog.gusibi.site/post/gc-reference-counting/</link><pubDate>Sun, 12 Aug 2018 19:15:05 +0800</pubDate><guid>https://blog.gusibi.site/post/gc-reference-counting/</guid><description>垃圾回收算法|引用计数法</description></item><item><title>使用github+travis将Python包部署到Pypi</title><link>https://blog.gusibi.site/post/howto-deploy-python-package-on-pypi-with-github-and-travis./</link><pubDate>Mon, 23 Jul 2018 23:45:46 +0800</pubDate><guid>https://blog.gusibi.site/post/howto-deploy-python-package-on-pypi-with-github-and-travis./</guid><description>使用github+travis将Python包部署到Pypi</description></item><item><title>垃圾回收算法|GC标记-清除算法</title><link>https://blog.gusibi.site/post/gc-mark-sweep/</link><pubDate>Sat, 21 Jul 2018 11:15:05 +0800</pubDate><guid>https://blog.gusibi.site/post/gc-mark-sweep/</guid><description>垃圾回收算法|标记-清除算法</description></item><item><title>Python 生成便签图片</title><link>https://blog.gusibi.site/post/python-text-to-image/</link><pubDate>Sun, 08 Jul 2018 15:04:52 +0800</pubDate><guid>https://blog.gusibi.site/post/python-text-to-image/</guid><description>python 文字转图片</description></item><item><title>Python gRPC 入门</title><link>https://blog.gusibi.site/post/hello-grpc/</link><pubDate>Thu, 07 Jun 2018 23:49:17 +0800</pubDate><guid>https://blog.gusibi.site/post/hello-grpc/</guid><description>Python gRPC 入门</description></item><item><title>newrelic python agent 源码分析-1</title><link>https://blog.gusibi.site/post/newrelic-python-agent-source-code-1/</link><pubDate>Wed, 16 May 2018 20:17:13 +0800</pubDate><guid>https://blog.gusibi.site/post/newrelic-python-agent-source-code-1/</guid><description>newrelic python agent 源码分析</description></item><item><title>Golang 学习笔记-2：控制流</title><link>https://blog.gusibi.site/post/golang-learing-note-2/</link><pubDate>Tue, 17 Apr 2018 23:49:35 +0800</pubDate><guid>https://blog.gusibi.site/post/golang-learing-note-2/</guid><description>golang 学习笔记 控制流</description></item><item><title>AWS-Lambda 使用入门</title><link>https://blog.gusibi.site/post/aws-lambda-quickstart/</link><pubDate>Sat, 13 Jan 2018 17:23:49 +0800</pubDate><guid>https://blog.gusibi.site/post/aws-lambda-quickstart/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;场景：&lt;/code&gt;现在需要开发一个前后端分离的应用，后端采用 RESTful API 最为方便，但是如果这个后端服务会在一天中的某些时候有高并发的情况，使用什么样的架构最为简单呢？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;刚思考这个问题的时候我想到的解决方案可能有以下几种：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;使用CDN内容分发网络，减少主服务器的压力&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;使用LVS服务器负载均衡&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;使用缓存&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;硬件层 提高带宽，使用SSD 硬盘，使用更好的服务器&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;代码层，优化代码（使用性能更好的语言等&lt;/p&gt;
&lt;p&gt;​&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但以上的几个方法都需要关注服务器的存储和计算资源，以便随时调整以满足更高的性能，并且高并发的请求也是分时段的，配置了更高性能的服务器在访问量变低的时候也是资源浪费。&lt;/p&gt;
&lt;p&gt;这个时候可以使用 FaaS（Functions as a Service） 架构，跟传统架构不同在于，他们运行于无状态的容器中，可以由事件触发，短暂的，完全被第三方管理，功能上FaaS就是不需要关心后台服务器或者应用服务，只需关心自己的代码即可。其中AWS Lambda是目前最佳的FaaS实现之一。&lt;/p&gt;
&lt;h2 id="aws-lambda"&gt;AWS Lambda&lt;/h2&gt;
&lt;p&gt;AWS Lambda 是一项计算服务，使用时无需预配置或管理服务器即可运行代码。AWS Lambda 只在需要时执行代码并自动缩放。借助 AWS Lambda，几乎可以为任何类型的应用程序或后端服务运行代码，而且无需执行任何管理。现在 AWS Lambda 支持 Node.js、Java、C# 和 Python。&lt;/p&gt;
&lt;h3 id="使用场景"&gt;使用场景&lt;/h3&gt;
&lt;p&gt;Lambda 常见的应用场景有以下几种：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;将Lambda 作为事件源用于 AWS 服务（比如音频上传到 s3后，触发 Lambda 音频转码服务，转码音频文件&lt;/li&gt;
&lt;li&gt;通过 HTTPS (Amazon API Gateway) 实现的按需 Lambda 函数调用（配合 API Gateway创建简单的微服务&lt;/li&gt;
&lt;li&gt;按需 Lambda 函数调用（使用自定义应用程序构建您自己的事件源）&lt;/li&gt;
&lt;li&gt;计划的事件（比如每天晚上12点生成报表发送到指定邮箱&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下图是将Lambda 作为事件源用于 AWS 服务案例的一个执行流程图：&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="http://media.gusibi.mobi/oXCMUsm_ZNoPkU5g5aa0OcXvvBo9_-TAB3xqUFlB4ktJlzakD_E9IA-3gQu85_QO"&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;用户将对象上传到 S3 存储桶（对象创建事件）。&lt;/li&gt;
&lt;li&gt;Amazon S3 检测到对象创建事件。&lt;/li&gt;
&lt;li&gt;Amazon S3 调用在存储桶通知配置中指定的 Lambda 函数。&lt;/li&gt;
&lt;li&gt;AWS Lambda 通过代入您在创建 Lambda 函数时指定的执行角色来执行 Lambda 函数。&lt;/li&gt;
&lt;li&gt;Lambda 函数执行。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这篇文章主要介绍 将 Lambda 作为事件源用于 AWS 服务 和 配合 API Gateway 创建简单的微服务。&lt;/p&gt;</description></item><item><title>python设计模式-命令模式</title><link>https://blog.gusibi.site/post/python-design-pattern-command/</link><pubDate>Tue, 09 Jan 2018 23:16:56 +0800</pubDate><guid>https://blog.gusibi.site/post/python-design-pattern-command/</guid><description>python 设计模式，命令模式</description></item><item><title>Python 字典</title><link>https://blog.gusibi.site/post/python-data-structures-dict/</link><pubDate>Sun, 03 Dec 2017 23:05:27 +0800</pubDate><guid>https://blog.gusibi.site/post/python-data-structures-dict/</guid><description>字典方法，如何处理查不到的键，标准库中 dict 的变种，散列表的工作原理</description></item><item><title>python设计模式-单例模式</title><link>https://blog.gusibi.site/post/python-design-pattern-singleton/</link><pubDate>Sun, 26 Nov 2017 12:59:39 +0800</pubDate><guid>https://blog.gusibi.site/post/python-design-pattern-singleton/</guid><description>python 单例模式</description></item><item><title>python设计模式-建造者模式</title><link>https://blog.gusibi.site/post/python-design-pattern-builder/</link><pubDate>Sun, 12 Nov 2017 21:16:56 +0800</pubDate><guid>https://blog.gusibi.site/post/python-design-pattern-builder/</guid><description>python 设计模式，建造者模式</description></item><item><title>python设计模式-抽象工厂模式</title><link>https://blog.gusibi.site/post/python-design-pattern-abstract-factory/</link><pubDate>Sat, 28 Oct 2017 21:23:56 +0800</pubDate><guid>https://blog.gusibi.site/post/python-design-pattern-abstract-factory/</guid><description>python 设计模式，工厂方法模式，抽象工厂模式</description></item><item><title>python设计模式-工厂方法模式</title><link>https://blog.gusibi.site/post/python-design-pattern-factory-method/</link><pubDate>Sun, 15 Oct 2017 13:23:56 +0800</pubDate><guid>https://blog.gusibi.site/post/python-design-pattern-factory-method/</guid><description>python 设计模式，工厂方法模式，简单工厂模式</description></item><item><title>python设计模式-观察者模式</title><link>https://blog.gusibi.site/post/python-design-pattern-observer/</link><pubDate>Sun, 24 Sep 2017 22:29:39 +0800</pubDate><guid>https://blog.gusibi.site/post/python-design-pattern-observer/</guid><description>python 观察者模式</description></item><item><title>redis 学习笔记</title><link>https://blog.gusibi.site/post/redis-note/</link><pubDate>Sun, 17 Sep 2017 22:41:51 +0800</pubDate><guid>https://blog.gusibi.site/post/redis-note/</guid><description>redis 学习笔记</description></item><item><title>Python 元组和分片</title><link>https://blog.gusibi.site/post/python-data-structures-an-array-of-seq-2/</link><pubDate>Sun, 10 Sep 2017 14:05:27 +0800</pubDate><guid>https://blog.gusibi.site/post/python-data-structures-an-array-of-seq-2/</guid><description>元组，切片以及对序列的一系列操作</description></item><item><title>Python 列表推导及优先级队列的实现</title><link>https://blog.gusibi.site/post/python-data-structures-an-array-of-seq-1/</link><pubDate>Sun, 03 Sep 2017 14:05:27 +0800</pubDate><guid>https://blog.gusibi.site/post/python-data-structures-an-array-of-seq-1/</guid><description>列表、列表推导有关的话题，最后演示如何用列表实现一个优先级队列</description></item><item><title>小程序开发：上传图片到腾讯云</title><link>https://blog.gusibi.site/post/wxapp-dev-upload-image-to-tencentyun-cos/</link><pubDate>Sun, 27 Aug 2017 12:17:13 +0800</pubDate><guid>https://blog.gusibi.site/post/wxapp-dev-upload-image-to-tencentyun-cos/</guid><description>微信小程序上传图片到腾讯云</description></item><item><title>Python 装饰器使用指南</title><link>https://blog.gusibi.site/post/python-decorator/</link><pubDate>Tue, 15 Aug 2017 22:41:51 +0800</pubDate><guid>https://blog.gusibi.site/post/python-decorator/</guid><description>&lt;blockquote&gt;
&lt;p&gt;装饰器是可调用的对象，其参数是另一个函数（被装饰的函数）。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="装饰器基础知识"&gt;装饰器基础知识&lt;/h2&gt;
&lt;p&gt;首先看一下这段代码&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;deco&lt;/span&gt;(fn):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print &lt;span style="color:#e6db74"&gt;&amp;#34;I am &lt;/span&gt;&lt;span style="color:#e6db74"&gt;%s&lt;/span&gt;&lt;span style="color:#e6db74"&gt;!&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;%&lt;/span&gt; fn&lt;span style="color:#f92672"&gt;.&lt;/span&gt;__name__
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@deco&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;func&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;pass&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# output&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;I am func&lt;span style="color:#960050;background-color:#1e0010"&gt;!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 没有执行func 函数 但是 deco 被执行了&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;HUGOMORE42&lt;/p&gt;
&lt;p&gt;在用某个@decorator来修饰某个函数func时&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@decorator&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;func&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;pass&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;其解释器会解释成下面这样的语句：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;func = decorator(func)&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;其实就是把一个函数当参数传到另一个函数中，然后再回调，但是值得注意的是装饰器必须返回一个函数给func&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;装饰器的一大特性是，能把被装饰的函数替换成其他函数。第二大特性是，装饰器在加载模块时立即执行。&lt;/p&gt;
&lt;h3 id="装饰器何时执行"&gt;装饰器何时执行&lt;/h3&gt;
&lt;p&gt;装饰器的一个关键特性是，它们在被装饰的函数定义后立即运行。这通常在导入是（python 加载模块时）。&lt;/p&gt;
&lt;p&gt;看下下面的示例：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;registry &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [] &lt;span style="color:#75715e"&gt;# registry 保存被@register 装饰的函数的引用&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;register&lt;/span&gt;(func): &lt;span style="color:#75715e"&gt;# register 的参数是一个函数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;&amp;#39;running register(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;%s&lt;/span&gt;&lt;span style="color:#e6db74"&gt;)&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;%&lt;/span&gt; func) &lt;span style="color:#75715e"&gt;# 打印被装饰的函数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; registry&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append(func) &lt;span style="color:#75715e"&gt;# 把 func 存入 `registery`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; func &lt;span style="color:#75715e"&gt;# 返回 func：必须返回函数，这里返回的函数与通过参数传入的一样&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@register&lt;/span&gt; &lt;span style="color:#75715e"&gt;# `f1` 和 `f2`被 `@register` 装饰&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;f1&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;&amp;#39;running f1()&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@register&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;f2&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;&amp;#39;running f2()&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;f3&lt;/span&gt;(): &lt;span style="color:#75715e"&gt;# &amp;lt;7&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;&amp;#39;running f3()&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(): &lt;span style="color:#75715e"&gt;# main 打印 `registry`，然后调用 f1()、f2()和 f3()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;&amp;#39;running main()&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;&amp;#39;registry -&amp;gt;&amp;#39;&lt;/span&gt;, registry)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; f1()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; f2()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; f3()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; __name__&lt;span style="color:#f92672"&gt;==&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; main() &lt;span style="color:#75715e"&gt;# &amp;lt;9&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;运行代码结果如下：&lt;/p&gt;</description></item><item><title>自定义 Sanic Exception</title><link>https://blog.gusibi.site/post/sanic-custom-exception/</link><pubDate>Sat, 05 Aug 2017 10:23:35 +0800</pubDate><guid>https://blog.gusibi.site/post/sanic-custom-exception/</guid><description>自定义 sanic 异常处理</description></item><item><title>小程序开发：python sanic 实现小程序登录注册</title><link>https://blog.gusibi.site/post/wxapp-dev-how-to-login-and-register-by-python-sanic/</link><pubDate>Sun, 30 Jul 2017 12:17:13 +0800</pubDate><guid>https://blog.gusibi.site/post/wxapp-dev-how-to-login-and-register-by-python-sanic/</guid><description>python sanic 实现微信小程序登录注册</description></item><item><title>CSS入门指南-3：定位元素</title><link>https://blog.gusibi.site/post/css-learing-3-positioning-elements/</link><pubDate>Wed, 26 Jul 2017 22:21:49 +0800</pubDate><guid>https://blog.gusibi.site/post/css-learing-3-positioning-elements/</guid><description>&lt;blockquote&gt;
&lt;p&gt;这是《CSS设计指南》的读书笔记，用于加深学习效果。
前一篇&lt;a href="https://mp.weixin.qq.com/s?__biz=MzAwNjI5MjAzNw==&amp;amp;mid=2655752018&amp;amp;idx=1&amp;amp;sn=6915e4f11ba08fa196a64375224cd92e&amp;amp;chksm=80b0b878b7c7316e1a065ae991c534cc11ca5fe72b33690a98fb1c3f6f53f8c98c4c8744cd3a#rd"&gt;CSS入门指南-2：盒子模型、浮动和清除&lt;/a&gt;介绍了css盒子模型、浮动和清除，这一篇介绍 css元素的定位。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="定位position"&gt;定位（position）&lt;/h2&gt;
&lt;p&gt;CSS 布局的核心是 position 属性，对元素盒子应用这个属性，可以相对于它在常规文档流中的位置重新定位。
position 属性有4个值：&lt;code&gt;static&lt;/code&gt;、&lt;code&gt;relative&lt;/code&gt;、&lt;code&gt;absoulte&lt;/code&gt;、&lt;code&gt;fixed&lt;/code&gt;，默认值为 static。&lt;/p&gt;
&lt;p&gt;接下来我会用以下四个段落来逐个说明这些属性是什么意思。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;p&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;first&amp;#34;&lt;/span&gt;&amp;gt;First Paragraph&amp;lt;/&lt;span style="color:#f92672"&gt;p&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;p&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;Second&amp;#34;&lt;/span&gt;&amp;gt;Second Paragraph&amp;lt;/&lt;span style="color:#f92672"&gt;p&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;p&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;specialpara&amp;#34;&lt;/span&gt;&amp;gt;Third Paragraph&amp;lt;/&lt;span style="color:#f92672"&gt;p&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;p&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;fourth&amp;#34;&lt;/span&gt;&amp;gt;First Paragraph&amp;lt;/&lt;span style="color:#f92672"&gt;p&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="静态定位static"&gt;静态定位（static）&lt;/h3&gt;
&lt;p&gt;我们先看一下四个段落都采用静态定位的效果。&lt;/p&gt;
&lt;p&gt;&lt;img alt="四段都采用静态定位的图示" loading="lazy" src="http://media.gusibi.mobi/R_7xrRQEA1TEc4S1GJsxwpfz99rx6nvnb0KZNOc1m-D5P8bdMAq-mQsvZ85xxMSb"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;静态定位下，每个元素在处在常规文档流中，它们都是块级元素，所以会在页面中自上而下地堆叠。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="相对定位relative"&gt;相对定位（relative）&lt;/h3&gt;
&lt;p&gt;现在我把第三段的 position 属性设置为 relative。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;p&lt;/span&gt;#specialpara {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;position&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;relative&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;top&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;25&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;left&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;30&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;因为相对定位&lt;code&gt;相对的是它原来在文档流中的位置（默认位置）&lt;/code&gt;，所以如果只设置 position 样式不会有任何变化。这里我同时设置了 top 和 left 属性来改变它的位置。&lt;/p&gt;
&lt;p&gt;现在它的效果如图所示：&lt;/p&gt;
&lt;p&gt;&lt;img alt="第三段使用相对定位的效果图" loading="lazy" src="http://media.gusibi.mobi/5OFF-2lXXl-JAY4tUuAl0V3Z5q6livJzUz11Fs7N8nIbz9mYgGp8GlzA6oM6_U9J"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;现在，第三段从原来的元素（body）中挣脱了出来，与它在文档中的默认位置相比向下移动了25像素，向右移动了30像素。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;需要注意的是，除了这个元素自己相对于原始位置挪动了一下以外，页面没有任何改变。这个元素原来占据的空间没有动，其他元素也没动。&lt;/p&gt;
&lt;p&gt;这时，如果不想第四段被它挡住，可以给第四段设置一个 margin-top 值。&lt;/p&gt;
&lt;h3 id="绝对定位absoulte"&gt;绝对定位（absoulte）&lt;/h3&gt;
&lt;p&gt;绝对定位跟静态定位和相对定位相比，它会把元素彻底从文档流中拿出来。&lt;/p&gt;
&lt;p&gt;我们把 position 改为绝对定位看一下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;p&lt;/span&gt;#specialpara {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;position&lt;/span&gt;: absoulte;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;top&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;25&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;left&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;30&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;效果如图：&lt;/p&gt;
&lt;p&gt;&lt;img alt="第三段使用绝对定位的效果图" loading="lazy" src="http://media.gusibi.mobi/2-U0Y3OwzCz9gOLmV-LF96-U1nnRhPUjvX6InOVjCfPo9vWCqwx0d_mQlmsFCkWL"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;可以看到，第三段原来的位置被回收了。这说明绝对定位的元素脱离了常规文档流，它现在是相对于顶级元素 body 在定位。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;现在就涉及到一个概念：&lt;code&gt;定位上下文&lt;/code&gt;，这个后边说，先继续看最后一种定位方式：&lt;code&gt;固定定位&lt;/code&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;盒子位移属性是如何工作？&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;盒子的位移属性有四个“top、right、bottom和left”，用来指定元素的定位位置和方向。这些属性只能在元素的“position”属性设置了“relative、absolute和fixed”属性值，才生效。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;对于相对定位元素，这些属性的设置让元素从默认位置移动。例如，top设置一个值“20px”在一个相对定位的元素上，这个元素会在原来位置向下移动“20px”。&lt;/p&gt;</description></item><item><title>理解JWT（JSON Web Token）认证及实践</title><link>https://blog.gusibi.site/post/how-to-use-json-web-token-and-python-practice/</link><pubDate>Sun, 23 Jul 2017 21:05:57 +0800</pubDate><guid>https://blog.gusibi.site/post/how-to-use-json-web-token-and-python-practice/</guid><description>description</description></item><item><title>CSS入门指南-2：盒子模型、浮动和清除</title><link>https://blog.gusibi.site/post/css-learing-2-box-model-float-and-clear/</link><pubDate>Wed, 19 Jul 2017 22:22:49 +0800</pubDate><guid>https://blog.gusibi.site/post/css-learing-2-box-model-float-and-clear/</guid><description>&lt;blockquote&gt;
&lt;p&gt;这是CSS设计指南的读书笔记，用于加深学习效果。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;上一篇介绍了css 的工作原理，这一篇主要介绍&lt;code&gt;盒子模型&lt;/code&gt;和&lt;code&gt;浮动&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id="盒子模型"&gt;盒子模型&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;所谓盒子模型，就是浏览器为页面中的每个HTML元素生成的矩形盒子。这些盒子们都要按照可见版式模型在页面上排布。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;HUGOMORE42&lt;/p&gt;
&lt;p&gt;可见的页面版式主要由三个属性控制：position、display和float。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;position：控制页面上元素的位置关系&lt;/li&gt;
&lt;li&gt;display：控制元素是堆叠、并排还是不在页面出现&lt;/li&gt;
&lt;li&gt;float：提供控制的方式，以便吧元素组成多栏布局&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;元素盒子的属性可以分成三组：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;边框(board)。可以甚至边框的宽窄、样式和颜色&lt;/li&gt;
&lt;li&gt;内边距(padding)。可以甚至盒子内容区与边框的间距&lt;/li&gt;
&lt;li&gt;外边距(margin)。可以设置盒子与相邻元素的间距&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="盒模型示意图展示了HTML元素的边框、内边距和外边距之间的关系" loading="lazy" src="http://omuo4kh1k.bkt.clouddn.com/4J2VDi7TIFFuSOVgWp-3uuDrzvYh7oMDxeNv5OxgpaQoUGlHPo8tL43fAa5iheKn"&gt;&lt;/p&gt;
&lt;p&gt;元素盒子还有一个背景层，可以改变颜色，也可以添加图片。&lt;/p&gt;
&lt;h3 id="简写样式"&gt;简写样式&lt;/h3&gt;
&lt;p&gt;CSS为边框、内边距和外边距分别规定了简写属性，每个简写声明中，属性值得顺序都是上、右、下、左。&lt;/p&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;margin-top&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;margin-right&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;margin-bottom&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;margin-left&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;使用简写则为这样：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;margin&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果有一个值没写，那么则使用对边的值。&lt;/p&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{&lt;span style="color:#66d9ef"&gt;margin&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/*等同于*/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;margin&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果只写一个值，则4个边都取这个值。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{&lt;span style="color:#66d9ef"&gt;margin&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/*等同于*/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{&lt;span style="color:#66d9ef"&gt;margin&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;另外每个盒子的属性也分三个粒度，这三个粒度从一般到特殊分别举例如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;border&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;dashed&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;red&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;混合使用三种粒度的简写属性达成设计目标是很常见的。比如，想为盒子的上边和下边添加4像素的红色边框，为左边添加1像素宽的红色边框，而右边没有。可以这么写：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{&lt;span style="color:#66d9ef"&gt;border&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;solid&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;red&lt;/span&gt;;} &lt;span style="color:#75715e"&gt;/* 先给4条边设置相同的样式*/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{&lt;span style="color:#66d9ef"&gt;border-left-width&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;} &lt;span style="color:#75715e"&gt;/* 修改左边框宽度*/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{border-fight: &lt;span style="color:#66d9ef"&gt;none&lt;/span&gt;;} &lt;span style="color:#75715e"&gt;/*移出右边框*/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="盒子边框"&gt;盒子边框&lt;/h3&gt;
&lt;p&gt;border 有三个相关属性。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;宽度（border-width)。可以使用thin、medium和thick等文本值，也可以使用除百分比和负值之外的任何绝对值。&lt;/li&gt;
&lt;li&gt;样式（border-style)。有none、hidden、dotted、dashed等文本值。&lt;/li&gt;
&lt;li&gt;颜色（border-color）。可以使用任意颜色值，包括RGB、HSL、十六进制颜色值和颜色关键字。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="盒子内边距"&gt;盒子内边距&lt;/h3&gt;
&lt;p&gt;内边距是盒子内容区与盒子边框之间的距离。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="http://omuo4kh1k.bkt.clouddn.com/sKiD0I3LeE7lTK8rARqH8TFpzVK9vh4QoAWCg_7Ll7m9V8VMkBNKY_YfvVUueia8"&gt;&lt;/p&gt;
&lt;p&gt;上图的样式为：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;p&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;font&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;16&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; helvetica, &lt;span style="color:#66d9ef"&gt;sans-serif&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;width&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;220&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;border&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;solid&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;red&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;background-color&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;#caebff&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;可以看到在没有设定内边距的情况下，内容紧挨着边框。&lt;/p&gt;
&lt;p&gt;设定边框后：&lt;/p&gt;</description></item><item><title>微信公号DIY：MongoDB 简易ORM &amp; 公号记账数据库设计</title><link>https://blog.gusibi.site/post/wechat-diy-keep-accounts-db-desgin/</link><pubDate>Sun, 16 Jul 2017 21:14:10 +0800</pubDate><guid>https://blog.gusibi.site/post/wechat-diy-keep-accounts-db-desgin/</guid><description>微信公号DIY python 实现 MongoDB 简易ORM &amp;amp; 公号记账应用数据库设计</description></item><item><title>使用swagger 生成 Flask RESTful API</title><link>https://blog.gusibi.site/post/build_restful_api_by_swagger/</link><pubDate>Tue, 11 Jul 2017 21:29:15 +0800</pubDate><guid>https://blog.gusibi.site/post/build_restful_api_by_swagger/</guid><description>使用swagger_py_codegen 生成 Flask, Tornado, Falcon，Sanic RESTful API</description></item><item><title>微信公号DIY：训练聊天机器人&amp;公号变身图片上传工具</title><link>https://blog.gusibi.site/post/wechat-chatbot-trainer-upload-image/</link><pubDate>Sat, 08 Jul 2017 23:34:53 +0800</pubDate><guid>https://blog.gusibi.site/post/wechat-chatbot-trainer-upload-image/</guid><description>训练聊天机器人&amp;amp;公号变身图片上传工具</description></item><item><title>微信公号DIY：一小时搭建微信聊天机器人</title><link>https://blog.gusibi.site/post/wechat-chatbot-step-by-step/</link><pubDate>Wed, 05 Jul 2017 23:47:13 +0800</pubDate><guid>https://blog.gusibi.site/post/wechat-chatbot-step-by-step/</guid><description>1小时搭建微信聊天机器人</description></item><item><title>python并发4：使用thread处理并发</title><link>https://blog.gusibi.site/post/python-thread-note/</link><pubDate>Sun, 02 Jul 2017 16:29:39 +0800</pubDate><guid>https://blog.gusibi.site/post/python-thread-note/</guid><description>python asyncio 介绍</description></item><item><title>python并发3：使用asyncio编写服务器</title><link>https://blog.gusibi.site/post/python-asyncio-server/</link><pubDate>Fri, 30 Jun 2017 16:29:39 +0800</pubDate><guid>https://blog.gusibi.site/post/python-asyncio-server/</guid><description>python asyncio 介绍</description></item><item><title>python web 框架 Sanci 快速入门</title><link>https://blog.gusibi.site/post/sanic-quickstart/</link><pubDate>Sun, 25 Jun 2017 12:47:34 +0800</pubDate><guid>https://blog.gusibi.site/post/sanic-quickstart/</guid><description>sanic 快速入门</description></item><item><title>python并发2：使用asyncio处理并发</title><link>https://blog.gusibi.site/post/python-asyncio/</link><pubDate>Fri, 23 Jun 2017 16:29:39 +0800</pubDate><guid>https://blog.gusibi.site/post/python-asyncio/</guid><description>python asyncio 介绍</description></item><item><title>python并发 1：使用 futures 处理并发</title><link>https://blog.gusibi.site/post/python-concurrency-with-futures/</link><pubDate>Sat, 17 Jun 2017 22:01:51 +0800</pubDate><guid>https://blog.gusibi.site/post/python-concurrency-with-futures/</guid><description>&lt;blockquote&gt;
&lt;p&gt;作为Python程序员，平时很少使用并发编程，偶尔使用也只需要派生出一批独立的线程，然后放到队列中，批量执行。所以，不夸张的说，虽然我知道线程、进程、并行、并发的概念，但每次使用的时候可能还需要再打开文档回顾一下。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;现在这一篇还是 &lt;em&gt;《流畅的python》读书笔记&lt;/em&gt;，译者在这里把future 翻译为“期物”，我觉得不太合适，既然future不能找到一个合适的词汇，暂时还是直接使用 future 吧。&lt;/p&gt;
&lt;h2 id="concurrentfutures"&gt;concurrent.futures&lt;/h2&gt;
&lt;p&gt;future 是一种对象，表示异步执行的操作。这个概念是 concurrent.futures模块和asyncio包的基础。&lt;/p&gt;
&lt;p&gt;concurrent.futures 模块是Python3.2 引入的，对于Python2x 版本，Python2.5 以上的版本可以安装 futures 包来使用这个模块。&lt;/p&gt;
&lt;p&gt;HUGOMORE42&lt;/p&gt;
&lt;p&gt;从Python3.4起，标准库中有两个为Future的类：concurrent.futures.Future 和 asyncio.Future。这两个类作用相同：两个Future类的实例都表示可能已经完成或未完成的延迟计算。&lt;/p&gt;
&lt;p&gt;Future 封装待完成的操作，可放入队列，完成的状态可以查询，得到结果（或抛出异常）后可以获取结果（或异常）。&lt;/p&gt;
&lt;p&gt;我们知道，如果程序中包含I/O操作，程序会有很高的延迟，CPU会处于等待状态，这时如果我们不使用并发会浪费很多时间。&lt;/p&gt;
&lt;h3 id="示例"&gt;示例&lt;/h3&gt;
&lt;p&gt;我们先举个例子：&lt;/p&gt;
&lt;p&gt;下边是有两段代码，主要功能都是从网上下载人口前20的国际的国旗：
第一段代码(flagss.py)是依序下载：下载完一个图片后保存到硬盘，然后请求下一张图片；
第二段代码(flagss_threadpool.py)使用 concurrent.futures 模块，批量下载10张图片。&lt;/p&gt;
&lt;p&gt;运行分别运行两段代码3次，结果如下：&lt;/p&gt;
&lt;p&gt;images.py 的结果如下&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ python flags.py
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;BD BR CD CN DE EG ET FR ID IN IR JP MX NG PH PK RU TR US VN
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;20&lt;/span&gt; flags downloaded in 6.18s
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ python flags.py
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;BD BR CD CN DE EG ET FR ID IN IR JP MX NG PH PK RU TR US VN
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;20&lt;/span&gt; flags downloaded in 5.67s
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ python flags.py
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;BD BR CD CN DE EG ET FR ID IN IR JP MX NG PH PK RU TR US VN
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;20&lt;/span&gt; flags downloaded in 6.55s
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;可以看到，依次下载10张图片，平均需要6秒&lt;/p&gt;</description></item><item><title>python协程3：用仿真实验学习协程</title><link>https://blog.gusibi.site/post/python-coroutine-discrete-event-simulation/</link><pubDate>Thu, 15 Jun 2017 19:22:49 +0800</pubDate><guid>https://blog.gusibi.site/post/python-coroutine-discrete-event-simulation/</guid><description>&lt;p&gt;前两篇我们已经介绍了&lt;a href="https://gusibi.github.io/post/python-coroutine-1-yield/"&gt;python 协程的使用&lt;/a&gt;和&lt;a href="https://gusibi.github.io/post/python-coroutine-yield-from/"&gt;yield from 的原理&lt;/a&gt;，这一篇，我们用一个例子来揭示如何使用协程在单线程中管理并发活动。&lt;/p&gt;
&lt;h2 id="什么是离散事件仿真"&gt;什么是离散事件仿真&lt;/h2&gt;
&lt;p&gt;Wiki上的定义是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;离散事件仿真将系统随时间的变化抽象成一系列的离散时间点上的事件，通过按照事件时间顺序处理事件来演进，是一种事件驱动的仿真世界观。离散事件仿真将系统的变化看做一个事件，因此系统任何的变化都只能是通过处理相应的事件来实现，在两个相邻的事件之间，系统状态维持前一个事件发生后的状态不变。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;人话说就是一种把系统建模成一系列事件的仿真系统。在离散事件仿真中，仿真“钟”向前推进的量不是固定的，而是直接推进到下一个事件模型的模拟时间。&lt;/p&gt;
&lt;p&gt;假设我们抽象模拟出租车的运营过程，其中一个事件是乘客上车，下一个事件则是乘客下车。不管乘客做了5分钟还是50分钟，一旦下车，仿真钟就会更新，指向此次运营的结束时间。&lt;/p&gt;
&lt;p&gt;事件？是不是想到了协程！&lt;/p&gt;
&lt;p&gt;协程恰好为实现离散事件仿真提供了合理的抽象。&lt;/p&gt;
&lt;p&gt;HUGOMORE42&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;第一门面向对象的语音 Simula 引入协程这个概念就是为了支持仿真。
Simpy 是一个实现离散事件仿真的Python包，通过一个协程表示离散事件仿真系统的各个进程。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="出租车对运营仿真"&gt;出租车对运营仿真&lt;/h2&gt;
&lt;p&gt;仿真程序会创建几辆出租车，每辆出租车会拉几个乘客，然后回家。出租车会首先驶离车库，四处徘徊，寻找乘客；拉到乘客后，行程开始；乘客下车后，继续四处徘徊。&lt;/p&gt;
&lt;p&gt;徘徊和行程所用的时间使用指数分布生成，我们将时间设为分钟数，以便显示清楚。&lt;/p&gt;
&lt;p&gt;完整代码如下：(taxi_sim.py)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#! -*- coding: utf-8 -*-&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; random
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; collections
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; queue
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; argparse
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;DEFAULT_NUMBER_OF_TAXIS &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;DEFAULT_END_TIME &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;180&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;SEARCH_DURATION &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;TRIP_DURATION &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;DEPARTURE_INTERAVAL &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# time 是事件发生的仿真时间，proc 是出租车进程实例的编号，action是描述活动的字符串&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Event &lt;span style="color:#f92672"&gt;=&lt;/span&gt; collections&lt;span style="color:#f92672"&gt;.&lt;/span&gt;namedtuple(&lt;span style="color:#e6db74"&gt;&amp;#39;Event&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;time proc action&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 开始 出租车进程&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 每辆出租车调用一次taxi_process 函数，创建一个生成器对象，表示各辆出租车的运营过程。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;taxi_process&lt;/span&gt;(ident, trips, start_time&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; 每次状态变化时向创建事件，把控制权交给仿真器
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param ident: 出租车编号
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param trips: 出租车回家前的行程数量
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param start_time: 离开车库的时间
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :return:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; time &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;yield&lt;/span&gt; Event(start_time, ident, &lt;span style="color:#e6db74"&gt;&amp;#39;leave garage&amp;#39;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;# 产出的第一个Event&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(trips): &lt;span style="color:#75715e"&gt;# 每次行程都会执行一遍这个代码块&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 产出一个Event实例，表示拉到了乘客 协程在这里暂停 等待下一次send() 激活&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; time &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;yield&lt;/span&gt; Event(time, ident, &lt;span style="color:#e6db74"&gt;&amp;#39;pick up passenger&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 产出一个Event实例，表示乘客下车 协程在这里暂停 等待下一次send() 激活&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; time &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;yield&lt;/span&gt; Event(time, ident, &lt;span style="color:#e6db74"&gt;&amp;#39;drop off passenger&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 指定的行程数量完成后，for 循环结束，最后产出 &amp;#39;going home&amp;#39; 事件。协程最后一次暂停&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;yield&lt;/span&gt; Event(time, ident, &lt;span style="color:#e6db74"&gt;&amp;#39;going home&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 协程执行到最后 抛出StopIteration 异常&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;compute_duration&lt;/span&gt;(previous_action):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&amp;#39;使用指数分布计算操作的耗时&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; previous_action &lt;span style="color:#f92672"&gt;in&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#39;leave garage&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;drop off passenger&amp;#39;&lt;/span&gt;]:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 新状态是四处徘徊&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; interval &lt;span style="color:#f92672"&gt;=&lt;/span&gt; SEARCH_DURATION
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;elif&lt;/span&gt; previous_action &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;pick up passenger&amp;#39;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 新状态是开始行程&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; interval &lt;span style="color:#f92672"&gt;=&lt;/span&gt; TRIP_DURATION
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;elif&lt;/span&gt; previous_action &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;going home&amp;#39;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; interval &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;raise&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ValueError&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;Unkonw previous_action: &lt;/span&gt;&lt;span style="color:#e6db74"&gt;%s&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;%&lt;/span&gt; previous_action)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; int(random&lt;span style="color:#f92672"&gt;.&lt;/span&gt;expovariate(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;interval)) &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 开始仿真&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Simulator&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;__init__&lt;/span&gt;(self, procs_map):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;events &lt;span style="color:#f92672"&gt;=&lt;/span&gt; queue&lt;span style="color:#f92672"&gt;.&lt;/span&gt;PriorityQueue() &lt;span style="color:#75715e"&gt;# 带优先级的队列 会按时间正向排序&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;procs &lt;span style="color:#f92672"&gt;=&lt;/span&gt; dict(procs_map) &lt;span style="color:#75715e"&gt;# 从获取的procs_map 参数中创建本地副本，为了不修改用户传入的值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;run&lt;/span&gt;(self, end_time):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; 调度并显示事件，直到时间结束
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param end_time: 结束时间 只需要指定一个参数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :return:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 调度各辆出租车的第一个事件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; iden, proc &lt;span style="color:#f92672"&gt;in&lt;/span&gt; sorted(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;procs&lt;span style="color:#f92672"&gt;.&lt;/span&gt;items()):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; first_event &lt;span style="color:#f92672"&gt;=&lt;/span&gt; next(proc) &lt;span style="color:#75715e"&gt;# 预激协程 并产出一个 Event 对象&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;events&lt;span style="color:#f92672"&gt;.&lt;/span&gt;put(first_event) &lt;span style="color:#75715e"&gt;# 把各个事件加到self.events 属性表示的 PriorityQueue对象中&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 此次仿真的主循环&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sim_time &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 把 sim_time 归0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; sim_time &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; end_time:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;events&lt;span style="color:#f92672"&gt;.&lt;/span&gt;empty(): &lt;span style="color:#75715e"&gt;# 事件全部完成后退出循环&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;&amp;#39;*** end of event ***&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;break&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; current_event &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;events&lt;span style="color:#f92672"&gt;.&lt;/span&gt;get() &lt;span style="color:#75715e"&gt;# 获取优先级最高(time 属性最小)的事件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sim_time, proc_id, previous_action &lt;span style="color:#f92672"&gt;=&lt;/span&gt; current_event &lt;span style="color:#75715e"&gt;# 更新 sim_time&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;&amp;#39;taxi:&amp;#39;&lt;/span&gt;, proc_id, proc_id &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39; &amp;#39;&lt;/span&gt;, current_event)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; active_proc &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;procs[proc_id] &lt;span style="color:#75715e"&gt;# 从self.procs 字典中获取表示当前活动的出租车协程&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; next_time &lt;span style="color:#f92672"&gt;=&lt;/span&gt; sim_time &lt;span style="color:#f92672"&gt;+&lt;/span&gt; compute_duration(previous_action)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; next_event &lt;span style="color:#f92672"&gt;=&lt;/span&gt; active_proc&lt;span style="color:#f92672"&gt;.&lt;/span&gt;send(next_time) &lt;span style="color:#75715e"&gt;# 把计算得到的时间发送给出租车协程。协程会产出下一个事件，或者抛出 StopIteration&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;except&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;StopIteration&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;del&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;procs[proc_id] &lt;span style="color:#75715e"&gt;# 如果有异常 表示已经退出， 删除这个协程&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;events&lt;span style="color:#f92672"&gt;.&lt;/span&gt;put(next_event) &lt;span style="color:#75715e"&gt;# 如果没有异常，把next_event 加入到队列&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;: &lt;span style="color:#75715e"&gt;# 如果超时 则走到这里&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; msg &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;*** end of simulation time: &lt;/span&gt;&lt;span style="color:#e6db74"&gt;{}&lt;/span&gt;&lt;span style="color:#e6db74"&gt; event pendding ***&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(msg&lt;span style="color:#f92672"&gt;.&lt;/span&gt;format(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;events&lt;span style="color:#f92672"&gt;.&lt;/span&gt;qsize()))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(end_time&lt;span style="color:#f92672"&gt;=&lt;/span&gt;DEFAULT_END_TIME, num_taxis&lt;span style="color:#f92672"&gt;=&lt;/span&gt;DEFAULT_NUMBER_OF_TAXIS,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; seed&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&amp;#39;初始化随机生成器，构建过程，运行仿真程序&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; seed &lt;span style="color:#f92672"&gt;is&lt;/span&gt; &lt;span style="color:#f92672"&gt;not&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; random&lt;span style="color:#f92672"&gt;.&lt;/span&gt;seed(seed) &lt;span style="color:#75715e"&gt;# 获取可复现的结果&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 构建taxis 字典。值是三个参数不同的生成器对象。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; taxis &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {i: taxi_process(i, (i &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;) &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, i&lt;span style="color:#f92672"&gt;*&lt;/span&gt;DEPARTURE_INTERAVAL)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(num_taxis)}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sim &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Simulator(taxis)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sim&lt;span style="color:#f92672"&gt;.&lt;/span&gt;run(end_time)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; __name__ &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; parser &lt;span style="color:#f92672"&gt;=&lt;/span&gt; argparse&lt;span style="color:#f92672"&gt;.&lt;/span&gt;ArgumentParser(description&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;Taxi fleet simulator.&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; parser&lt;span style="color:#f92672"&gt;.&lt;/span&gt;add_argument(&lt;span style="color:#e6db74"&gt;&amp;#39;-e&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;--end-time&amp;#39;&lt;/span&gt;, type&lt;span style="color:#f92672"&gt;=&lt;/span&gt;int,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; default&lt;span style="color:#f92672"&gt;=&lt;/span&gt;DEFAULT_END_TIME,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; help&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;simulation end time; default=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;%s&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;%&lt;/span&gt; DEFAULT_END_TIME)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; parser&lt;span style="color:#f92672"&gt;.&lt;/span&gt;add_argument(&lt;span style="color:#e6db74"&gt;&amp;#39;-t&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;--taxis&amp;#39;&lt;/span&gt;, type&lt;span style="color:#f92672"&gt;=&lt;/span&gt;int,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; default&lt;span style="color:#f92672"&gt;=&lt;/span&gt;DEFAULT_NUMBER_OF_TAXIS,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; help&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;number of taxis running; default = &lt;/span&gt;&lt;span style="color:#e6db74"&gt;%s&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;%&lt;/span&gt; DEFAULT_NUMBER_OF_TAXIS)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; parser&lt;span style="color:#f92672"&gt;.&lt;/span&gt;add_argument(&lt;span style="color:#e6db74"&gt;&amp;#39;-s&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;--seed&amp;#39;&lt;/span&gt;, type&lt;span style="color:#f92672"&gt;=&lt;/span&gt;int, default&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; help&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;random generator seed (for testing)&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; args &lt;span style="color:#f92672"&gt;=&lt;/span&gt; parser&lt;span style="color:#f92672"&gt;.&lt;/span&gt;parse_args()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; main(args&lt;span style="color:#f92672"&gt;.&lt;/span&gt;end_time, args&lt;span style="color:#f92672"&gt;.&lt;/span&gt;taxis, args&lt;span style="color:#f92672"&gt;.&lt;/span&gt;seed)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;运行程序，&lt;/p&gt;</description></item><item><title>python协程2：yield from 从入门到精通</title><link>https://blog.gusibi.site/post/python-coroutine-yield-from/</link><pubDate>Wed, 14 Jun 2017 17:22:49 +0800</pubDate><guid>https://blog.gusibi.site/post/python-coroutine-yield-from/</guid><description>&lt;p&gt;上一篇&lt;a href="https://mp.weixin.qq.com/s?__biz=MzAwNjI5MjAzNw==&amp;amp;mid=2655751983&amp;amp;idx=1&amp;amp;sn=e4c093c6e5d6e4e8281d76db7c67eb23"&gt;python协程1：yield的使用&lt;/a&gt;介绍了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;生成器作为协程使用时的行为和状态&lt;/li&gt;
&lt;li&gt;使用装饰器预激协程&lt;/li&gt;
&lt;li&gt;调用方如何使用生成器对象的 .throw(&amp;hellip;) 和 .close() 方法控制协程&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这一篇将介绍：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;协程终止时如何返回值&lt;/li&gt;
&lt;li&gt;yield新句法的用途和语义&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;HUGOMORE42&lt;/p&gt;
&lt;h2 id="让协程返回值"&gt;让协程返回值&lt;/h2&gt;
&lt;p&gt;先看一个例子：
这段代码会返回最终均值的结果，每次激活协程时不会产出移动平均值，而是最后一次返回。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#! -*- coding: utf-8 -*-&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;from&lt;/span&gt; collections &lt;span style="color:#f92672"&gt;import&lt;/span&gt; namedtuple
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Result &lt;span style="color:#f92672"&gt;=&lt;/span&gt; namedtuple(&lt;span style="color:#e6db74"&gt;&amp;#39;Result&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;count average&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;averager&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; total &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; count &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; average &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; term &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;yield&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; term &lt;span style="color:#f92672"&gt;is&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;break&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 为了返回值，协程必须正常终止；这里是退出条件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; total &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; term
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; count &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; average &lt;span style="color:#f92672"&gt;=&lt;/span&gt; total&lt;span style="color:#f92672"&gt;/&lt;/span&gt;count
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 返回一个namedtuple，包含count和average两个字段。在python3.3前，如果生成器返回值，会报错&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result(count, average)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我们调用这段代码，结果如下&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; coro_avg &lt;span style="color:#f92672"&gt;=&lt;/span&gt; averager()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; next(coro_avg)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; coro_avg&lt;span style="color:#f92672"&gt;.&lt;/span&gt;send(&lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;) &lt;span style="color:#75715e"&gt;# 并没有返回值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; coro_avg&lt;span style="color:#f92672"&gt;.&lt;/span&gt;send(&lt;span style="color:#ae81ff"&gt;30&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; coro_avg&lt;span style="color:#f92672"&gt;.&lt;/span&gt;send(&lt;span style="color:#ae81ff"&gt;40&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; coro_avg&lt;span style="color:#f92672"&gt;.&lt;/span&gt;send(&lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;) &lt;span style="color:#75715e"&gt;# 发送None终止循环，导致协程结束。生成器对象会抛出StopIteration异常。异常对象的value属性保存着返回值。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Traceback (most recent call last):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;StopIteration&lt;/span&gt;: Result(count&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;, average&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;30&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;return 表达式的值会传给调用方，&lt;em&gt;赋值给StopIteration&lt;/em&gt; 异常的一个属性。这样做虽然看着别扭，但为了保留生成器对象耗尽时抛出StopIteration异常的行为，也可以理解。&lt;/p&gt;</description></item><item><title>python协程1：协程 10分钟入门</title><link>https://blog.gusibi.site/post/python-coroutine-1-yield/</link><pubDate>Mon, 12 Jun 2017 17:22:49 +0800</pubDate><guid>https://blog.gusibi.site/post/python-coroutine-1-yield/</guid><description>&lt;blockquote&gt;
&lt;p&gt;最近找到一本python好书《流畅的python》，是到现在为止看到的对python高级特性讲述最详细的一本。
看了协程一章，做个读书笔记，加深印象。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="协程定义"&gt;协程定义&lt;/h2&gt;
&lt;p&gt;协程的底层架构是在pep342 中定义，并在python2.5 实现的。&lt;/p&gt;
&lt;p&gt;HUGOMORE42&lt;/p&gt;
&lt;p&gt;python2.5 中，yield关键字可以在表达式中使用，而且生成器API中增加了 .send(value)方法。生成器可以使用.send(&amp;hellip;)方法发送数据，发送的数据会成为生成器函数中yield表达式的值。&lt;/p&gt;
&lt;p&gt;协程是指一个过程，这个过程与调用方协作，产出有调用方提供的值。因此，生成器可以作为协程使用。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;除了 .send(&amp;hellip;)方法，pep342 和添加了 .throw(&amp;hellip;)（让调用方抛出异常，在生成器中处理）和.close()（终止生成器）方法。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;python3.3后，pep380对生成器函数做了两处改动：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;生成器可以返回一个值；以前，如果生成器中给return语句提供值，会抛出SyntaxError异常。&lt;/li&gt;
&lt;li&gt;引入yield from 语法，使用它可以把复杂的生成器重构成小型的嵌套生成器，省去之前把生成器的工作委托给子生成器所需的大量模板代码。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="协程生成器的基本行为"&gt;协程生成器的基本行为&lt;/h2&gt;
&lt;p&gt;首先说明一下，协程有四个状态，可以使用inspect.getgeneratorstate(&amp;hellip;)函数确定：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GEN_CREATED # 等待开始执行&lt;/li&gt;
&lt;li&gt;GEN_RUNNING # 解释器正在执行（只有在多线程应用中才能看到这个状态）&lt;/li&gt;
&lt;li&gt;GEN_SUSPENDED # 在yield表达式处暂停&lt;/li&gt;
&lt;li&gt;GEN_CLOSED # 执行结束&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#! -*- coding: utf-8 -*-&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; inspect
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 协程使用生成器函数定义：定义体中有yield关键字。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;simple_coroutine&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;&amp;#39;-&amp;gt; coroutine started&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# yield 在表达式中使用；如果协程只需要从客户那里接收数据，yield关键字右边不需要加表达式（yield默认返回None）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;yield&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;&amp;#39;-&amp;gt; coroutine received:&amp;#39;&lt;/span&gt;, x)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;my_coro &lt;span style="color:#f92672"&gt;=&lt;/span&gt; simple_coroutine()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;my_coro &lt;span style="color:#75715e"&gt;# 和创建生成器的方式一样，调用函数得到生成器对象。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 协程处于 GEN_CREATED (等待开始状态)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;print(inspect&lt;span style="color:#f92672"&gt;.&lt;/span&gt;getgeneratorstate(my_coro))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;my_coro&lt;span style="color:#f92672"&gt;.&lt;/span&gt;send(&lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 首先要调用next()函数，因为生成器还没有启动，没有在yield语句处暂停，所以开始无法发送数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 发送 None 可以达到相同的效果 my_coro.send(None) &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;next(my_coro)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 此时协程处于 GEN_SUSPENDED (在yield表达式处暂停)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;print(inspect&lt;span style="color:#f92672"&gt;.&lt;/span&gt;getgeneratorstate(my_coro))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 调用这个方法后，协程定义体中的yield表达式会计算出42；现在协程会恢复，一直运行到下一个yield表达式，或者终止。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;my_coro&lt;span style="color:#f92672"&gt;.&lt;/span&gt;send(&lt;span style="color:#ae81ff"&gt;42&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;print(inspect&lt;span style="color:#f92672"&gt;.&lt;/span&gt;getgeneratorstate(my_coro))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;运行上述代码，输出结果如下&lt;/p&gt;</description></item><item><title>CSS入门指南-1：工作原理</title><link>https://blog.gusibi.site/post/css-learing-1-css-how-it-works/</link><pubDate>Sat, 27 May 2017 17:22:49 +0800</pubDate><guid>https://blog.gusibi.site/post/css-learing-1-css-how-it-works/</guid><description>&lt;blockquote&gt;
&lt;p&gt;这是CSS设计指南的读书笔记，用于加深学习效果。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;最近想做一个小程序，前端是必修课，那就从css开始吧。&lt;/p&gt;
&lt;h2 id="css-工作原理"&gt;css 工作原理&lt;/h2&gt;
&lt;p&gt;每个html元素都有一组样式属性，可以通过css来设定。当html元素的同一个样式属性有多种样式值的时候，css就要靠层叠机智来决定最终应用哪种样式。&lt;/p&gt;
&lt;p&gt;HUGOMORE42&lt;/p&gt;
&lt;h3 id="css规则"&gt;css规则&lt;/h3&gt;
&lt;p&gt;规则实际上是一条完整的css指令，规则声明了要修改的元素和要应用给改元素的样式。&lt;/p&gt;
&lt;h4 id="为文档添加样式的三种方法"&gt;为文档添加样式的三种方法：&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;写在元素标签里（也叫行内样式，只能影响它所在的标签，会覆盖嵌入样式和链接样式）&lt;/li&gt;
&lt;li&gt;写在&amp;lt;style&amp;gt; 标签里（也就嵌入样式，应用范围仅限于当前页面，页面样式会覆盖外部样式表中的样式，但会被行内样式覆盖）&lt;/li&gt;
&lt;li&gt;写在单独css样式表中（也叫链接样式，样式表是一个扩展名为.css 的文件，可以在任意多个HTML页面链接同一个样式表文件。链接样式的作用范围是整个网站）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;除了这三种为页面添加样式的方法，还有一种在样式表中链接其他样式表的方法，使用@import 指令：例如&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;@import url(css/styles.css)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;@import 指令必须出现在样式表中其他样式之前，否则@吹灭；@import引用的样式表不会被加载。
&lt;img alt="css 规则命名惯例" loading="lazy" src="http://omuo4kh1k.bkt.clouddn.com/cpByY2yOl7gHv6vEFDL2CyMt8YJQ-0t0MRxo6itjABg0PeYrrqz6wrIV6q5kKsm8"&gt;&lt;/p&gt;
&lt;p&gt;对这个基本的结构有三种方法可以进行扩展&lt;/p&gt;
&lt;p&gt;**第一种方法：**多个声明包含在一条规则里。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;p&lt;/span&gt; {&lt;span style="color:#66d9ef"&gt;color&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;red&lt;/span&gt;; &lt;span style="color:#66d9ef"&gt;font-size&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;; &lt;span style="color:#66d9ef"&gt;font-weight&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;bold&lt;/span&gt;;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;**第二种方法：**多个选择器组合在一起。例如：如果想让&amp;lt;h1&amp;gt;、&amp;lt;h2&amp;gt;和&amp;lt;h3&amp;gt;的文本都变成蓝色粗体可以这么写：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;h1&lt;/span&gt; {&lt;span style="color:#66d9ef"&gt;color&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;blue&lt;/span&gt;; &lt;span style="color:#66d9ef"&gt;font-weight&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;bold&lt;/span&gt;;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;h2&lt;/span&gt; {&lt;span style="color:#66d9ef"&gt;color&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;blue&lt;/span&gt;; &lt;span style="color:#66d9ef"&gt;font-weight&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;bold&lt;/span&gt;;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;h3&lt;/span&gt; {&lt;span style="color:#66d9ef"&gt;color&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;blue&lt;/span&gt;; &lt;span style="color:#66d9ef"&gt;font-weight&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;bold&lt;/span&gt;;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;也可以这么写：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;h1&lt;/span&gt;&lt;span style="color:#f92672"&gt;,&lt;/span&gt; &lt;span style="color:#f92672"&gt;h2&lt;/span&gt;&lt;span style="color:#f92672"&gt;,&lt;/span&gt; &lt;span style="color:#f92672"&gt;h3&lt;/span&gt; {&lt;span style="color:#66d9ef"&gt;color&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;blue&lt;/span&gt;; &lt;span style="color:#66d9ef"&gt;font-weight&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;bold&lt;/span&gt;;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;分组选择符以逗号作为分隔符&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第三种方法：&lt;/strong&gt; 多条规则应用给一个选择符。
例如，写完上边的规则，还想把h3变成斜体，那么可以再为h3单独写一条规则：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;h1&lt;/span&gt;&lt;span style="color:#f92672"&gt;,&lt;/span&gt; &lt;span style="color:#f92672"&gt;h2&lt;/span&gt;&lt;span style="color:#f92672"&gt;,&lt;/span&gt; &lt;span style="color:#f92672"&gt;h3&lt;/span&gt; {&lt;span style="color:#66d9ef"&gt;color&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;blue&lt;/span&gt;; &lt;span style="color:#66d9ef"&gt;font-weight&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;bold&lt;/span&gt;;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;h3&lt;/span&gt; {&lt;span style="color:#66d9ef"&gt;font-style&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;italic&lt;/span&gt;;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="选择特定元素的选择符"&gt;选择特定元素的选择符&lt;/h3&gt;
&lt;p&gt;用于选择特定元素的操作符有三种&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;上下文选择符&lt;/strong&gt;。基于祖先或者同胞元素选择一个元素。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ID和类选择符&lt;/strong&gt;。基于id和class属性的值选择元素。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;属性选择符&lt;/strong&gt;。基于属性的有无和特征选择元素。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id="上下文选择符"&gt;上下文选择符&lt;/h4&gt;
&lt;p&gt;比如我们想给article中的段落设置不同的字号，可以使用上下文选择符来解决。&lt;/p&gt;
&lt;p&gt;上下文选择符的格式如下：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;标签1 标签2 {声明}&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;其中&lt;strong&gt;标签2&lt;/strong&gt; 是我们要选择的目标，而且只有在 &lt;strong&gt;标签1&lt;/strong&gt;是其祖先元素的情况下才会被选中。&lt;/p&gt;
&lt;p&gt;上下文选择符，叫后代组合式选择符，就是一组以空格分隔的标签名。用于选择作为特定祖先元素后代的标签。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;article&lt;/span&gt; &lt;span style="color:#f92672"&gt;p&lt;/span&gt; {&lt;span style="color:#66d9ef"&gt;font-weight&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;bold&lt;/span&gt;;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上边例子中，只有article后代的p元素才会应用后边的样式。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;上下文选择符以空格作为分隔符&lt;/strong&gt;&lt;/p&gt;
&lt;h5 id="特殊的上下文选择符"&gt;特殊的上下文选择符&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;子选择符 &amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;格式如下：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;标签1 &amp;gt; 标签2&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;标签1&lt;/strong&gt; 必须是 &lt;strong&gt;标签2&lt;/strong&gt; 的&lt;strong&gt;父元素&lt;/strong&gt;，不能是其它的祖先元素。&lt;/p&gt;</description></item><item><title>Elasticsearch 安装和使用</title><link>https://blog.gusibi.site/post/elasticsearch-install-and-setting/</link><pubDate>Thu, 18 May 2017 14:22:49 +0800</pubDate><guid>https://blog.gusibi.site/post/elasticsearch-install-and-setting/</guid><description>&lt;p&gt;安装使用 Elasticsearch 两种方法：&lt;/p&gt;
&lt;h3 id="方法1-手动安装-elasticsearch"&gt;方法1 手动安装 Elasticsearch&lt;/h3&gt;
&lt;h5 id="安装到ubuntu"&gt;安装到ubuntu&lt;/h5&gt;
&lt;p&gt;Elasticsearch与Logstash需要Java作为运行环境&lt;/p&gt;
&lt;h2 id="安装java-8"&gt;安装Java 8&lt;/h2&gt;
&lt;p&gt;将甲骨文Java PPA添加至apt：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo add-apt-repository -y ppa:webupd8team/java
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;更新apt软件包数据库：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;HUGOMORE42&lt;/p&gt;
&lt;p&gt;安装甲骨文Java 8的最新稳定版本，命令如下（在弹出的许可协议中点击接受）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt-get -y install oracle-java8-installer
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="安装elasticsearch"&gt;安装Elasticsearch&lt;/h2&gt;
&lt;h3 id="方法1-通过添加elastic的软件包源列表利用软件包管理器安装elasticsearch"&gt;方法1 通过添加Elastic的软件包源列表利用软件包管理器安装Elasticsearch。&lt;/h3&gt;
&lt;p&gt;运行以下命令以将Elasticsearch公共GPG密钥导入apt：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;wget -qO - https://packages.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;接下来，创建Elasticsearch源列表：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;echo &lt;span style="color:#e6db74"&gt;&amp;#34;deb http://packages.elastic.co/elasticsearch/&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;ELASTICSEARCH_VERSION&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/debian stable main&amp;#34;&lt;/span&gt; | sudo tee -a /etc/apt/sources.list.d/elk.list
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;更新apt软件包数据库：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;安装Elasticsearch&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt-get -y install elasticsearch
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Elasticsearch已经安装完成。下面编辑其配置文件：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo vi /etc/elasticsearch/elasticsearch.yml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;限制来自外部的Elasticsearch实例访问活动（端口9200），找到指定network.host的一行，取消其注释并将其值替换为“localhost”：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;elasticsearch.yml excerpt &lt;span style="color:#f92672"&gt;(&lt;/span&gt;updated&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;network.host: localhost
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;启动elasticsearch&lt;/p&gt;</description></item><item><title>Amazon DynamoDB 入门8：删除项目</title><link>https://blog.gusibi.site/post/amazon-dynamodb-delete-item/</link><pubDate>Fri, 03 Mar 2017 17:19:05 +0800</pubDate><guid>https://blog.gusibi.site/post/amazon-dynamodb-delete-item/</guid><description>&lt;blockquote&gt;
&lt;p&gt;上一篇介绍了DynamoDB 的更新，这一篇将会介绍项目删除操作和dynamoab-py&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="从表中删除数据"&gt;从表中删除数据&lt;/h2&gt;
&lt;p&gt;在 SQL 中，DELETE 语句从表中删除一个或多个行。&lt;em&gt;DynamoDB 使用 DeleteItem 操作一次删除一个项目。&lt;/em&gt;&lt;/p&gt;
&lt;h3 id="sql"&gt;SQL&lt;/h3&gt;
&lt;p&gt;在 SQL 中，可使用 DELETE 语句删除一个或多个行。WHERE 子句确定要修改的行。示例如下：&lt;/p&gt;
&lt;p&gt;HUGOMORE42&lt;/p&gt;
&lt;p&gt;DELETE FROM Music
WHERE Artist = &amp;lsquo;The Acme Band&amp;rsquo; AND SongTitle = &amp;lsquo;Look Out, World&amp;rsquo;;
我们可以修改 WHERE 子句以删除多个行。例如，删除某个特殊艺术家的所有歌曲，如下所示：&lt;/p&gt;
&lt;p&gt;DELETE FROM Music WHERE Artist = &amp;lsquo;The Acme Band&amp;rsquo;&lt;/p&gt;
&lt;h4 id="note"&gt;Note&lt;/h4&gt;
&lt;p&gt;如果省略 WHERE 子句，则数据库会尝试从表中删除所有行。&lt;/p&gt;
&lt;h3 id="dynamodb"&gt;DynamoDB&lt;/h3&gt;
&lt;p&gt;在 DynamoDB 中，可使用 DeleteItem 操作修改单个项目。&lt;/p&gt;
&lt;p&gt;(&lt;a href="http://docs.aws.amazon.com/zh_cn/amazondynamodb/latest/APIReference/API_DeleteItem.html?shortFooter=true%29[API"&gt;http://docs.aws.amazon.com/zh_cn/amazondynamodb/latest/APIReference/API_DeleteItem.html?shortFooter=true)[API&lt;/a&gt; 语法如下]：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;ConditionExpression&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;ExpressionAttributeNames&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; : &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;ExpressionAttributeValues&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; : {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;B&amp;#34;&lt;/span&gt;: &lt;span style="color:#960050;background-color:#1e0010"&gt;blob&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;BOOL&amp;#34;&lt;/span&gt;: &lt;span style="color:#960050;background-color:#1e0010"&gt;boolean&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;BS&amp;#34;&lt;/span&gt;: [ &lt;span style="color:#960050;background-color:#1e0010"&gt;blob&lt;/span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;L&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;AttributeValue&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;M&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; : &lt;span style="color:#e6db74"&gt;&amp;#34;AttributeValue&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;N&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;NS&amp;#34;&lt;/span&gt;: [ &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;NULL&amp;#34;&lt;/span&gt;: &lt;span style="color:#960050;background-color:#1e0010"&gt;boolean&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;S&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;SS&amp;#34;&lt;/span&gt;: [ &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;Key&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; : {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;B&amp;#34;&lt;/span&gt;: &lt;span style="color:#960050;background-color:#1e0010"&gt;blob&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;BOOL&amp;#34;&lt;/span&gt;: &lt;span style="color:#960050;background-color:#1e0010"&gt;boolean&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;BS&amp;#34;&lt;/span&gt;: [ &lt;span style="color:#960050;background-color:#1e0010"&gt;blob&lt;/span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;L&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;AttributeValue&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;M&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; : &lt;span style="color:#e6db74"&gt;&amp;#34;AttributeValue&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;N&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;NS&amp;#34;&lt;/span&gt;: [ &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;NULL&amp;#34;&lt;/span&gt;: &lt;span style="color:#960050;background-color:#1e0010"&gt;boolean&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;S&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;SS&amp;#34;&lt;/span&gt;: [ &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;ReturnConsumedCapacity&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;ReturnItemCollectionMetrics&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;ReturnValues&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;TableName&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;参数说明：&lt;/p&gt;</description></item><item><title>Amazon DynamoDB 入门7：项目更新</title><link>https://blog.gusibi.site/post/amazon-dynamodb-updateitem/</link><pubDate>Tue, 07 Feb 2017 22:23:33 +0800</pubDate><guid>https://blog.gusibi.site/post/amazon-dynamodb-updateitem/</guid><description>&lt;blockquote&gt;
&lt;p&gt;上一节介绍了DynamoDB 的查询，本来计划这一节介绍使用索引的查询，不过随机看到了更新操作，就先写更新操作吧&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="update-修改表中的数据"&gt;update (修改表中的数据)&lt;/h2&gt;
&lt;p&gt;SQL 语言提供用于修改数据的 UPDATE 语句。DynamoDB 使用 UpdateItem 操作完成类似的任务。&lt;/p&gt;
&lt;h3 id="sql"&gt;SQL&lt;/h3&gt;
&lt;p&gt;在 SQL 中，可使用 UPDATE 语句修改一个或多个行。SET 子句为一个或多个列指定新值，WHERE 子句确定修改的行。示例如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;UPDATE&lt;/span&gt; Music
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;SET&lt;/span&gt; RecordLabel &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Global Records&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; Artist &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;No One You Know&amp;#39;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;AND&lt;/span&gt; SongTitle &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Call Me Today&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;HUGOMORE42&lt;/p&gt;
&lt;p&gt;如果任何行均不匹配 WHERE 子句，则 UPDATE 语句不起作用。&lt;/p&gt;
&lt;h3 id="dynamodb"&gt;DynamoDB&lt;/h3&gt;
&lt;p&gt;在 DynamoDB 中，可使用 UpdateItem 操作修改单个项目。&lt;/p&gt;
&lt;p&gt;API 语法如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;AttributeUpdates&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; : {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;Action&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;B&amp;#34;&lt;/span&gt;: &lt;span style="color:#960050;background-color:#1e0010"&gt;blob&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;BOOL&amp;#34;&lt;/span&gt;: &lt;span style="color:#960050;background-color:#1e0010"&gt;boolean&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;BS&amp;#34;&lt;/span&gt;: [ &lt;span style="color:#960050;background-color:#1e0010"&gt;blob&lt;/span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;L&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;AttributeValue&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;M&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; : &lt;span style="color:#e6db74"&gt;&amp;#34;AttributeValue&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;N&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;NS&amp;#34;&lt;/span&gt;: [ &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;NULL&amp;#34;&lt;/span&gt;: &lt;span style="color:#960050;background-color:#1e0010"&gt;boolean&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;S&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;SS&amp;#34;&lt;/span&gt;: [ &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;ConditionalOperator&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;ConditionExpression&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;Expected&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; : {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;AttributeValueList&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;B&amp;#34;&lt;/span&gt;: &lt;span style="color:#960050;background-color:#1e0010"&gt;blob&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;BOOL&amp;#34;&lt;/span&gt;: &lt;span style="color:#960050;background-color:#1e0010"&gt;boolean&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;BS&amp;#34;&lt;/span&gt;: [ &lt;span style="color:#960050;background-color:#1e0010"&gt;blob&lt;/span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;L&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;AttributeValue&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;M&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; : &lt;span style="color:#e6db74"&gt;&amp;#34;AttributeValue&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;N&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;NS&amp;#34;&lt;/span&gt;: [ &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;NULL&amp;#34;&lt;/span&gt;: &lt;span style="color:#960050;background-color:#1e0010"&gt;boolean&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;S&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;SS&amp;#34;&lt;/span&gt;: [ &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;ComparisonOperator&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;Exists&amp;#34;&lt;/span&gt;: &lt;span style="color:#960050;background-color:#1e0010"&gt;boolean&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;B&amp;#34;&lt;/span&gt;: &lt;span style="color:#960050;background-color:#1e0010"&gt;blob&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;BOOL&amp;#34;&lt;/span&gt;: &lt;span style="color:#960050;background-color:#1e0010"&gt;boolean&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;BS&amp;#34;&lt;/span&gt;: [ &lt;span style="color:#960050;background-color:#1e0010"&gt;blob&lt;/span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;L&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;AttributeValue&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;M&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; : &lt;span style="color:#e6db74"&gt;&amp;#34;AttributeValue&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;N&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;NS&amp;#34;&lt;/span&gt;: [ &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;NULL&amp;#34;&lt;/span&gt;: &lt;span style="color:#960050;background-color:#1e0010"&gt;boolean&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;S&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;SS&amp;#34;&lt;/span&gt;: [ &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;ExpressionAttributeNames&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; : &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;ExpressionAttributeValues&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; : {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;B&amp;#34;&lt;/span&gt;: &lt;span style="color:#960050;background-color:#1e0010"&gt;blob&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;BOOL&amp;#34;&lt;/span&gt;: &lt;span style="color:#960050;background-color:#1e0010"&gt;boolean&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;BS&amp;#34;&lt;/span&gt;: [ &lt;span style="color:#960050;background-color:#1e0010"&gt;blob&lt;/span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;L&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;AttributeValue&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;M&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; : &lt;span style="color:#e6db74"&gt;&amp;#34;AttributeValue&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;N&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;NS&amp;#34;&lt;/span&gt;: [ &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;NULL&amp;#34;&lt;/span&gt;: &lt;span style="color:#960050;background-color:#1e0010"&gt;boolean&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;S&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;SS&amp;#34;&lt;/span&gt;: [ &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;Key&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; : {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;B&amp;#34;&lt;/span&gt;: &lt;span style="color:#960050;background-color:#1e0010"&gt;blob&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;BOOL&amp;#34;&lt;/span&gt;: &lt;span style="color:#960050;background-color:#1e0010"&gt;boolean&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;BS&amp;#34;&lt;/span&gt;: [ &lt;span style="color:#960050;background-color:#1e0010"&gt;blob&lt;/span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;L&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;AttributeValue&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;M&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; : &lt;span style="color:#e6db74"&gt;&amp;#34;AttributeValue&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;N&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;NS&amp;#34;&lt;/span&gt;: [ &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;NULL&amp;#34;&lt;/span&gt;: &lt;span style="color:#960050;background-color:#1e0010"&gt;boolean&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;S&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;SS&amp;#34;&lt;/span&gt;: [ &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;ReturnConsumedCapacity&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;ReturnItemCollectionMetrics&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;ReturnValues&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;TableName&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;UpdateExpression&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;参数说明：&lt;/p&gt;</description></item><item><title>Amazon DynamoDB 入门6：query 和 scan</title><link>https://blog.gusibi.site/post/amazon-dynamodb-query-and-scan/</link><pubDate>Tue, 31 Jan 2017 17:46:28 +0800</pubDate><guid>https://blog.gusibi.site/post/amazon-dynamodb-query-and-scan/</guid><description>&lt;blockquote&gt;
&lt;p&gt;上一节我们介绍了DynamoDB索引的创建及管理，这一节我们将介绍query（查询）和scan（扫描）的使用。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="查询query"&gt;查询Query&lt;/h1&gt;
&lt;p&gt;SQL 可使用 SELECT 语句查询关键列、非关键列或任意组合。WHERE 子句确定返回的行。&lt;/p&gt;
&lt;p&gt;DynamoDB Query 操作提供对存储数据的物理位置的快速高效访问。 可以将 Query 用于任何具有复合主键（分区键和排序键）的表。这里的表必须指定分区键的相等条件，并且可以选择性为排序键提供另一个条件。 KeyConditionExpression 参数指定要查询的键值。&lt;/p&gt;
&lt;p&gt;HUGOMORE42&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;可使用可选 FilterExpression 在结果中的找出某些符号条件的项目。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在 DynamoDB 中，必须使用 ExpressionAttributeValues 作为表达式参数（例如，KeyConditionExpression和 FilterExpression）中的占位符。这类似于在关系数据库中使用绑定变量，在运行时将实际值代入 SELECT语句。 下边是query的语法：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;response &lt;span style="color:#f92672"&gt;=&lt;/span&gt; table&lt;span style="color:#f92672"&gt;.&lt;/span&gt;query(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; IndexName&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;string&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Select&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;ALL_ATTRIBUTES&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;|&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;ALL_PROJECTED_ATTRIBUTES&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;|&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;SPECIFIC_ATTRIBUTES&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;|&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;COUNT&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; AttributesToGet&lt;span style="color:#f92672"&gt;=&lt;/span&gt;[
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;string&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Limit&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;123&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ConsistentRead&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;&lt;span style="color:#f92672"&gt;|&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;False&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ConditionalOperator&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;AND&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;|&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;OR&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ScanIndexForward&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;&lt;span style="color:#f92672"&gt;|&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;False&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ExclusiveStartKey&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;string&amp;#39;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#39;string&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;|&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;123&lt;/span&gt;&lt;span style="color:#f92672"&gt;|&lt;/span&gt;Binary(&lt;span style="color:#e6db74"&gt;b&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;bytes&amp;#39;&lt;/span&gt;)&lt;span style="color:#f92672"&gt;|&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;&lt;span style="color:#f92672"&gt;|&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;&lt;span style="color:#f92672"&gt;|&lt;/span&gt;set([&lt;span style="color:#e6db74"&gt;&amp;#39;string&amp;#39;&lt;/span&gt;])&lt;span style="color:#f92672"&gt;|&lt;/span&gt;set([&lt;span style="color:#ae81ff"&gt;123&lt;/span&gt;])&lt;span style="color:#f92672"&gt;|&lt;/span&gt;set([Binary(&lt;span style="color:#e6db74"&gt;b&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;bytes&amp;#39;&lt;/span&gt;)])&lt;span style="color:#f92672"&gt;|&lt;/span&gt;[]&lt;span style="color:#f92672"&gt;|&lt;/span&gt;{}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ReturnConsumedCapacity&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;INDEXES&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;|&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;TOTAL&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;|&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;NONE&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ProjectionExpression&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;string&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; FilterExpression&lt;span style="color:#f92672"&gt;=&lt;/span&gt;Attr(&lt;span style="color:#e6db74"&gt;&amp;#39;myattribute&amp;#39;&lt;/span&gt;)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;eq(&lt;span style="color:#e6db74"&gt;&amp;#39;myvalue&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; KeyConditionExpression&lt;span style="color:#f92672"&gt;=&lt;/span&gt;Key(&lt;span style="color:#e6db74"&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;eq(&lt;span style="color:#e6db74"&gt;&amp;#39;myvalue&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ExpressionAttributeNames&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;string&amp;#39;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#39;string&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ExpressionAttributeValues&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;string&amp;#39;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#39;string&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;|&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;123&lt;/span&gt;&lt;span style="color:#f92672"&gt;|&lt;/span&gt;Binary(&lt;span style="color:#e6db74"&gt;b&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;bytes&amp;#39;&lt;/span&gt;)&lt;span style="color:#f92672"&gt;|&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;&lt;span style="color:#f92672"&gt;|&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;&lt;span style="color:#f92672"&gt;|&lt;/span&gt;set([&lt;span style="color:#e6db74"&gt;&amp;#39;string&amp;#39;&lt;/span&gt;])&lt;span style="color:#f92672"&gt;|&lt;/span&gt;set([&lt;span style="color:#ae81ff"&gt;123&lt;/span&gt;])&lt;span style="color:#f92672"&gt;|&lt;/span&gt;set([Binary(&lt;span style="color:#e6db74"&gt;b&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;bytes&amp;#39;&lt;/span&gt;)])&lt;span style="color:#f92672"&gt;|&lt;/span&gt;[]&lt;span style="color:#f92672"&gt;|&lt;/span&gt;{}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;参数说明：&lt;/p&gt;</description></item><item><title>Amazon DynamoDB 入门5：索引创建及管理</title><link>https://blog.gusibi.site/post/amazon-dynamodb-indexes/</link><pubDate>Wed, 18 Jan 2017 21:55:39 +0800</pubDate><guid>https://blog.gusibi.site/post/amazon-dynamodb-indexes/</guid><description>&lt;blockquote&gt;
&lt;p&gt;上一节我们介绍了项目的添加、修改、获取、删除（CRUD）操作，这一节将介绍索引的创建及管理。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="创建索引"&gt;创建索引&lt;/h3&gt;
&lt;h4 id="sql"&gt;SQL&lt;/h4&gt;
&lt;p&gt;在关系数据库中，索引是一个数据结构，可对表中的不同的列执行快速查询。可以使用 CREATE INDEX SQL 语句将索引添加到现有表，并指定要建立索引的列。在创建索引后，可以照常查询表中的数据，但现在数据库可使用索引快速查找表中的指定行，而不是扫描整个表。&lt;/p&gt;
&lt;p&gt;在创建一个索引后，数据库将自动维护此索引。只要修改表中的数据，就会自动更改索引以反映表中的更改。&lt;/p&gt;
&lt;p&gt;HUGOMORE42&lt;/p&gt;
&lt;p&gt;在 MySQL 中，您可以创建如下所示的索引：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;CREATE INDEX GenreAndPriceIndex
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ON Music (genre, price);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="dynamodb"&gt;DynamoDB&lt;/h4&gt;
&lt;p&gt;在 DynamoDB 中，我们可以创建和使用secondary index来实现类似目的。&lt;/p&gt;
&lt;p&gt;DynamoDB 中的索引与其关系对应项不同。当我们创建secondary index时，必须指定其键属性 - 分区键和排序键。
在创建secondary index后，我们可以对它执行 Query 或 Scan 操作，就如同对表执行这些操作一样。
DynamoDB 没有查询优化程序，因此，仅在我们对secondary index执行 Query 或 Scan 操作时使用它。&lt;/p&gt;
&lt;p&gt;DynamoDB 支持两种不同的索引：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;全局二级索引 - 索引的主键可以是其表中的任意两个属性（&lt;strong&gt;可以在创建表时创建，也可以向现有表添加新全局二级索引，或者删除现有的全局二级索引&lt;/strong&gt;）。&lt;/li&gt;
&lt;li&gt;本地二级索引 - 索引的分区键必须与其表的分区键相同。不过，排序键可以是任何其他属性（&lt;strong&gt;是在创建表的同时创建的。不能向现有表添加本地二级索引，也不能删除已存在的任何本地二级索引&lt;/strong&gt;）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;DynamoDB 确保secondary index中的数据最终与其表保持一致。我们可以请求对表或local secondary index&lt;strong&gt;执行强一致性 Query 或 Scan 操作&lt;/strong&gt;。但是，&lt;strong&gt;全局二级索引仅支持最终一致性&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;可使用 UpdateTable 操作并指定 GlobalSecondaryIndexUpdates 来将global secondary index添加到现有表：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TableName: &amp;#34;Music&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; AttributeDefinitions:[
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {AttributeName: &amp;#34;Genre&amp;#34;, AttributeType: &amp;#34;S&amp;#34;},
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {AttributeName: &amp;#34;Price&amp;#34;, AttributeType: &amp;#34;N&amp;#34;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; GlobalSecondaryIndexUpdates: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Create: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; IndexName: &amp;#34;GenreAndPriceIndex&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; KeySchema: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {AttributeName: &amp;#34;Genre&amp;#34;, KeyType: &amp;#34;HASH&amp;#34;}, //Partition key
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {AttributeName: &amp;#34;Price&amp;#34;, KeyType: &amp;#34;RANGE&amp;#34;}, //Sort key
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Projection: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;ProjectionType&amp;#34;: &amp;#34;ALL&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ProvisionedThroughput: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;ReadCapacityUnits&amp;#34;: 1,&amp;#34;WriteCapacityUnits&amp;#34;: 1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;添加索引时必须向 UpdateTable 提供以下参数：&lt;/p&gt;</description></item><item><title>Amazon DynamoDB 入门4：项目的基本操作（CRUD）</title><link>https://blog.gusibi.site/post/amazon-dynamodb-items-crud/</link><pubDate>Wed, 18 Jan 2017 21:53:38 +0800</pubDate><guid>https://blog.gusibi.site/post/amazon-dynamodb-items-crud/</guid><description>&lt;blockquote&gt;
&lt;p&gt;上一节我们介绍了DynamoDB 表的操作，这一节将介绍项目的添加 修改 获取 删除操作。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="创建项目"&gt;创建项目&lt;/h2&gt;
&lt;p&gt;Amazon DynamoDB 提供了 PutItem 和 BatchWriteItem 两种方式写入数据&lt;/p&gt;
&lt;h3 id="添加单个项目"&gt;添加单个项目&lt;/h3&gt;
&lt;p&gt;在 Amazon DynamoDB 中，使用 PutItem 操作向表添加项目：&lt;/p&gt;
&lt;p&gt;HUGOMORE42&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TableName: &amp;#34;Music&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Item: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;Artist&amp;#34;:&amp;#34;No One You Know&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;SongTitle&amp;#34;:&amp;#34;Call Me Today&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;AlbumTitle&amp;#34;:&amp;#34;Somewhat Famous&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;Year&amp;#34;: 2015,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;Price&amp;#34;: 2.14,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;Genre&amp;#34;: &amp;#34;Country&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;Tags&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;Composers&amp;#34;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;Smith&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;Jones&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;Davis&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;LengthInSeconds&amp;#34;: 214
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;此表的主键包含 Artist 和 SongTitle。您必须为这些属性指定值。
以下是要了解的有关此 PutItem 示例的几个关键事项：&lt;/p&gt;</description></item><item><title>Amazon DynamoDB 入门3： 表的基本操作</title><link>https://blog.gusibi.site/post/amazon-dynamodb-table-operator/</link><pubDate>Sat, 14 Jan 2017 18:13:42 +0800</pubDate><guid>https://blog.gusibi.site/post/amazon-dynamodb-table-operator/</guid><description>&lt;blockquote&gt;
&lt;p&gt;之前两篇文章介绍了DynamoDB如何在本地安装以及基本的工作原理和API，这一节主要介绍如何使用DynamoDB。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;基本的DynamoDB 操作包括表操作、项目操作和索引管理。&lt;/p&gt;
&lt;p&gt;首先是链接数据库。和关系型数据库不同，&lt;strong&gt;DynamoDB 是一项 Web 服务，与其进行的交互是无状态的。应用程序不需要维护持久性网络连接。相反，与 DynamoDB 的交互是通过 HTTP(S) 请求和响应进行的。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;HUGOMORE42&lt;/p&gt;
&lt;p&gt;执行某项操作的步骤为：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;应用程序将 HTTP(S) 请求发送到 DynamoDB。该请求包含要执行的 DynamoDB 操作的名称和参数。DynamoDB 将立即执行请求。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DynamoDB 返回一个包含操作结果的 HTTP(S) 响应。如果出错，DynamoDB 将返回 HTTP 错误状态和消息。&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;大多数情况下，我们编写应用程序代码访问DynamoDB。同时还可以使用 AWS 管理控制台或 AWS Command Line Interface (AWS CLI) 向 DynamoDB 发送临时请求并查看结果。&lt;/p&gt;
&lt;p&gt;剩下的就让我们用代码展示吧！&lt;/p&gt;
&lt;h2 id="表操作"&gt;表操作&lt;/h2&gt;
&lt;p&gt;我们知道，关系模型需要一个明确定义的架构，其中，数据将标准化为表、列和行。此外，在表、列、索引和其他数据库元素之间定义所有关系。但 DynamoDB 不同，&lt;strong&gt;DynamoDB 没有架构。每个表必须具有一个用来唯一标识每个数据项目的主键，但对其他非键属性没有类似的约束。DynamoDB 可以管理结构化或半结构化的数据，包括 JSON 文档。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;表是关系数据库和 DynamoDB 中的基本数据结构。关系数据库管理系统 (RDBMS) 要求在创建表时定义表的架构。相比之下，DynamoDB 表没有架构 - 与主键不同，我们在创建表时无需定义任何属性或数据类型。&lt;/p&gt;
&lt;h3 id="新建表"&gt;新建表&lt;/h3&gt;
&lt;p&gt;DynamoDB 使用 CreateTable 操作创建表，并指定参数，请求语法如下所示：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;AttributeDefinitions&amp;#34;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;AttributeName&amp;#34;: &amp;#34;string&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;AttributeType&amp;#34;: &amp;#34;string&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;GlobalSecondaryIndexes&amp;#34;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;IndexName&amp;#34;: &amp;#34;string&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;KeySchema&amp;#34;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;AttributeName&amp;#34;: &amp;#34;string&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;KeyType&amp;#34;: &amp;#34;string&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;Projection&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;NonKeyAttributes&amp;#34;: [ &amp;#34;string&amp;#34; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;ProjectionType&amp;#34;: &amp;#34;string&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;ProvisionedThroughput&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;ReadCapacityUnits&amp;#34;: number,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;WriteCapacityUnits&amp;#34;: number
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;KeySchema&amp;#34;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;AttributeName&amp;#34;: &amp;#34;string&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;KeyType&amp;#34;: &amp;#34;string&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;LocalSecondaryIndexes&amp;#34;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;IndexName&amp;#34;: &amp;#34;string&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;KeySchema&amp;#34;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;AttributeName&amp;#34;: &amp;#34;string&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;KeyType&amp;#34;: &amp;#34;string&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;Projection&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;NonKeyAttributes&amp;#34;: [ &amp;#34;string&amp;#34; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;ProjectionType&amp;#34;: &amp;#34;string&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;ProvisionedThroughput&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;ReadCapacityUnits&amp;#34;: number,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;WriteCapacityUnits&amp;#34;: number
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;StreamSpecification&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;StreamEnabled&amp;#34;: boolean,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;StreamViewType&amp;#34;: &amp;#34;string&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;TableName&amp;#34;: &amp;#34;string&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;必须向 CreateTable 提供以下参数：&lt;/p&gt;</description></item><item><title>Amazon DynamoDB 入门2： 工作原理、API和数据类型介绍</title><link>https://blog.gusibi.site/post/amazon-dynamodb0how-it-works/</link><pubDate>Mon, 09 Jan 2017 22:37:11 +0800</pubDate><guid>https://blog.gusibi.site/post/amazon-dynamodb0how-it-works/</guid><description>&lt;h3 id="本节主要介绍dynamodb-基本概念核心组件数据结构api"&gt;本节主要介绍DynamoDB 基本概念、核心组件、数据结构、Api&lt;/h3&gt;
&lt;p&gt;DynamoDB工作原理&lt;/p&gt;
&lt;h2 id="dynamodb-基本概念"&gt;DynamoDB 基本概念&lt;/h2&gt;
&lt;p&gt;DynamoDB 是 AWS 独有的完全托管的 NoSQL Database。它的思想来源于 Amazon 2007 年发表的一篇论文：Dynamo: Amazon’s Highly Available Key-value Store。在这篇论文里，Amazon 介绍了如何使用 Commodity Hardware 来打造高可用、高弹性的数据存储。想要理解 DynamoDB，首先要理解 Consistent Hashing。Consistent Hashing 的原理如下图所示：
&lt;img loading="lazy" src="http://note.youdao.com/yws/public/resource/b99dcbe9b4a2069a3337badbeafe4b29/xmlnote/WEBRESOURCEb477b81f1e511ee919b14f3393326749/470"&gt;&lt;/p&gt;
&lt;p&gt;HUGOMORE42&lt;/p&gt;
&lt;p&gt;它的概念是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;我有一个足够大的Keyspace（2的160次方，比较一下：IPv6是2的128次方），我们记作X。&lt;/li&gt;
&lt;li&gt;然后将X放在一个环形的空间里划分成大小相等的Y个 Partition，依次循环排列（如图），每个 Partition 由一个Vnode（Riak的概念）管理，&lt;/li&gt;
&lt;li&gt;当你有M个Database Server（Node），Y个Vnode再平均映射到M个Node上。&lt;/li&gt;
&lt;li&gt;当数据要插入时，将其主键（Hash Key）映射到K中的一个地址（Addr），对应到某个Vnode，再进一步对应到某个Node，如果这个数据需要N个Replica，则将数据写入Addr（Vnode a），Addr + 1（Vnode b）， …，Add + N（Vnode n）。&lt;/li&gt;
&lt;li&gt;这里，M就是你的Shards，N是Replica。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;以后添加新的Node时，映射发生变化，只需要把相应的变化了的Vnode迁移到新的Node上即可。在这种结构下，Sharding/Replica对程序员基本上是透明的。&lt;/p&gt;
&lt;h2 id="dynamodb-核心组件"&gt;DynamoDB 核心组件&lt;/h2&gt;
&lt;p&gt;基本 DynamoDB 组件包括：表、项目、属性&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;表 - 类似于其他数据库系统，DynamoDB将数据存储在表中。表是数据的集合。（类似于关系型数据库中的表）&lt;/li&gt;
&lt;li&gt;项目 - 每个表包含多个项目。项目是一组属性，具有不同于所有其他项目的唯一标识。（类似于其他数据库系统中的行、记录或元组。）&lt;/li&gt;
&lt;li&gt;属性 - 每个项目包含一个或多个属性。属性是基础的数据元素，无需进一步分解。（类似于其他数据库系统中的字段或列。）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下图是一个名为 People 的表，其中显示了一些示例项目和属性：&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" loading="lazy" src="http://note.youdao.com/yws/public/resource/b99dcbe9b4a2069a3337badbeafe4b29/xmlnote/WEBRESOURCEe0de7341429c0ba6408f2a3b1a60d214/100"&gt;&lt;/p&gt;
&lt;p&gt;请注意有关 People 表的以下内容：&lt;/p&gt;</description></item><item><title>Amazon DynamoDB 入门1：配置（本地）及python示例</title><link>https://blog.gusibi.site/post/amazon-dynamodb-insetall-and-setting/</link><pubDate>Sat, 07 Jan 2017 22:57:39 +0800</pubDate><guid>https://blog.gusibi.site/post/amazon-dynamodb-insetall-and-setting/</guid><description>&lt;h3 id="本节主要介绍amazondynamodb-安装配置及python开发示例"&gt;本节主要介绍AmazonDynamoDB 安装配置及Python开发示例&amp;quot;&lt;/h3&gt;
&lt;h2 id="什么是-amazon-dynamodb"&gt;什么是 Amazon DynamoDB&lt;/h2&gt;
&lt;p&gt;Amazon DynamoDB 是一种完全托管的 NoSQL 数据库服务，提供快速而可预测的性能，能够实现无缝扩展。使用 DynamoDB，您可以免除操作和扩展分布式数据库的管理工作负担，因而无需担心硬件预置、设置和配置、复制、软件修补或集群扩展等问题。&lt;/p&gt;
&lt;p&gt;使用 DynamoDB，您可以创建数据库表来存储和检索任意量级的数据，并提供任意级别的请求流量。您可以扩展或缩减您的表的吞吐容量，而不会导致停机或性能下降，还可以使用 AWS 管理控制台来监控资源使用情况和各种性能指标。&lt;/p&gt;
&lt;p&gt;HUGOMORE42&lt;/p&gt;
&lt;h2 id="amazon-dynamodb-特点"&gt;Amazon DynamoDB 特点&lt;/h2&gt;
&lt;p&gt;DynamoDB 会自动将数据和流量分散到足够数量的服务器上，以满足吞吐量和存储需求，同时保持始终如一的高性能。所有数据均存储在固态硬盘 (SSD) 中，并会自动复制到 AWS 区域中的多个可用区中，从而提供内置的高可用性和数据持久性。&lt;/p&gt;
&lt;p&gt;DynamoDB 是 NoSQL 数据库并且无架构，这意味着，与主键属性不同，无需在创建表时定义任何属性或数据类型。与此相对，关系数据库要求在创建表时定义每个列的名称和数据类型。&lt;/p&gt;
&lt;h2 id="amazon-dynamodb-使用"&gt;Amazon DynamoDB 使用&lt;/h2&gt;
&lt;h3 id="aws-配置"&gt;AWS 配置&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;注册 Amazon Web Services 并创建访问密钥&lt;/li&gt;
&lt;li&gt;创建 AWS 凭证文件&lt;/li&gt;
&lt;li&gt;开启DynamoDB 服务&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="在计算机上运行-dynamodb"&gt;在计算机上运行 DynamoDB&lt;/h3&gt;
&lt;p&gt;除了 Amazon DynamoDB Web 服务之外，AWS 还提供可本地运行的可下载版本的 DynamoDB。
使用本地版本，在开发应用程序时无需 Internet 连接。&lt;/p&gt;
&lt;h4 id="方法1-直接在计算机上安装"&gt;方法1 直接在计算机上安装&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;需要安装java环境&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;下载 DynamoDB&lt;/li&gt;
&lt;li&gt;解压，并将解压后的目录复制到某个位置&lt;/li&gt;
&lt;li&gt;打开命令提示符窗口，打开 DynamoDBLocal.jar 的目录，并输入以下命令：&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;现在就可以使用了&lt;/p&gt;</description></item><item><title>网站微信登录－python 实现</title><link>https://blog.gusibi.site/post/weixin-python-login/</link><pubDate>Mon, 05 Sep 2016 17:59:45 +0800</pubDate><guid>https://blog.gusibi.site/post/weixin-python-login/</guid><description>&lt;p&gt;最近我们的网站要加微信登录功能，找了python sdk 感觉都不满意，然后就参考instagram python sdk 自己造了轮子。&lt;/p&gt;
&lt;p&gt;轮子 github 地址 &lt;a href="https://github.com/gusibi/python-weixin"&gt;python-weixin&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="根据需求选择相应的登录方式"&gt;根据需求选择相应的登录方式&lt;/h3&gt;
&lt;p&gt;微信现在提供两种登录接入方式&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;移动应用微信登录&lt;/li&gt;
&lt;li&gt;网站应用微信登录&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;HUGOMORE42&lt;/p&gt;
&lt;p&gt;&lt;em&gt;这里我们使用的是网站应用微信登录&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;按照 官方流程&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;注册并通过开放平台开发者资质认证&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;注册微信开放平台帐号后，在帐号中心中填写开发者资质认证申请，并等待认证通过。&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;创建网站应用&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;通过填写网站应用名称、简介和图标，以及各平台下载地址等资料，创建网站应用&lt;/p&gt;
&lt;ol start="3"&gt;
&lt;li&gt;接入微信登录&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在资源中心查阅网站应用开发文档,开发接入微信登陆功能，让用户可使用微信登录你的网站应用&lt;/p&gt;
&lt;p&gt;如果已经完成上面的操作，请继续往下看&lt;/p&gt;
&lt;p&gt;微信网站应用微信登录是基于OAuth2.0协议标准构建的微信OAuth2.0授权登录系统。&lt;/p&gt;
&lt;p&gt;微信OAuth2.0授权登录目前支持authorization_code模式，适用于拥有server端的应用授权。该模式整体流程为：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;第三方发起微信授权登录请求，微信用户允许授权第三方应用后，微信会拉起应用或重定向到第三方网站，并且带上授权临时票据code参数；&lt;/li&gt;
&lt;li&gt;通过code参数加上AppID和AppSecret等，通过API换取access_token；&lt;/li&gt;
&lt;li&gt;通过access_token进行接口调用，获取用户基本数据资源或帮助用户实现基本操作。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h4 id="获取access_token-时序图"&gt;获取access_token 时序图&lt;/h4&gt;
&lt;p&gt;&lt;img alt="获取access_token 时序图" loading="lazy" src="https://res.wx.qq.com/op_res/D0wkkHSbtC6VUSHX4WsjP5ssg5mdnEmXO8NGVGF34dxS9N1WCcq6wvquR4K_Hcut"&gt;&lt;/p&gt;
&lt;p&gt;具体流程请参考官方文档，我们这里只说一下python的实现方法。官方文档地址 &lt;a href="https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&amp;amp;t=resource/res_list&amp;amp;verify=1&amp;amp;lang=zh_CN&amp;amp;token=db685a316b7e3933cae42c5ca91d4e024125d1b8&amp;amp;appid=wx6d8c79fb64de6c08"&gt;点这里&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;参考python-instagram 我写了一个 [python-weixin] (&lt;a href="https://github.com/gusibi/python-weixin"&gt;https://github.com/gusibi/python-weixin&lt;/a&gt;)一个微信python SDK&lt;/p&gt;
&lt;p&gt;不过现在还只有微信接入、获取用户信息、 刷新refresh_token 等简单功能&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="安装"&gt;安装&lt;/h3&gt;
&lt;h4 id="方法一-手动安装"&gt;方法一 手动安装&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;首先 需要把代码clone到本地&lt;/li&gt;
&lt;li&gt;python setup.py install&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id="方法二-pip-install"&gt;方法二 pip install&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;pip install git+https://github.com/gusibi/python-weixin.git@master
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="使用方式"&gt;使用方式&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;from&lt;/span&gt; weixin.client &lt;span style="color:#f92672"&gt;import&lt;/span&gt; WeixinAPI
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;APP_ID &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;your app id&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;APP_SECRET &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;your app secret&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;REDIRECT_URI &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;http://your_domain.com/redirect_uri&amp;#39;&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 这里一定要注意 地址一定要加上http/https&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;scope &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#e6db74"&gt;&amp;#34;snsapi_login&amp;#34;&lt;/span&gt;, )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;api &lt;span style="color:#f92672"&gt;=&lt;/span&gt; WeixinAPI(appid&lt;span style="color:#f92672"&gt;=&lt;/span&gt;APP_ID,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; app_secret&lt;span style="color:#f92672"&gt;=&lt;/span&gt;APP_SECRET,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; redirect_uri&lt;span style="color:#f92672"&gt;=&lt;/span&gt;REDIRECT_URI)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;authorize_url &lt;span style="color:#f92672"&gt;=&lt;/span&gt; api&lt;span style="color:#f92672"&gt;.&lt;/span&gt;get_authorize_url(scope&lt;span style="color:#f92672"&gt;=&lt;/span&gt;scope)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;现在将 authorize_url地址(如 &lt;a href="http://yoursite.com/login/weixin"&gt;http://yoursite.com/login/weixin&lt;/a&gt;)在浏览器打开， 将跳转到微信登录页面，使用手机扫码登录后将跳转到&lt;/p&gt;</description></item><item><title>跟着代码学go 002 -- 控制流</title><link>https://blog.gusibi.site/post/golang-learning-by-code-002/</link><pubDate>Tue, 26 Apr 2016 15:49:35 +0800</pubDate><guid>https://blog.gusibi.site/post/golang-learning-by-code-002/</guid><description>跟着代码学golang 控制流</description></item><item><title>跟着代码学go 001 -- 变量&amp;函数</title><link>https://blog.gusibi.site/post/golang-learning-by-code-001/</link><pubDate>Mon, 25 Apr 2016 14:53:47 +0800</pubDate><guid>https://blog.gusibi.site/post/golang-learning-by-code-001/</guid><description>跟着代码学golang 变量 函数 基本数据结构</description></item><item><title>golang 介绍</title><link>https://blog.gusibi.site/post/golang-description/</link><pubDate>Thu, 14 Apr 2016 22:44:40 +0800</pubDate><guid>https://blog.gusibi.site/post/golang-description/</guid><description>&lt;h2 id="1-golang-是什么"&gt;1. Golang 是什么&lt;/h2&gt;
&lt;p&gt;Go 官方说明：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Go 编程语言是一个使得程序员更加有效率的开源项目。Go 是有表达力、简 洁、清晰和有效率的。它的并行机制使其很容易编写多核和网络应用,而新的类型系统允许构建有 性的模块化程序。Go 编译到机器码非常快 速,同时具有便利的垃圾回收和强大的运行时反射。它是快速的、静态类 型编译语言,但是感觉上是动态类型的,解释型语言&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;HUGOMORE42&lt;/p&gt;
&lt;h2 id="2-为什么要开发这个语言"&gt;2. 为什么要开发这个语言&lt;/h2&gt;
&lt;h3 id="go-语言的发展目标"&gt;Go 语言的发展目标&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Go 语言的主要目标是将静态语言的安全性和高效性与动态语言的易开发性进行有机结合&lt;/li&gt;
&lt;li&gt;Go 语言是一门类型安全和内存安全的编程语言。虽然 Go 语言中仍有指针的存在，但并不允许进行指针运算。&lt;/li&gt;
&lt;li&gt;Go 语言的另一个目标是对于网络通信、并发和并行编程的极佳支持，从而更好地利用大量的分布式和多核的计算机&lt;/li&gt;
&lt;li&gt;Go 语言中另一个非常重要的特性就是它的构建速度（编译和链接到机器代码的速度），一般情况下构建一个程序的时间只需要数百毫秒到几秒。&lt;/li&gt;
&lt;li&gt;Go 语言实现高效快速的垃圾回收（使用了一个简单的标记-清除算法）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="3-有什么特性用途"&gt;3. 有什么特性&amp;amp;&amp;amp;用途&lt;/h2&gt;
&lt;h3 id="语言的特性"&gt;语言的特性&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;清晰并且简洁&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Go 努力保持小并且优美,你可以在短短几行代码里做许多事情;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;并行&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Go 语言从本质上（程序和结构方面）来实现并发编程。
Go 让函数很容易成为非常轻量的线程。这些线程在 Go 中被叫做 goroutines&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Channel&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;这些 goroutines 之间的通讯由 channel[18, 25] 完成&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;快速&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;编译很快,执行也很快。目标是跟 C 一样快。编译时间用秒计算;
Go 的可执行文件都比相对应的源代码文件要大很多，这恰恰说明了 Go 的 runtime 嵌入到了每一个可执行文件当中。当然，在部署到数量巨大的集群时，较大的文件体积也是比较头疼的问题。但总得来说，Go 的部署工作还是要比 Java 和 Python 轻松得多。因为 Go 不需要依赖任何其它文件，它只需要一个单独的静态文件，这样你也不会像使用其它语言一样在各种不同版本的依赖文件之间混淆。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;安全&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;当转换一个类型到另一个类型的时候需要显式的转换并遵循严格的规则。Go 有 垃圾收集（使用了一个简单的标记-清除算法）,在 Go 中无须 free(),语言会处理这一切;
值得注意的是，因为垃圾回收和自动内存分配的原因，Go 语言不适合用来开发对实时性要求很高的软件。&lt;/p&gt;</description></item></channel></rss>