<?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>读书笔记 on 古思乱想</title><link>https://blog.gusibi.site/categories/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/</link><description>Recent content in 读书笔记 on 古思乱想</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Thu, 30 May 2019 21:05:57 +0800</lastBuildDate><atom:link href="https://blog.gusibi.site/categories/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/index.xml" rel="self" type="application/rss+xml"/><item><title>PostgreSQL jsonb 使用入门</title><link>https://blog.gusibi.site/post/postgresql-json/</link><pubDate>Thu, 30 May 2019 21:05:57 +0800</pubDate><guid>https://blog.gusibi.site/post/postgresql-json/</guid><description>postgresql json jsonb 使用入门</description></item><item><title>并发模型：线程与锁</title><link>https://blog.gusibi.site/post/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>垃圾回收算法|引用计数法</title><link>https://blog.gusibi.site/post/gc-reference-counting/</link><pubDate>Sun, 12 Aug 2018 19:15:05 +0800</pubDate><guid>https://blog.gusibi.site/post/gc-reference-counting/</guid><description>垃圾回收算法|引用计数法</description></item><item><title>垃圾回收算法|GC标记-清除算法</title><link>https://blog.gusibi.site/post/gc-mark-sweep/</link><pubDate>Sat, 21 Jul 2018 11:15:05 +0800</pubDate><guid>https://blog.gusibi.site/post/gc-mark-sweep/</guid><description>垃圾回收算法|标记-清除算法</description></item><item><title>Golang 学习笔记-2：控制流</title><link>https://blog.gusibi.site/post/golang-learing-note-2/</link><pubDate>Tue, 17 Apr 2018 23:49:35 +0800</pubDate><guid>https://blog.gusibi.site/post/golang-learing-note-2/</guid><description>golang 学习笔记 控制流</description></item><item><title>《理解 unix 进程》笔记-1</title><link>https://blog.gusibi.site/post/understand-unix-process-note-1/</link><pubDate>Sun, 25 Mar 2018 23:25:53 +0800</pubDate><guid>https://blog.gusibi.site/post/understand-unix-process-note-1/</guid><description>description</description></item><item><title>操作系统线程描述</title><link>https://blog.gusibi.site/post/system-process-3/</link><pubDate>Sat, 24 Mar 2018 12:25:53 +0800</pubDate><guid>https://blog.gusibi.site/post/system-process-3/</guid><description>description</description></item><item><title>操作系统进程描述</title><link>https://blog.gusibi.site/post/system-process-2/</link><pubDate>Tue, 20 Mar 2018 23:25:53 +0800</pubDate><guid>https://blog.gusibi.site/post/system-process-2/</guid><description>description</description></item><item><title>操作系统发展和进程简介</title><link>https://blog.gusibi.site/post/system-process-1/</link><pubDate>Wed, 07 Mar 2018 23:25:53 +0800</pubDate><guid>https://blog.gusibi.site/post/system-process-1/</guid><description>description</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-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>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>CSS入门指南-3：定位元素</title><link>https://blog.gusibi.site/post/css-learing-3-positioning-elements/</link><pubDate>Wed, 26 Jul 2017 22:21:49 +0800</pubDate><guid>https://blog.gusibi.site/post/css-learing-3-positioning-elements/</guid><description>&lt;blockquote&gt;
&lt;p&gt;这是《CSS设计指南》的读书笔记，用于加深学习效果。
前一篇&lt;a href="https://mp.weixin.qq.com/s?__biz=MzAwNjI5MjAzNw==&amp;amp;mid=2655752018&amp;amp;idx=1&amp;amp;sn=6915e4f11ba08fa196a64375224cd92e&amp;amp;chksm=80b0b878b7c7316e1a065ae991c534cc11ca5fe72b33690a98fb1c3f6f53f8c98c4c8744cd3a#rd"&gt;CSS入门指南-2：盒子模型、浮动和清除&lt;/a&gt;介绍了css盒子模型、浮动和清除，这一篇介绍 css元素的定位。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="定位position"&gt;定位（position）&lt;/h2&gt;
&lt;p&gt;CSS 布局的核心是 position 属性，对元素盒子应用这个属性，可以相对于它在常规文档流中的位置重新定位。
position 属性有4个值：&lt;code&gt;static&lt;/code&gt;、&lt;code&gt;relative&lt;/code&gt;、&lt;code&gt;absoulte&lt;/code&gt;、&lt;code&gt;fixed&lt;/code&gt;，默认值为 static。&lt;/p&gt;
&lt;p&gt;接下来我会用以下四个段落来逐个说明这些属性是什么意思。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;p&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;first&amp;#34;&lt;/span&gt;&amp;gt;First Paragraph&amp;lt;/&lt;span style="color:#f92672"&gt;p&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;p&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;Second&amp;#34;&lt;/span&gt;&amp;gt;Second Paragraph&amp;lt;/&lt;span style="color:#f92672"&gt;p&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;p&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;specialpara&amp;#34;&lt;/span&gt;&amp;gt;Third Paragraph&amp;lt;/&lt;span style="color:#f92672"&gt;p&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;p&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;fourth&amp;#34;&lt;/span&gt;&amp;gt;First Paragraph&amp;lt;/&lt;span style="color:#f92672"&gt;p&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="静态定位static"&gt;静态定位（static）&lt;/h3&gt;
&lt;p&gt;我们先看一下四个段落都采用静态定位的效果。&lt;/p&gt;
&lt;p&gt;&lt;img alt="四段都采用静态定位的图示" loading="lazy" src="http://media.gusibi.mobi/R_7xrRQEA1TEc4S1GJsxwpfz99rx6nvnb0KZNOc1m-D5P8bdMAq-mQsvZ85xxMSb"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;静态定位下，每个元素在处在常规文档流中，它们都是块级元素，所以会在页面中自上而下地堆叠。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="相对定位relative"&gt;相对定位（relative）&lt;/h3&gt;
&lt;p&gt;现在我把第三段的 position 属性设置为 relative。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;p&lt;/span&gt;#specialpara {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;position&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;relative&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;top&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;25&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;left&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;30&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;因为相对定位&lt;code&gt;相对的是它原来在文档流中的位置（默认位置）&lt;/code&gt;，所以如果只设置 position 样式不会有任何变化。这里我同时设置了 top 和 left 属性来改变它的位置。&lt;/p&gt;
&lt;p&gt;现在它的效果如图所示：&lt;/p&gt;
&lt;p&gt;&lt;img alt="第三段使用相对定位的效果图" loading="lazy" src="http://media.gusibi.mobi/5OFF-2lXXl-JAY4tUuAl0V3Z5q6livJzUz11Fs7N8nIbz9mYgGp8GlzA6oM6_U9J"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;现在，第三段从原来的元素（body）中挣脱了出来，与它在文档中的默认位置相比向下移动了25像素，向右移动了30像素。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;需要注意的是，除了这个元素自己相对于原始位置挪动了一下以外，页面没有任何改变。这个元素原来占据的空间没有动，其他元素也没动。&lt;/p&gt;
&lt;p&gt;这时，如果不想第四段被它挡住，可以给第四段设置一个 margin-top 值。&lt;/p&gt;
&lt;h3 id="绝对定位absoulte"&gt;绝对定位（absoulte）&lt;/h3&gt;
&lt;p&gt;绝对定位跟静态定位和相对定位相比，它会把元素彻底从文档流中拿出来。&lt;/p&gt;
&lt;p&gt;我们把 position 改为绝对定位看一下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;p&lt;/span&gt;#specialpara {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;position&lt;/span&gt;: absoulte;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;top&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;25&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;left&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;30&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;效果如图：&lt;/p&gt;
&lt;p&gt;&lt;img alt="第三段使用绝对定位的效果图" loading="lazy" src="http://media.gusibi.mobi/2-U0Y3OwzCz9gOLmV-LF96-U1nnRhPUjvX6InOVjCfPo9vWCqwx0d_mQlmsFCkWL"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;可以看到，第三段原来的位置被回收了。这说明绝对定位的元素脱离了常规文档流，它现在是相对于顶级元素 body 在定位。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;现在就涉及到一个概念：&lt;code&gt;定位上下文&lt;/code&gt;，这个后边说，先继续看最后一种定位方式：&lt;code&gt;固定定位&lt;/code&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;盒子位移属性是如何工作？&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;盒子的位移属性有四个“top、right、bottom和left”，用来指定元素的定位位置和方向。这些属性只能在元素的“position”属性设置了“relative、absolute和fixed”属性值，才生效。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;对于相对定位元素，这些属性的设置让元素从默认位置移动。例如，top设置一个值“20px”在一个相对定位的元素上，这个元素会在原来位置向下移动“20px”。&lt;/p&gt;</description></item><item><title>CSS入门指南-2：盒子模型、浮动和清除</title><link>https://blog.gusibi.site/post/css-learing-2-box-model-float-and-clear/</link><pubDate>Wed, 19 Jul 2017 22:22:49 +0800</pubDate><guid>https://blog.gusibi.site/post/css-learing-2-box-model-float-and-clear/</guid><description>&lt;blockquote&gt;
&lt;p&gt;这是CSS设计指南的读书笔记，用于加深学习效果。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;上一篇介绍了css 的工作原理，这一篇主要介绍&lt;code&gt;盒子模型&lt;/code&gt;和&lt;code&gt;浮动&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id="盒子模型"&gt;盒子模型&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;所谓盒子模型，就是浏览器为页面中的每个HTML元素生成的矩形盒子。这些盒子们都要按照可见版式模型在页面上排布。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;HUGOMORE42&lt;/p&gt;
&lt;p&gt;可见的页面版式主要由三个属性控制：position、display和float。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;position：控制页面上元素的位置关系&lt;/li&gt;
&lt;li&gt;display：控制元素是堆叠、并排还是不在页面出现&lt;/li&gt;
&lt;li&gt;float：提供控制的方式，以便吧元素组成多栏布局&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;元素盒子的属性可以分成三组：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;边框(board)。可以甚至边框的宽窄、样式和颜色&lt;/li&gt;
&lt;li&gt;内边距(padding)。可以甚至盒子内容区与边框的间距&lt;/li&gt;
&lt;li&gt;外边距(margin)。可以设置盒子与相邻元素的间距&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="盒模型示意图展示了HTML元素的边框、内边距和外边距之间的关系" loading="lazy" src="http://omuo4kh1k.bkt.clouddn.com/4J2VDi7TIFFuSOVgWp-3uuDrzvYh7oMDxeNv5OxgpaQoUGlHPo8tL43fAa5iheKn"&gt;&lt;/p&gt;
&lt;p&gt;元素盒子还有一个背景层，可以改变颜色，也可以添加图片。&lt;/p&gt;
&lt;h3 id="简写样式"&gt;简写样式&lt;/h3&gt;
&lt;p&gt;CSS为边框、内边距和外边距分别规定了简写属性，每个简写声明中，属性值得顺序都是上、右、下、左。&lt;/p&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;margin-top&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;margin-right&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;margin-bottom&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;margin-left&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;使用简写则为这样：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;margin&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果有一个值没写，那么则使用对边的值。&lt;/p&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{&lt;span style="color:#66d9ef"&gt;margin&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/*等同于*/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;margin&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果只写一个值，则4个边都取这个值。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{&lt;span style="color:#66d9ef"&gt;margin&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/*等同于*/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{&lt;span style="color:#66d9ef"&gt;margin&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;另外每个盒子的属性也分三个粒度，这三个粒度从一般到特殊分别举例如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;border&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;dashed&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;red&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;混合使用三种粒度的简写属性达成设计目标是很常见的。比如，想为盒子的上边和下边添加4像素的红色边框，为左边添加1像素宽的红色边框，而右边没有。可以这么写：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{&lt;span style="color:#66d9ef"&gt;border&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;solid&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;red&lt;/span&gt;;} &lt;span style="color:#75715e"&gt;/* 先给4条边设置相同的样式*/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{&lt;span style="color:#66d9ef"&gt;border-left-width&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;} &lt;span style="color:#75715e"&gt;/* 修改左边框宽度*/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{border-fight: &lt;span style="color:#66d9ef"&gt;none&lt;/span&gt;;} &lt;span style="color:#75715e"&gt;/*移出右边框*/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="盒子边框"&gt;盒子边框&lt;/h3&gt;
&lt;p&gt;border 有三个相关属性。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;宽度（border-width)。可以使用thin、medium和thick等文本值，也可以使用除百分比和负值之外的任何绝对值。&lt;/li&gt;
&lt;li&gt;样式（border-style)。有none、hidden、dotted、dashed等文本值。&lt;/li&gt;
&lt;li&gt;颜色（border-color）。可以使用任意颜色值，包括RGB、HSL、十六进制颜色值和颜色关键字。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="盒子内边距"&gt;盒子内边距&lt;/h3&gt;
&lt;p&gt;内边距是盒子内容区与盒子边框之间的距离。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="http://omuo4kh1k.bkt.clouddn.com/sKiD0I3LeE7lTK8rARqH8TFpzVK9vh4QoAWCg_7Ll7m9V8VMkBNKY_YfvVUueia8"&gt;&lt;/p&gt;
&lt;p&gt;上图的样式为：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;p&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;font&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;16&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; helvetica, &lt;span style="color:#66d9ef"&gt;sans-serif&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;width&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;220&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;border&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;solid&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;red&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;background-color&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;#caebff&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;可以看到在没有设定内边距的情况下，内容紧挨着边框。&lt;/p&gt;
&lt;p&gt;设定边框后：&lt;/p&gt;</description></item><item><title>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并发2：使用asyncio处理并发</title><link>https://blog.gusibi.site/post/python-asyncio/</link><pubDate>Fri, 23 Jun 2017 16:29:39 +0800</pubDate><guid>https://blog.gusibi.site/post/python-asyncio/</guid><description>python asyncio 介绍</description></item><item><title>python并发 1：使用 futures 处理并发</title><link>https://blog.gusibi.site/post/python-concurrency-with-futures/</link><pubDate>Sat, 17 Jun 2017 22:01:51 +0800</pubDate><guid>https://blog.gusibi.site/post/python-concurrency-with-futures/</guid><description>&lt;blockquote&gt;
&lt;p&gt;作为Python程序员，平时很少使用并发编程，偶尔使用也只需要派生出一批独立的线程，然后放到队列中，批量执行。所以，不夸张的说，虽然我知道线程、进程、并行、并发的概念，但每次使用的时候可能还需要再打开文档回顾一下。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;现在这一篇还是 &lt;em&gt;《流畅的python》读书笔记&lt;/em&gt;，译者在这里把future 翻译为“期物”，我觉得不太合适，既然future不能找到一个合适的词汇，暂时还是直接使用 future 吧。&lt;/p&gt;
&lt;h2 id="concurrentfutures"&gt;concurrent.futures&lt;/h2&gt;
&lt;p&gt;future 是一种对象，表示异步执行的操作。这个概念是 concurrent.futures模块和asyncio包的基础。&lt;/p&gt;
&lt;p&gt;concurrent.futures 模块是Python3.2 引入的，对于Python2x 版本，Python2.5 以上的版本可以安装 futures 包来使用这个模块。&lt;/p&gt;
&lt;p&gt;HUGOMORE42&lt;/p&gt;
&lt;p&gt;从Python3.4起，标准库中有两个为Future的类：concurrent.futures.Future 和 asyncio.Future。这两个类作用相同：两个Future类的实例都表示可能已经完成或未完成的延迟计算。&lt;/p&gt;
&lt;p&gt;Future 封装待完成的操作，可放入队列，完成的状态可以查询，得到结果（或抛出异常）后可以获取结果（或异常）。&lt;/p&gt;
&lt;p&gt;我们知道，如果程序中包含I/O操作，程序会有很高的延迟，CPU会处于等待状态，这时如果我们不使用并发会浪费很多时间。&lt;/p&gt;
&lt;h3 id="示例"&gt;示例&lt;/h3&gt;
&lt;p&gt;我们先举个例子：&lt;/p&gt;
&lt;p&gt;下边是有两段代码，主要功能都是从网上下载人口前20的国际的国旗：
第一段代码(flagss.py)是依序下载：下载完一个图片后保存到硬盘，然后请求下一张图片；
第二段代码(flagss_threadpool.py)使用 concurrent.futures 模块，批量下载10张图片。&lt;/p&gt;
&lt;p&gt;运行分别运行两段代码3次，结果如下：&lt;/p&gt;
&lt;p&gt;images.py 的结果如下&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ python flags.py
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;BD BR CD CN DE EG ET FR ID IN IR JP MX NG PH PK RU TR US VN
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;20&lt;/span&gt; flags downloaded in 6.18s
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ python flags.py
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;BD BR CD CN DE EG ET FR ID IN IR JP MX NG PH PK RU TR US VN
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;20&lt;/span&gt; flags downloaded in 5.67s
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ python flags.py
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;BD BR CD CN DE EG ET FR ID IN IR JP MX NG PH PK RU TR US VN
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;20&lt;/span&gt; flags downloaded in 6.55s
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;可以看到，依次下载10张图片，平均需要6秒&lt;/p&gt;</description></item><item><title>python协程3：用仿真实验学习协程</title><link>https://blog.gusibi.site/post/python-coroutine-discrete-event-simulation/</link><pubDate>Thu, 15 Jun 2017 19:22:49 +0800</pubDate><guid>https://blog.gusibi.site/post/python-coroutine-discrete-event-simulation/</guid><description>&lt;p&gt;前两篇我们已经介绍了&lt;a href="https://gusibi.github.io/post/python-coroutine-1-yield/"&gt;python 协程的使用&lt;/a&gt;和&lt;a href="https://gusibi.github.io/post/python-coroutine-yield-from/"&gt;yield from 的原理&lt;/a&gt;，这一篇，我们用一个例子来揭示如何使用协程在单线程中管理并发活动。&lt;/p&gt;
&lt;h2 id="什么是离散事件仿真"&gt;什么是离散事件仿真&lt;/h2&gt;
&lt;p&gt;Wiki上的定义是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;离散事件仿真将系统随时间的变化抽象成一系列的离散时间点上的事件，通过按照事件时间顺序处理事件来演进，是一种事件驱动的仿真世界观。离散事件仿真将系统的变化看做一个事件，因此系统任何的变化都只能是通过处理相应的事件来实现，在两个相邻的事件之间，系统状态维持前一个事件发生后的状态不变。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;人话说就是一种把系统建模成一系列事件的仿真系统。在离散事件仿真中，仿真“钟”向前推进的量不是固定的，而是直接推进到下一个事件模型的模拟时间。&lt;/p&gt;
&lt;p&gt;假设我们抽象模拟出租车的运营过程，其中一个事件是乘客上车，下一个事件则是乘客下车。不管乘客做了5分钟还是50分钟，一旦下车，仿真钟就会更新，指向此次运营的结束时间。&lt;/p&gt;
&lt;p&gt;事件？是不是想到了协程！&lt;/p&gt;
&lt;p&gt;协程恰好为实现离散事件仿真提供了合理的抽象。&lt;/p&gt;
&lt;p&gt;HUGOMORE42&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;第一门面向对象的语音 Simula 引入协程这个概念就是为了支持仿真。
Simpy 是一个实现离散事件仿真的Python包，通过一个协程表示离散事件仿真系统的各个进程。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="出租车对运营仿真"&gt;出租车对运营仿真&lt;/h2&gt;
&lt;p&gt;仿真程序会创建几辆出租车，每辆出租车会拉几个乘客，然后回家。出租车会首先驶离车库，四处徘徊，寻找乘客；拉到乘客后，行程开始；乘客下车后，继续四处徘徊。&lt;/p&gt;
&lt;p&gt;徘徊和行程所用的时间使用指数分布生成，我们将时间设为分钟数，以便显示清楚。&lt;/p&gt;
&lt;p&gt;完整代码如下：(taxi_sim.py)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#! -*- coding: utf-8 -*-&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; random
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; collections
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; queue
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; argparse
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;DEFAULT_NUMBER_OF_TAXIS &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;DEFAULT_END_TIME &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;180&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;SEARCH_DURATION &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;TRIP_DURATION &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;DEPARTURE_INTERAVAL &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# time 是事件发生的仿真时间，proc 是出租车进程实例的编号，action是描述活动的字符串&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Event &lt;span style="color:#f92672"&gt;=&lt;/span&gt; collections&lt;span style="color:#f92672"&gt;.&lt;/span&gt;namedtuple(&lt;span style="color:#e6db74"&gt;&amp;#39;Event&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;time proc action&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 开始 出租车进程&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 每辆出租车调用一次taxi_process 函数，创建一个生成器对象，表示各辆出租车的运营过程。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;taxi_process&lt;/span&gt;(ident, trips, start_time&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; 每次状态变化时向创建事件，把控制权交给仿真器
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param ident: 出租车编号
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param trips: 出租车回家前的行程数量
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param start_time: 离开车库的时间
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :return:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; time &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;yield&lt;/span&gt; Event(start_time, ident, &lt;span style="color:#e6db74"&gt;&amp;#39;leave garage&amp;#39;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;# 产出的第一个Event&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(trips): &lt;span style="color:#75715e"&gt;# 每次行程都会执行一遍这个代码块&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 产出一个Event实例，表示拉到了乘客 协程在这里暂停 等待下一次send() 激活&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; time &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;yield&lt;/span&gt; Event(time, ident, &lt;span style="color:#e6db74"&gt;&amp;#39;pick up passenger&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 产出一个Event实例，表示乘客下车 协程在这里暂停 等待下一次send() 激活&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; time &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;yield&lt;/span&gt; Event(time, ident, &lt;span style="color:#e6db74"&gt;&amp;#39;drop off passenger&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 指定的行程数量完成后，for 循环结束，最后产出 &amp;#39;going home&amp;#39; 事件。协程最后一次暂停&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;yield&lt;/span&gt; Event(time, ident, &lt;span style="color:#e6db74"&gt;&amp;#39;going home&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 协程执行到最后 抛出StopIteration 异常&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;compute_duration&lt;/span&gt;(previous_action):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&amp;#39;使用指数分布计算操作的耗时&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; previous_action &lt;span style="color:#f92672"&gt;in&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#39;leave garage&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;drop off passenger&amp;#39;&lt;/span&gt;]:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 新状态是四处徘徊&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; interval &lt;span style="color:#f92672"&gt;=&lt;/span&gt; SEARCH_DURATION
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;elif&lt;/span&gt; previous_action &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;pick up passenger&amp;#39;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 新状态是开始行程&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; interval &lt;span style="color:#f92672"&gt;=&lt;/span&gt; TRIP_DURATION
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;elif&lt;/span&gt; previous_action &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;going home&amp;#39;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; interval &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;raise&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ValueError&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;Unkonw previous_action: &lt;/span&gt;&lt;span style="color:#e6db74"&gt;%s&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;%&lt;/span&gt; previous_action)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; int(random&lt;span style="color:#f92672"&gt;.&lt;/span&gt;expovariate(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;interval)) &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 开始仿真&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Simulator&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;__init__&lt;/span&gt;(self, procs_map):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;events &lt;span style="color:#f92672"&gt;=&lt;/span&gt; queue&lt;span style="color:#f92672"&gt;.&lt;/span&gt;PriorityQueue() &lt;span style="color:#75715e"&gt;# 带优先级的队列 会按时间正向排序&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;procs &lt;span style="color:#f92672"&gt;=&lt;/span&gt; dict(procs_map) &lt;span style="color:#75715e"&gt;# 从获取的procs_map 参数中创建本地副本，为了不修改用户传入的值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;run&lt;/span&gt;(self, end_time):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; 调度并显示事件，直到时间结束
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param end_time: 结束时间 只需要指定一个参数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :return:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 调度各辆出租车的第一个事件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; iden, proc &lt;span style="color:#f92672"&gt;in&lt;/span&gt; sorted(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;procs&lt;span style="color:#f92672"&gt;.&lt;/span&gt;items()):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; first_event &lt;span style="color:#f92672"&gt;=&lt;/span&gt; next(proc) &lt;span style="color:#75715e"&gt;# 预激协程 并产出一个 Event 对象&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;events&lt;span style="color:#f92672"&gt;.&lt;/span&gt;put(first_event) &lt;span style="color:#75715e"&gt;# 把各个事件加到self.events 属性表示的 PriorityQueue对象中&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 此次仿真的主循环&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sim_time &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 把 sim_time 归0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; sim_time &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; end_time:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;events&lt;span style="color:#f92672"&gt;.&lt;/span&gt;empty(): &lt;span style="color:#75715e"&gt;# 事件全部完成后退出循环&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;&amp;#39;*** end of event ***&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;break&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; current_event &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;events&lt;span style="color:#f92672"&gt;.&lt;/span&gt;get() &lt;span style="color:#75715e"&gt;# 获取优先级最高(time 属性最小)的事件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sim_time, proc_id, previous_action &lt;span style="color:#f92672"&gt;=&lt;/span&gt; current_event &lt;span style="color:#75715e"&gt;# 更新 sim_time&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;&amp;#39;taxi:&amp;#39;&lt;/span&gt;, proc_id, proc_id &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39; &amp;#39;&lt;/span&gt;, current_event)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; active_proc &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;procs[proc_id] &lt;span style="color:#75715e"&gt;# 从self.procs 字典中获取表示当前活动的出租车协程&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; next_time &lt;span style="color:#f92672"&gt;=&lt;/span&gt; sim_time &lt;span style="color:#f92672"&gt;+&lt;/span&gt; compute_duration(previous_action)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; next_event &lt;span style="color:#f92672"&gt;=&lt;/span&gt; active_proc&lt;span style="color:#f92672"&gt;.&lt;/span&gt;send(next_time) &lt;span style="color:#75715e"&gt;# 把计算得到的时间发送给出租车协程。协程会产出下一个事件，或者抛出 StopIteration&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;except&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;StopIteration&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;del&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;procs[proc_id] &lt;span style="color:#75715e"&gt;# 如果有异常 表示已经退出， 删除这个协程&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;events&lt;span style="color:#f92672"&gt;.&lt;/span&gt;put(next_event) &lt;span style="color:#75715e"&gt;# 如果没有异常，把next_event 加入到队列&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;: &lt;span style="color:#75715e"&gt;# 如果超时 则走到这里&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; msg &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;*** end of simulation time: &lt;/span&gt;&lt;span style="color:#e6db74"&gt;{}&lt;/span&gt;&lt;span style="color:#e6db74"&gt; event pendding ***&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(msg&lt;span style="color:#f92672"&gt;.&lt;/span&gt;format(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;events&lt;span style="color:#f92672"&gt;.&lt;/span&gt;qsize()))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(end_time&lt;span style="color:#f92672"&gt;=&lt;/span&gt;DEFAULT_END_TIME, num_taxis&lt;span style="color:#f92672"&gt;=&lt;/span&gt;DEFAULT_NUMBER_OF_TAXIS,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; seed&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&amp;#39;初始化随机生成器，构建过程，运行仿真程序&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; seed &lt;span style="color:#f92672"&gt;is&lt;/span&gt; &lt;span style="color:#f92672"&gt;not&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; random&lt;span style="color:#f92672"&gt;.&lt;/span&gt;seed(seed) &lt;span style="color:#75715e"&gt;# 获取可复现的结果&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 构建taxis 字典。值是三个参数不同的生成器对象。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; taxis &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {i: taxi_process(i, (i &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;) &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, i&lt;span style="color:#f92672"&gt;*&lt;/span&gt;DEPARTURE_INTERAVAL)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(num_taxis)}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sim &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Simulator(taxis)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sim&lt;span style="color:#f92672"&gt;.&lt;/span&gt;run(end_time)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; __name__ &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; parser &lt;span style="color:#f92672"&gt;=&lt;/span&gt; argparse&lt;span style="color:#f92672"&gt;.&lt;/span&gt;ArgumentParser(description&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;Taxi fleet simulator.&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; parser&lt;span style="color:#f92672"&gt;.&lt;/span&gt;add_argument(&lt;span style="color:#e6db74"&gt;&amp;#39;-e&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;--end-time&amp;#39;&lt;/span&gt;, type&lt;span style="color:#f92672"&gt;=&lt;/span&gt;int,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; default&lt;span style="color:#f92672"&gt;=&lt;/span&gt;DEFAULT_END_TIME,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; help&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;simulation end time; default=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;%s&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;%&lt;/span&gt; DEFAULT_END_TIME)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; parser&lt;span style="color:#f92672"&gt;.&lt;/span&gt;add_argument(&lt;span style="color:#e6db74"&gt;&amp;#39;-t&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;--taxis&amp;#39;&lt;/span&gt;, type&lt;span style="color:#f92672"&gt;=&lt;/span&gt;int,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; default&lt;span style="color:#f92672"&gt;=&lt;/span&gt;DEFAULT_NUMBER_OF_TAXIS,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; help&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;number of taxis running; default = &lt;/span&gt;&lt;span style="color:#e6db74"&gt;%s&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;%&lt;/span&gt; DEFAULT_NUMBER_OF_TAXIS)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; parser&lt;span style="color:#f92672"&gt;.&lt;/span&gt;add_argument(&lt;span style="color:#e6db74"&gt;&amp;#39;-s&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;--seed&amp;#39;&lt;/span&gt;, type&lt;span style="color:#f92672"&gt;=&lt;/span&gt;int, default&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; help&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;random generator seed (for testing)&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; args &lt;span style="color:#f92672"&gt;=&lt;/span&gt; parser&lt;span style="color:#f92672"&gt;.&lt;/span&gt;parse_args()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; main(args&lt;span style="color:#f92672"&gt;.&lt;/span&gt;end_time, args&lt;span style="color:#f92672"&gt;.&lt;/span&gt;taxis, args&lt;span style="color:#f92672"&gt;.&lt;/span&gt;seed)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;运行程序，&lt;/p&gt;</description></item><item><title>python协程2：yield from 从入门到精通</title><link>https://blog.gusibi.site/post/python-coroutine-yield-from/</link><pubDate>Wed, 14 Jun 2017 17:22:49 +0800</pubDate><guid>https://blog.gusibi.site/post/python-coroutine-yield-from/</guid><description>&lt;p&gt;上一篇&lt;a href="https://mp.weixin.qq.com/s?__biz=MzAwNjI5MjAzNw==&amp;amp;mid=2655751983&amp;amp;idx=1&amp;amp;sn=e4c093c6e5d6e4e8281d76db7c67eb23"&gt;python协程1：yield的使用&lt;/a&gt;介绍了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;生成器作为协程使用时的行为和状态&lt;/li&gt;
&lt;li&gt;使用装饰器预激协程&lt;/li&gt;
&lt;li&gt;调用方如何使用生成器对象的 .throw(&amp;hellip;) 和 .close() 方法控制协程&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这一篇将介绍：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;协程终止时如何返回值&lt;/li&gt;
&lt;li&gt;yield新句法的用途和语义&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;HUGOMORE42&lt;/p&gt;
&lt;h2 id="让协程返回值"&gt;让协程返回值&lt;/h2&gt;
&lt;p&gt;先看一个例子：
这段代码会返回最终均值的结果，每次激活协程时不会产出移动平均值，而是最后一次返回。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#! -*- coding: utf-8 -*-&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;from&lt;/span&gt; collections &lt;span style="color:#f92672"&gt;import&lt;/span&gt; namedtuple
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Result &lt;span style="color:#f92672"&gt;=&lt;/span&gt; namedtuple(&lt;span style="color:#e6db74"&gt;&amp;#39;Result&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;count average&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;averager&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; total &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; count &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; average &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; term &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;yield&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; term &lt;span style="color:#f92672"&gt;is&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;break&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 为了返回值，协程必须正常终止；这里是退出条件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; total &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; term
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; count &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; average &lt;span style="color:#f92672"&gt;=&lt;/span&gt; total&lt;span style="color:#f92672"&gt;/&lt;/span&gt;count
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 返回一个namedtuple，包含count和average两个字段。在python3.3前，如果生成器返回值，会报错&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Result(count, average)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我们调用这段代码，结果如下&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; coro_avg &lt;span style="color:#f92672"&gt;=&lt;/span&gt; averager()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; next(coro_avg)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; coro_avg&lt;span style="color:#f92672"&gt;.&lt;/span&gt;send(&lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;) &lt;span style="color:#75715e"&gt;# 并没有返回值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; coro_avg&lt;span style="color:#f92672"&gt;.&lt;/span&gt;send(&lt;span style="color:#ae81ff"&gt;30&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; coro_avg&lt;span style="color:#f92672"&gt;.&lt;/span&gt;send(&lt;span style="color:#ae81ff"&gt;40&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; coro_avg&lt;span style="color:#f92672"&gt;.&lt;/span&gt;send(&lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;) &lt;span style="color:#75715e"&gt;# 发送None终止循环，导致协程结束。生成器对象会抛出StopIteration异常。异常对象的value属性保存着返回值。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Traceback (most recent call last):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;StopIteration&lt;/span&gt;: Result(count&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;, average&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;30&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;return 表达式的值会传给调用方，&lt;em&gt;赋值给StopIteration&lt;/em&gt; 异常的一个属性。这样做虽然看着别扭，但为了保留生成器对象耗尽时抛出StopIteration异常的行为，也可以理解。&lt;/p&gt;</description></item><item><title>python协程1：协程 10分钟入门</title><link>https://blog.gusibi.site/post/python-coroutine-1-yield/</link><pubDate>Mon, 12 Jun 2017 17:22:49 +0800</pubDate><guid>https://blog.gusibi.site/post/python-coroutine-1-yield/</guid><description>&lt;blockquote&gt;
&lt;p&gt;最近找到一本python好书《流畅的python》，是到现在为止看到的对python高级特性讲述最详细的一本。
看了协程一章，做个读书笔记，加深印象。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="协程定义"&gt;协程定义&lt;/h2&gt;
&lt;p&gt;协程的底层架构是在pep342 中定义，并在python2.5 实现的。&lt;/p&gt;
&lt;p&gt;HUGOMORE42&lt;/p&gt;
&lt;p&gt;python2.5 中，yield关键字可以在表达式中使用，而且生成器API中增加了 .send(value)方法。生成器可以使用.send(&amp;hellip;)方法发送数据，发送的数据会成为生成器函数中yield表达式的值。&lt;/p&gt;
&lt;p&gt;协程是指一个过程，这个过程与调用方协作，产出有调用方提供的值。因此，生成器可以作为协程使用。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;除了 .send(&amp;hellip;)方法，pep342 和添加了 .throw(&amp;hellip;)（让调用方抛出异常，在生成器中处理）和.close()（终止生成器）方法。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;python3.3后，pep380对生成器函数做了两处改动：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;生成器可以返回一个值；以前，如果生成器中给return语句提供值，会抛出SyntaxError异常。&lt;/li&gt;
&lt;li&gt;引入yield from 语法，使用它可以把复杂的生成器重构成小型的嵌套生成器，省去之前把生成器的工作委托给子生成器所需的大量模板代码。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="协程生成器的基本行为"&gt;协程生成器的基本行为&lt;/h2&gt;
&lt;p&gt;首先说明一下，协程有四个状态，可以使用inspect.getgeneratorstate(&amp;hellip;)函数确定：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GEN_CREATED # 等待开始执行&lt;/li&gt;
&lt;li&gt;GEN_RUNNING # 解释器正在执行（只有在多线程应用中才能看到这个状态）&lt;/li&gt;
&lt;li&gt;GEN_SUSPENDED # 在yield表达式处暂停&lt;/li&gt;
&lt;li&gt;GEN_CLOSED # 执行结束&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#! -*- coding: utf-8 -*-&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; inspect
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 协程使用生成器函数定义：定义体中有yield关键字。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;simple_coroutine&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;&amp;#39;-&amp;gt; coroutine started&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# yield 在表达式中使用；如果协程只需要从客户那里接收数据，yield关键字右边不需要加表达式（yield默认返回None）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;yield&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;&amp;#39;-&amp;gt; coroutine received:&amp;#39;&lt;/span&gt;, x)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;my_coro &lt;span style="color:#f92672"&gt;=&lt;/span&gt; simple_coroutine()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;my_coro &lt;span style="color:#75715e"&gt;# 和创建生成器的方式一样，调用函数得到生成器对象。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 协程处于 GEN_CREATED (等待开始状态)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;print(inspect&lt;span style="color:#f92672"&gt;.&lt;/span&gt;getgeneratorstate(my_coro))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;my_coro&lt;span style="color:#f92672"&gt;.&lt;/span&gt;send(&lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 首先要调用next()函数，因为生成器还没有启动，没有在yield语句处暂停，所以开始无法发送数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 发送 None 可以达到相同的效果 my_coro.send(None) &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;next(my_coro)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 此时协程处于 GEN_SUSPENDED (在yield表达式处暂停)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;print(inspect&lt;span style="color:#f92672"&gt;.&lt;/span&gt;getgeneratorstate(my_coro))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 调用这个方法后，协程定义体中的yield表达式会计算出42；现在协程会恢复，一直运行到下一个yield表达式，或者终止。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;my_coro&lt;span style="color:#f92672"&gt;.&lt;/span&gt;send(&lt;span style="color:#ae81ff"&gt;42&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;print(inspect&lt;span style="color:#f92672"&gt;.&lt;/span&gt;getgeneratorstate(my_coro))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;运行上述代码，输出结果如下&lt;/p&gt;</description></item><item><title>CSS入门指南-1：工作原理</title><link>https://blog.gusibi.site/post/css-learing-1-css-how-it-works/</link><pubDate>Sat, 27 May 2017 17:22:49 +0800</pubDate><guid>https://blog.gusibi.site/post/css-learing-1-css-how-it-works/</guid><description>&lt;blockquote&gt;
&lt;p&gt;这是CSS设计指南的读书笔记，用于加深学习效果。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;最近想做一个小程序，前端是必修课，那就从css开始吧。&lt;/p&gt;
&lt;h2 id="css-工作原理"&gt;css 工作原理&lt;/h2&gt;
&lt;p&gt;每个html元素都有一组样式属性，可以通过css来设定。当html元素的同一个样式属性有多种样式值的时候，css就要靠层叠机智来决定最终应用哪种样式。&lt;/p&gt;
&lt;p&gt;HUGOMORE42&lt;/p&gt;
&lt;h3 id="css规则"&gt;css规则&lt;/h3&gt;
&lt;p&gt;规则实际上是一条完整的css指令，规则声明了要修改的元素和要应用给改元素的样式。&lt;/p&gt;
&lt;h4 id="为文档添加样式的三种方法"&gt;为文档添加样式的三种方法：&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;写在元素标签里（也叫行内样式，只能影响它所在的标签，会覆盖嵌入样式和链接样式）&lt;/li&gt;
&lt;li&gt;写在&amp;lt;style&amp;gt; 标签里（也就嵌入样式，应用范围仅限于当前页面，页面样式会覆盖外部样式表中的样式，但会被行内样式覆盖）&lt;/li&gt;
&lt;li&gt;写在单独css样式表中（也叫链接样式，样式表是一个扩展名为.css 的文件，可以在任意多个HTML页面链接同一个样式表文件。链接样式的作用范围是整个网站）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;除了这三种为页面添加样式的方法，还有一种在样式表中链接其他样式表的方法，使用@import 指令：例如&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;@import url(css/styles.css)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;@import 指令必须出现在样式表中其他样式之前，否则@吹灭；@import引用的样式表不会被加载。
&lt;img alt="css 规则命名惯例" loading="lazy" src="http://omuo4kh1k.bkt.clouddn.com/cpByY2yOl7gHv6vEFDL2CyMt8YJQ-0t0MRxo6itjABg0PeYrrqz6wrIV6q5kKsm8"&gt;&lt;/p&gt;
&lt;p&gt;对这个基本的结构有三种方法可以进行扩展&lt;/p&gt;
&lt;p&gt;**第一种方法：**多个声明包含在一条规则里。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;p&lt;/span&gt; {&lt;span style="color:#66d9ef"&gt;color&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;red&lt;/span&gt;; &lt;span style="color:#66d9ef"&gt;font-size&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;; &lt;span style="color:#66d9ef"&gt;font-weight&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;bold&lt;/span&gt;;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;**第二种方法：**多个选择器组合在一起。例如：如果想让&amp;lt;h1&amp;gt;、&amp;lt;h2&amp;gt;和&amp;lt;h3&amp;gt;的文本都变成蓝色粗体可以这么写：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;h1&lt;/span&gt; {&lt;span style="color:#66d9ef"&gt;color&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;blue&lt;/span&gt;; &lt;span style="color:#66d9ef"&gt;font-weight&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;bold&lt;/span&gt;;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;h2&lt;/span&gt; {&lt;span style="color:#66d9ef"&gt;color&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;blue&lt;/span&gt;; &lt;span style="color:#66d9ef"&gt;font-weight&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;bold&lt;/span&gt;;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;h3&lt;/span&gt; {&lt;span style="color:#66d9ef"&gt;color&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;blue&lt;/span&gt;; &lt;span style="color:#66d9ef"&gt;font-weight&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;bold&lt;/span&gt;;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;也可以这么写：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;h1&lt;/span&gt;&lt;span style="color:#f92672"&gt;,&lt;/span&gt; &lt;span style="color:#f92672"&gt;h2&lt;/span&gt;&lt;span style="color:#f92672"&gt;,&lt;/span&gt; &lt;span style="color:#f92672"&gt;h3&lt;/span&gt; {&lt;span style="color:#66d9ef"&gt;color&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;blue&lt;/span&gt;; &lt;span style="color:#66d9ef"&gt;font-weight&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;bold&lt;/span&gt;;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;分组选择符以逗号作为分隔符&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第三种方法：&lt;/strong&gt; 多条规则应用给一个选择符。
例如，写完上边的规则，还想把h3变成斜体，那么可以再为h3单独写一条规则：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;h1&lt;/span&gt;&lt;span style="color:#f92672"&gt;,&lt;/span&gt; &lt;span style="color:#f92672"&gt;h2&lt;/span&gt;&lt;span style="color:#f92672"&gt;,&lt;/span&gt; &lt;span style="color:#f92672"&gt;h3&lt;/span&gt; {&lt;span style="color:#66d9ef"&gt;color&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;blue&lt;/span&gt;; &lt;span style="color:#66d9ef"&gt;font-weight&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;bold&lt;/span&gt;;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;h3&lt;/span&gt; {&lt;span style="color:#66d9ef"&gt;font-style&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;italic&lt;/span&gt;;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="选择特定元素的选择符"&gt;选择特定元素的选择符&lt;/h3&gt;
&lt;p&gt;用于选择特定元素的操作符有三种&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;上下文选择符&lt;/strong&gt;。基于祖先或者同胞元素选择一个元素。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ID和类选择符&lt;/strong&gt;。基于id和class属性的值选择元素。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;属性选择符&lt;/strong&gt;。基于属性的有无和特征选择元素。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id="上下文选择符"&gt;上下文选择符&lt;/h4&gt;
&lt;p&gt;比如我们想给article中的段落设置不同的字号，可以使用上下文选择符来解决。&lt;/p&gt;
&lt;p&gt;上下文选择符的格式如下：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;标签1 标签2 {声明}&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;其中&lt;strong&gt;标签2&lt;/strong&gt; 是我们要选择的目标，而且只有在 &lt;strong&gt;标签1&lt;/strong&gt;是其祖先元素的情况下才会被选中。&lt;/p&gt;
&lt;p&gt;上下文选择符，叫后代组合式选择符，就是一组以空格分隔的标签名。用于选择作为特定祖先元素后代的标签。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;article&lt;/span&gt; &lt;span style="color:#f92672"&gt;p&lt;/span&gt; {&lt;span style="color:#66d9ef"&gt;font-weight&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;bold&lt;/span&gt;;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上边例子中，只有article后代的p元素才会应用后边的样式。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;上下文选择符以空格作为分隔符&lt;/strong&gt;&lt;/p&gt;
&lt;h5 id="特殊的上下文选择符"&gt;特殊的上下文选择符&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;子选择符 &amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;格式如下：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;标签1 &amp;gt; 标签2&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;标签1&lt;/strong&gt; 必须是 &lt;strong&gt;标签2&lt;/strong&gt; 的&lt;strong&gt;父元素&lt;/strong&gt;，不能是其它的祖先元素。&lt;/p&gt;</description></item><item><title>跟着代码学go 002 -- 控制流</title><link>https://blog.gusibi.site/post/golang-learning-by-code-002/</link><pubDate>Tue, 26 Apr 2016 15:49:35 +0800</pubDate><guid>https://blog.gusibi.site/post/golang-learning-by-code-002/</guid><description>跟着代码学golang 控制流</description></item><item><title>跟着代码学go 001 -- 变量&amp;函数</title><link>https://blog.gusibi.site/post/golang-learning-by-code-001/</link><pubDate>Mon, 25 Apr 2016 14:53:47 +0800</pubDate><guid>https://blog.gusibi.site/post/golang-learning-by-code-001/</guid><description>跟着代码学golang 变量 函数 基本数据结构</description></item><item><title>golang 介绍</title><link>https://blog.gusibi.site/post/golang-description/</link><pubDate>Thu, 14 Apr 2016 22:44:40 +0800</pubDate><guid>https://blog.gusibi.site/post/golang-description/</guid><description>&lt;h2 id="1-golang-是什么"&gt;1. Golang 是什么&lt;/h2&gt;
&lt;p&gt;Go 官方说明：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Go 编程语言是一个使得程序员更加有效率的开源项目。Go 是有表达力、简 洁、清晰和有效率的。它的并行机制使其很容易编写多核和网络应用,而新的类型系统允许构建有 性的模块化程序。Go 编译到机器码非常快 速,同时具有便利的垃圾回收和强大的运行时反射。它是快速的、静态类 型编译语言,但是感觉上是动态类型的,解释型语言&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;HUGOMORE42&lt;/p&gt;
&lt;h2 id="2-为什么要开发这个语言"&gt;2. 为什么要开发这个语言&lt;/h2&gt;
&lt;h3 id="go-语言的发展目标"&gt;Go 语言的发展目标&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Go 语言的主要目标是将静态语言的安全性和高效性与动态语言的易开发性进行有机结合&lt;/li&gt;
&lt;li&gt;Go 语言是一门类型安全和内存安全的编程语言。虽然 Go 语言中仍有指针的存在，但并不允许进行指针运算。&lt;/li&gt;
&lt;li&gt;Go 语言的另一个目标是对于网络通信、并发和并行编程的极佳支持，从而更好地利用大量的分布式和多核的计算机&lt;/li&gt;
&lt;li&gt;Go 语言中另一个非常重要的特性就是它的构建速度（编译和链接到机器代码的速度），一般情况下构建一个程序的时间只需要数百毫秒到几秒。&lt;/li&gt;
&lt;li&gt;Go 语言实现高效快速的垃圾回收（使用了一个简单的标记-清除算法）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="3-有什么特性用途"&gt;3. 有什么特性&amp;amp;&amp;amp;用途&lt;/h2&gt;
&lt;h3 id="语言的特性"&gt;语言的特性&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;清晰并且简洁&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Go 努力保持小并且优美,你可以在短短几行代码里做许多事情;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;并行&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Go 语言从本质上（程序和结构方面）来实现并发编程。
Go 让函数很容易成为非常轻量的线程。这些线程在 Go 中被叫做 goroutines&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Channel&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;这些 goroutines 之间的通讯由 channel[18, 25] 完成&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;快速&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;编译很快,执行也很快。目标是跟 C 一样快。编译时间用秒计算;
Go 的可执行文件都比相对应的源代码文件要大很多，这恰恰说明了 Go 的 runtime 嵌入到了每一个可执行文件当中。当然，在部署到数量巨大的集群时，较大的文件体积也是比较头疼的问题。但总得来说，Go 的部署工作还是要比 Java 和 Python 轻松得多。因为 Go 不需要依赖任何其它文件，它只需要一个单独的静态文件，这样你也不会像使用其它语言一样在各种不同版本的依赖文件之间混淆。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;安全&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;当转换一个类型到另一个类型的时候需要显式的转换并遵循严格的规则。Go 有 垃圾收集（使用了一个简单的标记-清除算法）,在 Go 中无须 free(),语言会处理这一切;
值得注意的是，因为垃圾回收和自动内存分配的原因，Go 语言不适合用来开发对实时性要求很高的软件。&lt;/p&gt;</description></item></channel></rss>