<?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>Python on 古思乱想</title><link>https://blog.gusibi.site/categories/python/</link><description>Recent content in Python on 古思乱想</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Sat, 15 Jun 2019 23:34:53 +0800</lastBuildDate><atom:link href="https://blog.gusibi.site/categories/python/index.xml" rel="self" type="application/rss+xml"/><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>并发模型：线程与锁</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>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>使用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>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>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>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>微信公号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>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></channel></rss>