<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>songroger</title>
    <description>Hi there, My name is Luozhan.Song, usually I use &quot;songroger&quot; as my ID everywhere. I was born and raised in Hunan China.  I&apos;m really fond of beautiful design, drawing etc.
</description>
    <link>http://songroger.win/</link>
    <atom:link href="http://songroger.win/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Mon, 10 Mar 2025 09:17:56 +0000</pubDate>
    <lastBuildDate>Mon, 10 Mar 2025 09:17:56 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>docx cracked experience</title>
        <description>&lt;p&gt;1.Hash file&lt;/p&gt;

&lt;p&gt;Use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;john&lt;/code&gt;&lt;sup id=&quot;fnref:footnote1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:footnote1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; to get the hash file.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python john.py 2020.docx &amp;gt;hash.txt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;2.Hashcat&lt;sup id=&quot;fnref:footnote2&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:footnote2&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; to crack the password&lt;/p&gt;

&lt;p&gt;Example commands for hashcat:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hashcat -a 3 -m 9400 --username -o cracked_pass.txt 111.txt song?d?d?d --force --self-test-disable&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hashcat -a 0 -m 9400 rockyou.txt 111.txt --username -o cracked_pass.txt --force --self-test-disable&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hashcat -a 3 -m 9600 hash.txt test.hcmask --username -o cracked_pass.txt --force --self-test-disable&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:footnote1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;/img/john.py&quot;&gt;john&lt;/a&gt; &lt;a href=&quot;#fnref:footnote1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:footnote2&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://github.com/hashcat/hashcat&quot;&gt;hashcat&lt;/a&gt; &lt;a href=&quot;#fnref:footnote2&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Mon, 07 Sep 2020 20:20:39 +0000</pubDate>
        <link>http://songroger.win/office-password-recovery/</link>
        <guid isPermaLink="true">http://songroger.win/office-password-recovery/</guid>
        
        
            <category>code</category>
        
      </item>
    
      <item>
        <title>自动编曲软件可以做到什么程度了</title>
        <description>&lt;p&gt;最近把我的老伙计(ipad)修好了，亲切而又陌生之余，发现里面有款宝藏APP-「music-memos」.&lt;/p&gt;

&lt;p&gt;表面看这是一个录音软件，其实它应该是轻量级的自动配伴奏APP，每个录音文件下面有个吉他和架子鼓的logo，点一下，神奇的事情就发生了。&lt;/p&gt;

&lt;p&gt;所以，看我ipad里面的录音文件记录，我应该是16年开始就在玩自动编曲软件了，可是我像失忆了似的，完全不记得录了那么多…囧.&lt;/p&gt;

&lt;p&gt;于是像发现了新大陆似的，找了一圈相关的软件，全部装上研究了一遍，最后完成了《少年》这首成品。没错，这首抖音爆款 BGM 就是我的第一首用了整个标配乐队阵容（鼓、贝斯、吉他、键盘）的作品了。（—笑—）&lt;/p&gt;

&lt;p&gt;里面的和弦编排全部是由软件根据录入的钢琴旋律自动排出来的，确定调号和节拍速度即可。&lt;/p&gt;

&lt;h5 id=&quot;附一张工作界面图&quot;&gt;附一张工作界面图：&lt;/h5&gt;
&lt;p&gt;&lt;img src=&quot;/img/ai-music.png&quot; alt=&quot;p1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;去年在二叉树上看到彩虹合唱团万源说的那句“音乐是理性的艺术”，我深以为然。&lt;/p&gt;

&lt;p&gt;自动编曲软件的原理其实很简单，识别音乐文件的频率对应上固定音名，然后根据和弦编排乐理，根据一些算法生成一系列和弦编排。如果做得更智能的话，可以结合AI训练一些常用和弦走向，应该可以拿下市面上大部分流行歌曲的「完美」编配了。或者再结合训练一些古典经典作品，那就更高级了吧。&lt;/p&gt;

&lt;p&gt;最后再秉承本人一贯「科学严谨」求索的态度回答一下标题疑问吧。&lt;/p&gt;

&lt;p&gt;对于乐理知识有一定修为的，自动编曲软件可以帮你构思整首曲子和弦架构的大部分工作，至少能给你一个相对完整的参考。
对于不太了解乐理的人来说，自动编曲软件可以帮你把自己的录音自动合成一个带有伴奏版本的成品曲子。&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;来，我们一起唱爆款神曲~ 
愿你出走半生，归来仍是少年

我还是从前那个少年
没有一丝丝改变
时间只不过是考验
种在心中信念丝毫未减
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Mon, 06 Apr 2020 09:20:39 +0000</pubDate>
        <link>http://songroger.win/ai-music/</link>
        <guid isPermaLink="true">http://songroger.win/ai-music/</guid>
        
        
            <category>diary</category>
        
      </item>
    
      <item>
        <title>别「惹」学霸</title>
        <description>&lt;p&gt;前段时间因帮忙了一位朋友，一直说要请我吃饭。
今日刚好得闲，下午临时发了信息给她。
她爽快地答应跑过来，生怕耽误还我一顿饭似的。&lt;/p&gt;

&lt;p&gt;可是在等她过来的时间中，我查了半天附近饭馆，突然什么胃口都没有。
我心想这下可不好，于是灵机一动，跟她说我想喝「鲫鱼汤」&lt;sup id=&quot;fnref:footnote1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:footnote1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;，这附近可能暂时不好找，要不我们去瑞幸找点喝的算了，算是蹭个最近的热点吧&lt;sup id=&quot;fnref:footnote2&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:footnote2&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;

&lt;p&gt;她迟疑了一下，可能觉得对不起她跑过来这趟，竟然说“就请你喝鲫鱼汤，我自己做”。
这倒出乎我意料，可是更让我没想到的是，她补充说以前从没做过，我可能是第一个吃她煮的鱼的人…&lt;/p&gt;

&lt;p&gt;我开始有点担心，可是又没法不识好歹地自己再作回去…&lt;/p&gt;

&lt;p&gt;我们径直去了菜市场买食材，一路上她都在拿着手机各种百度。
看她迷糊的样子，我才完全相信，眼前这位大小姐真的从来没有煮过鱼，可能其他菜也没做过！
在追问中得知，她从小到大下厨的经验可能仅限于「泡面」。
我已经完全没了期待，告诉自己好好享受别人做饭的乐趣吧，饭后不是可以给没胃口的自己一个很好的「理由」了不是？&lt;/p&gt;

&lt;p&gt;直到这位同学，从我锅里倒出题图这一碗「茼蒿豆腐鲫鱼汤」，我有点惊了&lt;sup id=&quot;fnref:footnote3&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:footnote3&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;

&lt;p&gt;奶白色的汤，真是神奇的存在，相机拍不出半分它的鲜、甜来。&lt;/p&gt;

&lt;p&gt;我只想说，别惹学霸，那种学什么都可以称霸的孩子！&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:footnote1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;随便想的一个饭馆不好找的菜罢了。 &lt;a href=&quot;#fnref:footnote1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:footnote2&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;瑞幸自查报告公布销售额造假22亿，股价暴跌门店爆单。 &lt;a href=&quot;#fnref:footnote2&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:footnote3&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;你能想象，没胃口的我最后喝了半锅汤，下了三大碗米饭？！ &lt;a href=&quot;#fnref:footnote3&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Sat, 04 Apr 2020 13:50:39 +0000</pubDate>
        <link>http://songroger.win/first-fish/</link>
        <guid isPermaLink="true">http://songroger.win/first-fish/</guid>
        
            <category>recommend</category>
        
        
            <category>diary</category>
        
      </item>
    
      <item>
        <title>奇技淫巧系列</title>
        <description>&lt;p&gt;前言：&lt;/p&gt;

&lt;p&gt;这篇主要记录本人碰到的一些奇怪的软硬件问题以及解决方式。可能不是所有人通用的，但是肯定是我自己验证过并且获得解决的才会记录在此。&lt;/p&gt;

&lt;h4 id=&quot;1-电脑自动输入反斜杠&quot;&gt;1. 电脑自动输入反斜杠。&lt;/h4&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;现象：电脑一开机就任何输入框都自动输入反斜杠。非键盘坏。
最终确认： .NET Framework的问题
解决：禁用.NET Framework服务
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Tue, 24 Mar 2020 14:09:39 +0000</pubDate>
        <link>http://songroger.win/fanta-issue/</link>
        <guid isPermaLink="true">http://songroger.win/fanta-issue/</guid>
        
        
            <category>code</category>
        
      </item>
    
      <item>
        <title>Understand Flask (一)</title>
        <description>&lt;div class=&quot;post-text&quot; itemprop=&quot;text&quot;&gt;
&lt;p&gt;Previous answers already give a nice overview of what goes on in the background of Flask during a request. If you haven&apos;t read it yet I recommend @MarkHildreth&apos;s answer prior to reading this. In short, a new context (thread) is created for each http request, which is why it&apos;s necessary to have a thread &lt;code&gt;Local&lt;/code&gt; facility that allows objects such as &lt;code&gt;request&lt;/code&gt; and &lt;code&gt;g&lt;/code&gt; to be accessible globally across threads, while maintaining their request specific context. Furthermore, while processing an http request Flask can emulate additional requests from within, hence the necessity to store their respective context on a stack. Also, Flask allows multiple wsgi applications to run along each other within a single process, and more than one can be called to action  during a request (each request creates a new application context), hence the need for a context stack for applications. That&apos;s a summary of what was covered in previous answers.&lt;/p&gt;

&lt;p&gt;My goal now is to complement our current understanding by explaining &lt;em&gt;how&lt;/em&gt; Flask and Werkzeug do what they do with these context locals. I simplified the code to enhance the understanding of its logic, but if you get this, you should be able to easily grasp most of what&apos;s in the actual source (&lt;code&gt;werkzeug.local&lt;/code&gt; and &lt;code&gt;flask.globals&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Let&apos;s first understand how Werkzeug implements thread Locals. &lt;/p&gt;

&lt;h1&gt;Local&lt;/h1&gt;

&lt;p&gt;When an http request comes in, it is processed within the context of a single thread. As an alternative mean to spawn a new context during an http request, Werkzeug also allows the use of greenlets (a sort of lighter &quot;micro-threads&quot;) instead of normal threads. If you don&apos;t have greenlets installed it will revert to using threads instead. Each of these threads (or greenlets) are identifiable by a unique id, which you can retrieve with the module&apos;s &lt;code&gt;get_ident()&lt;/code&gt; function. That function is the starting point to the magic behind having &lt;code&gt;request&lt;/code&gt;, &lt;code&gt;current_app&lt;/code&gt;,&lt;code&gt;url_for&lt;/code&gt;, &lt;code&gt;g&lt;/code&gt;, and other such context-bound global objects.&lt;/p&gt;

&lt;pre class=&quot;lang-py prettyprint prettyprinted&quot; style=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;kwd&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; greenlet &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; get_ident
&lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;except&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;ImportError&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; thread &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; get_ident&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now that we have our identity function we can know which thread we&apos;re on at any given time and we can create what&apos;s called a thread &lt;code&gt;Local&lt;/code&gt;, a contextual object that can be accessed globally, but when you access its attributes they resolve to their value for that specific thread.
e.g.&lt;/p&gt;

&lt;pre class=&quot;lang-py prettyprint prettyprinted&quot; style=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;com&quot;&gt;# globally&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
local &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;Local&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# ...&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# on thread 1&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
local&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;first_name &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;str&quot;&gt;&apos;John&apos;&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# ...&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# on thread 2&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
local&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;first_name &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;str&quot;&gt;&apos;Debbie&apos;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Both values are present on the globally accessible &lt;code&gt;Local&lt;/code&gt; object at the same time, but accessing &lt;code&gt;local.first_name&lt;/code&gt; within the context of thread 1 will give you &lt;code&gt;&apos;John&apos;&lt;/code&gt;, whereas it will return &lt;code&gt;&apos;Debbie&apos;&lt;/code&gt; on thread 2.&lt;/p&gt;

&lt;p&gt;How is that possible? Let&apos;s look at some (simplified) code:&lt;/p&gt;

&lt;pre class=&quot;lang-py prettyprint prettyprinted&quot; style=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;kwd&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;Local&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; __init__&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;storage &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;{}&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; __getattr__&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; name&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        context_id &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; get_ident&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# we get the current thread&apos;s or greenlet&apos;s id&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        contextual_storage &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;storage&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;setdefault&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;context_id&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;{})&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; contextual_storage&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;except&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;KeyError&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;raise&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;AttributeError&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; __setattr__&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; name&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; value&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        context_id &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; get_ident&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        contextual_storage &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;storage&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;setdefault&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;context_id&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;{})&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        contextual_storage&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; value

    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; __release_local__&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        context_id &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; get_ident&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;storage&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;context_id&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

local &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;Local&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;From the code above we can see that the magic boils down to &lt;code&gt;get_ident()&lt;/code&gt; which identifies the current greenlet or thread. The &lt;code&gt;Local&lt;/code&gt; storage then just uses that as a key to store any data contextual to the current thread.&lt;/p&gt;

&lt;p&gt;You can have multiple &lt;code&gt;Local&lt;/code&gt; objects per process and &lt;code&gt;request&lt;/code&gt;, &lt;code&gt;g&lt;/code&gt;, &lt;code&gt;current_app&lt;/code&gt; and others could simply have been created like that. But that&apos;s not how it&apos;s done in Flask in which these are not &lt;em&gt;technically&lt;/em&gt; &lt;code&gt;Local&lt;/code&gt; objects, but more accurately &lt;code&gt;LocalProxy&lt;/code&gt; objects. What&apos;s a &lt;code&gt;LocalProxy&lt;/code&gt;? &lt;/p&gt;

&lt;h1&gt;LocalProxy&lt;/h1&gt;

&lt;p&gt;A LocalProxy is an object that queries a &lt;code&gt;Local&lt;/code&gt; to find another object of interest (i.e. the object it proxies to). Let&apos;s take a look to understand:&lt;/p&gt;

&lt;pre class=&quot;lang-py prettyprint prettyprinted&quot; style=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;kwd&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;LocalProxy&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; __init__&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; local&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; name&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# `local` here is either an actual `Local` object, that can be used&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# to find the object of interest, here identified by `name`, or it&apos;s&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# a callable that can resolve to that proxied object&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;local &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; local
        &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# `name` is an identifier that will be passed to the local to find the&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# object of interest.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;name &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; name

    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; _get_current_object&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# if `self.local` is truly a `Local` it means that it implements&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# the `__release_local__()` method which, as its name implies, is&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# normally used to release the local. We simply look for it here&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# to identify which is actually a Local and which is rather just&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# a callable:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; hasattr&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;str&quot;&gt;&apos;__release_local__&apos;&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; getattr&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;except&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;AttributeError&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;raise&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;RuntimeError&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;str&quot;&gt;&apos;no object bound to %s&apos;&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

        &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# if self.local is not actually a Local it must be a callable that &lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# would resolve to the object of interest.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# Now for the LocalProxy to perform its intended duties i.e. proxying &lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# to an underlying object located somewhere in a Local, we turn all magic&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# methods into proxies for the same methods in the object of interest.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;lit&quot;&gt;@property&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; __dict__&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;_get_current_object&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;__dict__
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;except&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;RuntimeError&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;raise&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;AttributeError&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;str&quot;&gt;&apos;__dict__&apos;&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; __repr__&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; repr&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;_get_current_object&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;())&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;except&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;RuntimeError&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;str&quot;&gt;&apos;&amp;lt;%s unbound&amp;gt;&apos;&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;__class__&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;__name__

    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; __bool__&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; bool&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;_get_current_object&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;())&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;except&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;RuntimeError&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# ... etc etc ... &lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; __getattr__&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; name&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; name &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;str&quot;&gt;&apos;__members__&apos;&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; dir&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;_get_current_object&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;())&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; getattr&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;_get_current_object&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(),&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; name&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; __setitem__&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; key&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; value&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;_get_current_object&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;()[&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; value

    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; __delitem__&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; key&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;del&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;_get_current_object&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;()[&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# ... and so on ...&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

    __setattr__ &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;lambda&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; x&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; n&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; v&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; setattr&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;_get_current_object&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(),&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; n&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; v&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
    __delattr__ &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;lambda&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; x&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; n&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; delattr&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;_get_current_object&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(),&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; n&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
    __str__ &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;lambda&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; x&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; str&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;_get_current_object&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;())&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
    __lt__ &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;lambda&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; x&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; o&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; x&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;_get_current_object&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; o
    __le__ &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;lambda&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; x&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; o&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; x&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;_get_current_object&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; o
    __eq__ &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;lambda&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; x&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; o&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; x&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;_get_current_object&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; o

    &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# ... and so forth ...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now to create globally accessible proxies you would do &lt;/p&gt;

&lt;pre class=&quot;lang-py prettyprint prettyprinted&quot; style=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;com&quot;&gt;# this would happen some time near application start-up&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
local &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;Local&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
request &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;LocalProxy&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;str&quot;&gt;&apos;request&apos;&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
g &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;LocalProxy&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;str&quot;&gt;&apos;g&apos;&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and now some time early over the course of a request you would store some objects inside the local that the previously created proxies can access, no matter which thread we&apos;re on&lt;/p&gt;

&lt;pre class=&quot;lang-py prettyprint prettyprinted&quot; style=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;com&quot;&gt;# this would happen early during processing of an http request&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
local&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;request &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;RequestContext&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;http_environment&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
local&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;g &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;SomeGeneralPurposeContainer&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The advantage of using &lt;code&gt;LocalProxy&lt;/code&gt; as globally accessible objects rather than making them &lt;code&gt;Locals&lt;/code&gt; themselves is that it simplifies their management. You only just need a single &lt;code&gt;Local&lt;/code&gt; object to create many globally accessible proxies. At the end of the request, during cleanup, you simply release the one &lt;code&gt;Local&lt;/code&gt; (i.e. you pop the context_id from its storage) and don&apos;t bother with the proxies, they&apos;re still globally accessible and still defer to the one &lt;code&gt;Local&lt;/code&gt; to find their object of interest for subsequent http requests.&lt;/p&gt;

&lt;pre class=&quot;lang-py prettyprint prettyprinted&quot; style=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;com&quot;&gt;# this would happen some time near the end of request processing&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
release&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# aka local.__release_local__()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To simplify the creation of a &lt;code&gt;LocalProxy&lt;/code&gt; when we already have a &lt;code&gt;Local&lt;/code&gt;, Werkzeug implements the &lt;code&gt;Local.__call__()&lt;/code&gt; magic method as follows:&lt;/p&gt;

&lt;pre class=&quot;lang-py prettyprint prettyprinted&quot; style=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;kwd&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;Local&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# ... &lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# ... all same stuff as before go here ...&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# ... &lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; __call__&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; name&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;LocalProxy&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; name&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# now you can do&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
local &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;Local&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
request &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; local&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;str&quot;&gt;&apos;request&apos;&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
g &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; local&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;str&quot;&gt;&apos;g&apos;&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;However, if you look in the Flask source (flask.globals) that&apos;s still not how &lt;code&gt;request&lt;/code&gt;, &lt;code&gt;g&lt;/code&gt;, &lt;code&gt;current_app&lt;/code&gt; and &lt;code&gt;session&lt;/code&gt; are created. As we&apos;ve established, Flask can spawn multiple &quot;fake&quot; requests (from a single true http request) and in the process also push multiple application contexts. This isn&apos;t a common use-case, but it&apos;s a capability of the framework. Since these &quot;concurrent&quot; requests and apps are still limited to run with only one having the &quot;focus&quot; at any time, it makes sense to use a stack for their respective context. Whenever a new request is spawned or one of the applications is called, they push their context at the top of their respective stack. Flask uses &lt;code&gt;LocalStack&lt;/code&gt; objects for this purpose. When they conclude their business they pop the context out of the stack.&lt;/p&gt;

&lt;h1&gt;LocalStack&lt;/h1&gt;

&lt;p&gt;This is what a &lt;code&gt;LocalStack&lt;/code&gt; looks like (again the code is simplified to facilitate understanding of its logic).&lt;/p&gt;

&lt;pre class=&quot;lang-py prettyprint prettyprinted&quot; style=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;kwd&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;LocalStack&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; __init__&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;local &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;Local&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; push&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; obj&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;str&quot;&gt;&quot;&quot;&quot;Pushes a new item to the stack&quot;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        rv &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; getattr&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;str&quot;&gt;&apos;stack&apos;&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; rv &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;is&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
            self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;stack &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; rv &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        rv&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; rv

    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; pop&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;str&quot;&gt;&quot;&quot;&quot;Removes the topmost item from the stack, will return the
        old value or `None` if the stack was already empty.
        &quot;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        stack &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; getattr&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;str&quot;&gt;&apos;stack&apos;&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; stack &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;is&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;elif&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; len&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;stack&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;lit&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
            release_local&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# this simply releases the local&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; stack&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;[-&lt;/span&gt;&lt;span class=&quot;lit&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; stack&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;lit&quot;&gt;@property&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; top&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;str&quot;&gt;&quot;&quot;&quot;The topmost item on the stack.  If the stack is empty,
        `None` is returned.
        &quot;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;stack&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;[-&lt;/span&gt;&lt;span class=&quot;lit&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;except&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;AttributeError&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;IndexError&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;None&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note from the above that a &lt;code&gt;LocalStack&lt;/code&gt; is a stack stored in a local, not a bunch of locals stored on a stack. This implies that although the stack is globally accessible it&apos;s a different stack in each thread.&lt;/p&gt;

&lt;p&gt;Flask doesn&apos;t have its &lt;code&gt;request&lt;/code&gt;, &lt;code&gt;current_app&lt;/code&gt;, &lt;code&gt;g&lt;/code&gt;, and &lt;code&gt;session&lt;/code&gt; objects resolving directly to a &lt;code&gt;LocalStack&lt;/code&gt;, it rather uses &lt;code&gt;LocalProxy&lt;/code&gt; objects that wrap a lookup function (instead of a &lt;code&gt;Local&lt;/code&gt; object) that will find the underlying object from the &lt;code&gt;LocalStack&lt;/code&gt;:&lt;/p&gt;

&lt;pre class=&quot;lang-py prettyprint prettyprinted&quot; style=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;pln&quot;&gt;_request_ctx_stack &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;LocalStack&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; _find_request&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;():&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
    top &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; _request_ctx_stack&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;top
    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; top &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;is&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;raise&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;RuntimeError&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;str&quot;&gt;&apos;working outside of request context&apos;&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; top&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;request
request &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;LocalProxy&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;_find_request&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; _find_session&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;():&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
    top &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; _request_ctx_stack&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;top
    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; top &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;is&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;raise&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;RuntimeError&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;str&quot;&gt;&apos;working outside of request context&apos;&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; top&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;session
session &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;LocalProxy&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;_find_session&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

_app_ctx_stack &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;LocalStack&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; _find_g&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;():&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
    top &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; _app_ctx_stack&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;top
    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; top &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;is&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;raise&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;RuntimeError&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;str&quot;&gt;&apos;working outside of application context&apos;&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; top&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;g
g &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;LocalProxy&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;_find_g&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; _find_app&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;():&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
    top &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; _app_ctx_stack&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;top
    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; top &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;is&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;raise&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;RuntimeError&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;str&quot;&gt;&apos;working outside of application context&apos;&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; top&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;app
current_app &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;LocalProxy&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;_find_app&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;All these are declared at application start-up, but do not actually resolve to anything until a request context or application context is pushed to their respective stack.&lt;/p&gt;

&lt;p&gt;If you&apos;re curious to see how a context is actually inserted in the stack (and subsequently popped out), look in &lt;code&gt;flask.app.Flask.wsgi_app()&lt;/code&gt; which is the point of entry of the wsgi app (i.e. what the web server calls and pass the http environment to when a request comes in), and follow the creation of the &lt;code&gt;RequestContext&lt;/code&gt; object all through its subsequent &lt;code&gt;push()&lt;/code&gt; into &lt;code&gt;_request_ctx_stack&lt;/code&gt;. Once pushed at the top of the stack, it&apos;s accessible via &lt;code&gt;_request_ctx_stack.top&lt;/code&gt;. Here&apos;s some abbreviated code to demonstrate the flow:&lt;/p&gt;

&lt;p&gt;So you start an app and make it available to the WSGI server...&lt;/p&gt;

&lt;pre class=&quot;lang-py prettyprint prettyprinted&quot; style=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;pln&quot;&gt;app &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;Flask&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(*&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;kwconfig&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# ...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Later an http request comes in and the WSGI server calls the app with the usual params...&lt;/p&gt;

&lt;pre class=&quot;lang-py prettyprint prettyprinted&quot; style=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;pln&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;environ&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; start_response&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# aka app.__call__(environ, start_response)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is roughly what happens in the app...&lt;/p&gt;

&lt;pre class=&quot;lang-py prettyprint prettyprinted&quot; style=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;kwd&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;Flask&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# ...&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; __call__&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; environ&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; start_response&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;wsgi_app&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;environ&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; start_response&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; wsgi_app&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; environ&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; start_response&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        ctx &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;RequestContext&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; environ&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        ctx&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# process the request here&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# raise error if any&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# return Response&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;finally&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
            ctx&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;com&quot;&gt;# ...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and this is roughly what happens with RequestContext...&lt;/p&gt;

&lt;pre class=&quot;lang-py prettyprint prettyprinted&quot; style=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;kwd&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;typ&quot;&gt;RequestContext&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; __init__&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; app&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; environ&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; request&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;app &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; app
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; request &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;is&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
            request &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; app&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;request_class&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;environ&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;request &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; request
        self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;url_adapter &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; app&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;create_url_adapter&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;session &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;open_session&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;session &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;is&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
            self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;session &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;make_null_session&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;flashes &lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; push&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        _request_ctx_stack&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;kwd&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt; pop&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;
        _request_ctx_stack&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pln&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;pun&quot;&gt;()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Say a request has finished initializing, the lookup for &lt;code&gt;request.path&lt;/code&gt; from one of your view functions would therefore go as follow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;start from the globally accessible &lt;code&gt;LocalProxy&lt;/code&gt; object &lt;code&gt;request&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;to find its underlying object of interest (the object it&apos;s proxying to) it calls its lookup function &lt;code&gt;_find_request()&lt;/code&gt; (the function it registered as its &lt;code&gt;self.local&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;that function queries the &lt;code&gt;LocalStack&lt;/code&gt; object &lt;code&gt;_request_ctx_stack&lt;/code&gt; for the top context on the stack.&lt;/li&gt;
&lt;li&gt;to find the top context, the &lt;code&gt;LocalStack&lt;/code&gt; object first queries its inner &lt;code&gt;Local&lt;/code&gt; attribute (&lt;code&gt;self.local&lt;/code&gt;) for the &lt;code&gt;stack&lt;/code&gt; property that was previously stored there.&lt;/li&gt;
&lt;li&gt;from the &lt;code&gt;stack&lt;/code&gt; it gets the top context&lt;/li&gt;
&lt;li&gt;and &lt;code&gt;top.request&lt;/code&gt; is thus resolved as the underlying object of interest.&lt;/li&gt;
&lt;li&gt;from that object we get the &lt;code&gt;path&lt;/code&gt; attribute&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So we&apos;ve seen how &lt;code&gt;Local&lt;/code&gt;, &lt;code&gt;LocalProxy&lt;/code&gt;, and &lt;code&gt;LocalStack&lt;/code&gt; work, now think for a moment of the implications and nuances in retrieving the &lt;code&gt;path&lt;/code&gt; from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a &lt;code&gt;request&lt;/code&gt; object that would be a simple globally accessible object.&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;request&lt;/code&gt; object that would be a local.&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;request&lt;/code&gt; object stored as an attribute of a local.&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;request&lt;/code&gt; object that is a proxy to an object stored in a local.&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;request&lt;/code&gt; object stored on a stack, that is in turn stored in a local.&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;request&lt;/code&gt; object that is a proxy to an object on a stack stored in a local. &amp;lt;- this is what Flask does.&lt;/li&gt;
&lt;/ul&gt;
    &lt;/div&gt;
</description>
        <pubDate>Sat, 10 Aug 2019 09:15:39 +0000</pubDate>
        <link>http://songroger.win/understand-flask-s1/</link>
        <guid isPermaLink="true">http://songroger.win/understand-flask-s1/</guid>
        
            <category>recommend</category>
        
        
            <category>code</category>
        
      </item>
    
      <item>
        <title>一点笔记</title>
        <description>&lt;p&gt;又一年了。&lt;br /&gt;
一直想写2018，但是每有提笔的冲动都又放下了。&lt;br /&gt;
没有太多的波澜，但也并不宁静。&lt;br /&gt;
在这个本该奋斗的年纪，总觉得缺一番惊天动地。&lt;br /&gt;
特别是前段时间看到云舒与妻子离婚，放下家庭全力投入创业的举措，再次激起本就迷茫的自己去思考人生的意义。&lt;/p&gt;

&lt;p&gt;亲情、友情、爱情。&lt;/p&gt;

&lt;p&gt;相对不变的一直是亲情，只希望家人健康，生活平凡而喜乐。&lt;br /&gt;
而友情和爱情，在我心中同样重要的两部分，从没让我省心过。&lt;br /&gt;
甚至都在强行怪自己打字的时候，为什么不在中文和英文之间加空格呢？！&lt;sup id=&quot;fnref:note1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:note1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;年前，在相识十多年的好基友家玩了几天。两个男人，每每聊到凌晨，提及这些年来发生的事情，不亚于《人在囧途》的各种百态。&lt;br /&gt;
总的来说，&lt;br /&gt;
失去了一些人，也得到了新伙伴。&lt;br /&gt;
以为会没那么快失散的，却也提前消失在了人海。&lt;/p&gt;

&lt;p&gt;更早的三年，和计划结婚的女友分手，最后一次旅行定格在澳门威尼斯人，我们还在一起牵手憧憬未来，可笑的是几个月后因为家里的原因分手了。我很长的一段时间内一直非常非常努力的工作，再也不想触及爱情。&lt;br /&gt;
好在时间真是个好东西，心受伤了也只是恢复得慢一点。&lt;br /&gt;
直到我渐渐想通一些事情，开始走出来这份悲观了。「现在倒在想，又想要贴心的基友，又想要甜甜的女票，是不是太贪心了点？！」&lt;/p&gt;

&lt;p&gt;深交过的人，都说我很文艺。但我倒不觉得，我只是享受我没经历过的一切，喜欢折腾艺文的东西，也刚好可能略有天赋。  人生总归要回归柴米油盐的生活的，这些精神食粮只是会冲淡我的一些物质欲，这样挺好。&lt;/p&gt;

&lt;p&gt;在和好哥们的夜聊中说到，最不能接受他们（某些大学同学）的就是甘于平庸。他们的生活似乎接受了被父母操控着，被安排进国局、去接替、只选公职，总之即使拿着再多的灰色收入，也只每天搪瓷缸子人民日报的日子。&lt;br /&gt;
而我们，靠自己去奋斗，反而是真正的在“享受”生活了。 用他的话说，我们这是回到平凡，而不是始终平庸。 当然，个中心酸，也只容我们这么愤青了。&lt;/p&gt;

&lt;p&gt;也奢望2018这一年的遗憾都可以成为2019惊喜的铺垫。&lt;/p&gt;

&lt;p&gt;“在路上”的感觉也许应该就是这样的吧～&lt;/p&gt;

&lt;p&gt;最后推一下最近在看的毛姆的小说《月亮与六便士》。&lt;br /&gt;
选择月亮还是六便士？&lt;br /&gt;
哪一种值得敬畏，哪一种该被怜悯？&lt;br /&gt;
这是一个问题。它没有正确答案。&lt;/p&gt;

&lt;p&gt;毛姆在书中说：&lt;br /&gt;
“做自己最想做的事，过自己想过的生活，求得内心安宁，怎么能叫作贱自己？做一个有名的外科医生，一年赚一万英镑，娶一位漂亮的妻子，就是成功？我想，这取决于你如何看待生活的意义。”&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:note1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;有研究显示，打字的时候不喜欢在中文和英文之间加空格的人，感情路都走得很辛苦. &lt;a href=&quot;#fnref:note1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Tue, 26 Mar 2019 21:10:14 +0000</pubDate>
        <link>http://songroger.win/moon-and-six-pence/</link>
        <guid isPermaLink="true">http://songroger.win/moon-and-six-pence/</guid>
        
            <category>recommend</category>
        
        
            <category>diary</category>
        
      </item>
    
      <item>
        <title>python 单例模式</title>
        <description>&lt;p&gt;单例模式（Singleton Pattern）是一种常用的软件设计模式，该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中，某个类只能出现一个实例时，单例对象就能派上用场。&lt;/p&gt;

&lt;p&gt;比如，某个服务器程序的配置信息存放在一个文件中，客户端通过一个 AppConfig 的类来读取配置文件的信息。如果在程序运行期间，有很多地方都需要使用配置文件的内容，也就是说，很多地方都需要创建 AppConfig 对象的实例，这就导致系统中存在多个 AppConfig 的实例对象，而这样会严重浪费内存资源，尤其是在配置文件内容很多的情况下。事实上，类似 AppConfig 这样的类，我们希望在程序运行期间只存在一个实例对象。&lt;/p&gt;

&lt;p&gt;在 Python 中，我们可以用多种方法来实现单例模式：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;使用模块&lt;/li&gt;
  &lt;li&gt;使用 &lt;strong&gt;new&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;使用装饰器（decorator）&lt;/li&gt;
  &lt;li&gt;使用元类（metaclass）&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;使用-new-&quot;&gt;使用 &lt;strong&gt;new&lt;/strong&gt; :&lt;/h3&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Singleton&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;_instance&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__new__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# NOTICE: __init__方法中除了self之外定义的参数，都将与__new__方法中除cls参数之外的参数是必须保持一致或者等效
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_instance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_instance&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Singleton&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__new__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_instance&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NonSingleton&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MySingleClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Singleton&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyNonSingleClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NonSingleton&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;


&lt;span class=&quot;n&quot;&gt;a1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MySingleClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;a2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MySingleClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a1&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# --&amp;gt; True
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;a3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MyNonSingleClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;a4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MyNonSingleClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a3&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# --&amp;gt; False
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;More:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/6760685/creating-a-singleton-in-python&quot;&gt;creating-a-singleton-in-python&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://foofish.net/magic-method.html&quot;&gt;&lt;strong&gt;init&lt;/strong&gt;、&lt;strong&gt;new&lt;/strong&gt;、&lt;strong&gt;call&lt;/strong&gt; 方法&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Tue, 12 Feb 2019 12:25:10 +0000</pubDate>
        <link>http://songroger.win/python-singleton/</link>
        <guid isPermaLink="true">http://songroger.win/python-singleton/</guid>
        
            <category>recommend</category>
        
        
            <category>code</category>
        
      </item>
    
      <item>
        <title>python super()</title>
        <description>&lt;p&gt;super() 函数是用于调用父类(超类)的一个方法。
super 是用来解决多重继承问题的，直接用类名调用父类方法在使用单继承的时候没问题，但是如果使用多继承，会涉及到查找顺序（MRO）、重复调用（钻石继承）等种种问题。
super 的一大好处在于，当父类的名字修改时，其继承类不用修改调用方法。每次调用super()则是，调用MRO中下一个函数。
MRO(Method Resolution Order) 就是类的方法解析顺序表, 其实也就是继承父类方法时的顺序表。&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;super(type[, object-or-type])&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;type – 类。
object-or-type – 类，一般是 self&lt;/p&gt;

&lt;p&gt;注意：
super(type, obj).func()函数调用的是，obj实例在MRO中下一个父类的可调用func()，而不是type的父类中的func()&lt;/p&gt;

</description>
        <pubDate>Sun, 10 Feb 2019 08:05:10 +0000</pubDate>
        <link>http://songroger.win/python-super/</link>
        <guid isPermaLink="true">http://songroger.win/python-super/</guid>
        
        
            <category>code</category>
        
      </item>
    
      <item>
        <title>Python 线程池 fragment</title>
        <description>&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;queue&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Queue&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;threading&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Thread&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Worker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot; Thread executing tasks from a given tasks queue &quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tasks&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tasks&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;daemon&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kargs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;c1&quot;&gt;# An exception happened in this thread
&lt;/span&gt;                &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;finally&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;c1&quot;&gt;# Mark this task as done, whether an exception happened or not
&lt;/span&gt;                &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;task_done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ThreadPool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot; Pool of threads consuming tasks from a queue &quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num_threads&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tasks&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Queue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num_threads&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num_threads&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Worker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;add_task&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot; Add a task to the queue &quot;&quot;&quot;&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot; Add a list of tasks to the queue &quot;&quot;&quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_task&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;wait_completion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot; Wait for completion of all the tasks in the queue &quot;&quot;&quot;&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;__main__&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;random&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;randrange&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;time&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sleep&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# Function to be executed in a thread
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;wait_delay&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;sleeping for (%d)sec&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# Generate random delays
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;delays&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;randrange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# Instantiate a thread pool with 5 worker threads
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;pool&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ThreadPool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# Add the jobs in bulk to the thread pool. Alternatively you could use
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# `pool.add_task` to add single jobs. The code will block here, which
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# makes it possible to cancel the thread pool with an exception when
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# the currently running batch of workers is finished.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;pool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;wait_delay&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;delays&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;pool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;wait_completion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Wed, 16 Jan 2019 11:05:39 +0000</pubDate>
        <link>http://songroger.win/python-thread-pool/</link>
        <guid isPermaLink="true">http://songroger.win/python-thread-pool/</guid>
        
            <category>recommend</category>
        
        
            <category>code</category>
        
      </item>
    
      <item>
        <title>小鸭子的故事</title>
        <description>&lt;h3 id=&quot;1-python-strongly-typed-dynamic&quot;&gt;1. Python: Strongly-typed? Dynamic?&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Dynamic？&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;静态类型：编译时就知道每个变量的类型，因为类型错误而不能做的事情是语法错误。&lt;/li&gt;
      &lt;li&gt;动态类型：编译时不知道每个变量的类型，因为类型错误而不能做的事情是运行时错误。
        &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; 优点：
  更适合开发小的项目，无需声明类型;
  Duck typing 解除了很多束缚;
 缺点：
  慢：编译器对于没有typing的变量，需要一个个check具体type
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Strongly-typed？&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;强类型语言：偏向于不容忍隐式类型转换。&lt;/li&gt;
      &lt;li&gt;弱类型语言：偏向于容忍隐式类型转换。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Python 是动态强类型语言。&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
  &lt;p&gt;Python uses dynamic typing, which allows you to change the type of a variable, by replacing an integer with a string, for example.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img src=&quot;/img/programing_lang.jpg&quot; alt=&quot;lang&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;2-duck-typing&quot;&gt;2. Duck typing&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;【“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子，那么这只鸟就可以被称为鸭子。”】&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;鸭子类型是动态类型的一种风格。在这种风格中，一个对象有效的语义，
不是由继承自特定的类或实现特定的接口，
而是由”当前方法和属性的集合”决定。
没有了接口类型的继承约束。
鸭子类型可以在不使用继承的情况下使用多态。(其实就是因为变量没有显式的类型)&lt;/p&gt;

&lt;p&gt;利用鸭子类型的思想，我们不必借助超类型的帮助，就能轻松地在动态类型语言中实现一个原则：“面向接口编程，而不是面向实现编程”。例如，一个对象若有push和pop方法，并且这些方法提供了正确的实现，它就可以被当作栈来使用。一个对象如果有length属性，也可以依照下标来存取属性（最好还要拥有slice和splice等方法），这个对象就可以被当作数组来使用。&lt;/p&gt;

&lt;p&gt;在静态类型语言中，要实现“面向接口编程”并不是一件容易的事情，往往要通过抽象类或者接口等将对象进行向上转型。当对象的真正类型被隐藏在它的超类型身后，这些对象才能在类型检查系统的“监视”之下互相被替换使用。只有当对象能够被互相替换使用，才能体现出对象多态性的价值。&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Duck&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Duck flying&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Airplane&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Airplane flying&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Whale&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;swim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Whale swimming&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;animal&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Duck&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Airplane&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Whale&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;animal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Duck&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flying&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Airplane&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flying&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;AttributeError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;Whale&apos;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;has&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;no&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attribute&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;fly&apos;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;C++、Java 虽然不是动态语言, 但是它们也能支持 Duck Typing，它们是通过模板来支持的。
go 同样可以实现，并且相对比较灵活，又不失类型检查。&lt;/p&gt;

&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li&gt;
      &lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Duck_typing&quot;&gt;Duck_typing&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li&gt;
      &lt;p&gt;&lt;a href=&quot;https://dustyprogrammer-blog.tumblr.com/post/16746798643/should-your-start-up-go-static-or-dynamic&quot;&gt;static-or-dynamic&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li&gt;
      &lt;p&gt;&lt;a href=&quot;http://www.voidspace.org.uk/python/articles/duck_typing.shtml&quot;&gt;Duck Typing in Python&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li&gt;
      &lt;p&gt;&lt;a href=&quot;https://segmentfault.com/a/1190000019607240&quot;&gt;编程语言中的 DUCK TYPING&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Mon, 12 Nov 2018 08:02:10 +0000</pubDate>
        <link>http://songroger.win/duck-typing/</link>
        <guid isPermaLink="true">http://songroger.win/duck-typing/</guid>
        
            <category>recommend</category>
        
        
            <category>code</category>
        
      </item>
    
  </channel>
</rss>
