<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Python on Quietbo</title><link>https://quietbo.com/categories/python/</link><description>Recent content in Python on Quietbo</description><generator>Hugo -- gohugo.io</generator><language>zh-tw</language><lastBuildDate>Sun, 24 Mar 2024 06:42:36 +0000</lastBuildDate><atom:link href="https://quietbo.com/categories/python/index.xml" rel="self" type="application/rss+xml"/><item><title>[Graph database] 使用docker安裝memgraph &amp; python簡易連線</title><link>https://quietbo.com/2024/03/24/graph-database-%E4%BD%BF%E7%94%A8docker%E5%AE%89%E8%A3%9Dmemgraph/</link><pubDate>Sun, 24 Mar 2024 06:42:36 +0000</pubDate><guid>https://quietbo.com/2024/03/24/graph-database-%E4%BD%BF%E7%94%A8docker%E5%AE%89%E8%A3%9Dmemgraph/</guid><description>&lt;ul&gt;
&lt;li&gt;使用docker desktop&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="什麼是-graph-database-"&gt;什麼是 Graph database ？
&lt;/h2&gt;&lt;p&gt;[Graph database簡稱GDB][1],是一個使用圖結構進行語意查詢的資料庫，它使用節點、邊和屬性來表示和儲存資料。 該系統的關鍵概念是圖，它直接將儲存中的資料項，與資料節點和節點間表示關係的邊的集合相關聯 目前有哪些GraphDB,排名:&lt;a class="link" href="https://db-engines.com/en/ranking/graph&amp;#43;dbmsmemgraph" target="_blank" rel="noopener"
 &gt;圖形資料庫排名&lt;/a&gt;以及所有&lt;a class="link" href="https://db-engines.com/en/ranking" target="_blank" rel="noopener"
 &gt;受歡迎程度對資料庫管理系統進行排名&lt;/a&gt; ## docker desktop 安裝 memgraph&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://quietbo.com/uploads/2024/03/image-1-1024x579.png"&gt;以在 localhost:7687 看到 memgraph 的介面了。&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://quietbo.com/uploads/2024/03/image-2-1024x551.png"&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://quietbo.com/uploads/2024/03/image-3-1024x638.png"&gt;點擊左方的Datasets 找 CORA: Scientific publications classified into seven categories&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://quietbo.com/uploads/2024/03/image-4-1024x550.png"&gt;執行完成後點擊 run query&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://quietbo.com/uploads/2024/03/image-5-1024x550.png"&gt;會出現下方成功的結果&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://quietbo.com/uploads/2024/03/image-1024x591.png"&gt;## Python連線&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用pycharm&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;官網教學:[網址][2] 當memgraph建立成功後使用下方程式碼來建立Person&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;mgclient&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mgclient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;127.0.0.1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;7687&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;cursor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; CREATE (n:Person {name: &amp;#39;John&amp;#39;})-[e:KNOWS]-&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; (m:Person {name: &amp;#39;Steve&amp;#39;})
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; RETURN n, e, m
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetchone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c1"&gt;# (:Person {&amp;#39;name&amp;#39;: &amp;#39;John&amp;#39;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c1"&gt;# [:KNOWS]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c1"&gt;# (:Person {&amp;#39;name&amp;#39;: &amp;#39;Steve&amp;#39;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# 提交數據(沒有commit就不會真正存進資料庫內)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 關閉游標和連線&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;接著在memgraph下sql指令即可看到剛才創建的2筆資料&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;RETURN&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;[1]: &lt;a class="link" href="https://zh.wikipedia.org/zh-tw/%E5%9B%BE%E6%95%B0%E6%8D%AE%E5%BA%93" target="_blank" rel="noopener"
 &gt;https://zh.wikipedia.org/zh-tw/%E5%9B%BE%E6%95%B0%E6%8D%AE%E5%BA%93&lt;/a&gt; [2]: &lt;a class="link" href="https://pypi.org/project/pymgclient/0.1.0/" target="_blank" rel="noopener"
 &gt;https://pypi.org/project/pymgclient/0.1.0/&lt;/a&gt;&lt;/p&gt;</description></item><item><title>[Python] grequest 出現 Monkey-patching ssl after ssl has already been imported may lead to errors, including RecursionError on Python 3.6. It may also silently lead to incorrect behaviour on Python 3.7. Please monkey-patch earlier(已解決)</title><link>https://quietbo.com/2023/05/02/python-grequest-%E5%87%BA%E7%8F%BE-monkey-patching-ssl-after-ssl-has-already-been-imported-may-lead-to-errors-including-recursionerror-on-python-3-6-it-may-also-silently-lead-to-incorrect-behaviou/</link><pubDate>Tue, 02 May 2023 14:56:10 +0000</pubDate><guid>https://quietbo.com/2023/05/02/python-grequest-%E5%87%BA%E7%8F%BE-monkey-patching-ssl-after-ssl-has-already-been-imported-may-lead-to-errors-including-recursionerror-on-python-3-6-it-may-also-silently-lead-to-incorrect-behaviou/</guid><description>&lt;p&gt;剛開始使用grequest就遇到這個Error，用這段訊息去找也沒有解決方式，一開始google到的都是要加下方這段，但仍然沒有解決根本的問題!&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;import gevent
from gevent import monkey
monkey.patch_all(select=False)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但我使用下方code，開啟一個新的py檔案就正常運行&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;import grequests

req_list = [ # 请求列表
 grequests.get('http://httpbin.org/get?a=1&amp;b=2'),
 grequests.post('http://httpbin.org/post', data={'a':1,'b':2}),
 grequests.put('http://httpbin.org/post', json={'a': 1, 'b': 2}),
]

res_list = grequests.map(req_list) # 并行发送，等最后一个运行完后返回
print(res_list[0].text) # 打印第一个请求的响应文本&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;看一下&lt;a class="link" href="https://github.com/spyoungtech/grequests" target="_blank" rel="noopener"
 &gt;grequests的GitHub&lt;/a&gt;&lt;br&gt;
最下面方有個最好的寫法&lt;figure class="wp-block-image"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/TSt5RhX.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;後來發現原本py檔有from其他py檔是有使用request的，把request前面import grequests就成功解決這個問題&lt;/p&gt;</description></item><item><title>[Mongodb] 資料內為什麼有$numberLong?(已解決)</title><link>https://quietbo.com/2023/03/11/mongodb-%E8%B3%87%E6%96%99%E5%85%A7%E7%82%BA%E4%BB%80%E9%BA%BC%E6%9C%89numberlong%E5%B7%B2%E8%A7%A3%E6%B1%BA/</link><pubDate>Fri, 10 Mar 2023 16:56:40 +0000</pubDate><guid>https://quietbo.com/2023/03/11/mongodb-%E8%B3%87%E6%96%99%E5%85%A7%E7%82%BA%E4%BB%80%E9%BA%BC%E6%9C%89numberlong%E5%B7%B2%E8%A7%A3%E6%B1%BA/</guid><description>&lt;p&gt;這件事情是不小心自己做了一個坑給自己踩的，&lt;br&gt;
我從公司的QAT測試環境的GUI(Mongodb compass)複製了一份data，內容複製出來如下:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;uuid&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2580913&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;name&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;UserName&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;id&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;A123456789&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;age&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;weight&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;height&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;175&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;birthday&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;:{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;$numberLong&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;789798540000&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;registration_date&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;$numberLong&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;1677211157126&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然後在我自己本機用Studio 3T直接insert了這些相同格式的資料，都正常匯入了！ 後來我在local開發的時候find用了下方的方式來搜尋(注意!其實這是錯的，這裡的$numberLong是被當作層級使用)&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;{&amp;#34;birthday.$numberLong&amp;#34;: {&amp;#34;$gte&amp;#34;: &amp;#34;789798540000&amp;#34;}}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;此時local能正常取出資料，我還沒意識到問題。 後來部署到QAT後頻繁出錯，一去了解才發現，原來當時從Mongodb compass複製出來的$numberLong該資料的type， 原始資料為:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;uuid&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2580913068820&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;name&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;UserName&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;id&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;A123456789&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;age&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;weight&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;height&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;175&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;birthday&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;789798540000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;registration_date&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1677211157126&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我後來去QAT機器測了一下這段，(如果birthday的type是int)&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;db.user.find ({birthday:{$ type : &amp;#34;int&amp;#34; }})
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;結果沒有資料。我把int換成了long：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;db.user.find ({birthday:{$ type : &amp;#34;long&amp;#34; }})
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;就出現一堆資料了。 其實我一開始在把QAT的測試資料存進local這裡就出錯了！ 原因是Mongodb compass在複製資料時為了區分int和long這兩個不同的type，所以加了$numberLong 這段讓我們肉眼能夠判斷資料的type，後來我把$numberLong都拿掉後，公司QAT就正常可以取得資料了。&lt;/p&gt;</description></item><item><title>[Python] 製作一個exe檔案在windows執行</title><link>https://quietbo.com/2022/12/11/python-%E8%A3%BD%E4%BD%9C%E4%B8%80%E5%80%8Bexe%E6%AA%94%E6%A1%88%E5%9C%A8windows%E5%9F%B7%E8%A1%8C/</link><pubDate>Sun, 11 Dec 2022 08:03:13 +0000</pubDate><guid>https://quietbo.com/2022/12/11/python-%E8%A3%BD%E4%BD%9C%E4%B8%80%E5%80%8Bexe%E6%AA%94%E6%A1%88%E5%9C%A8windows%E5%9F%B7%E8%A1%8C/</guid><description>&lt;ul class="wp-block-list"&gt;
 &lt;li&gt;
 Windows 11
 &lt;/li&gt;
 &lt;li&gt;
 IDE:PyCharm 2022.3 (Community Edition)
 &lt;/li&gt;
 &lt;li&gt;
 Python3.7
 &lt;/li&gt;
 &lt;li&gt;
 package:PyInstaller
 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以下為pycharm初始的Code，請先確認環境與package可install與執行指令。&lt;/p&gt;
&lt;p&gt;本篇程式碼檔案名為main.py&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;# This is a sample Python script.

# Press Shift+F10 to execute it or replace it with your code.
# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings.


def print_hi(name):
 # Use a breakpoint in the code line below to debug your script.
 print(f'Hi, {name}') # Press Ctrl+F8 to toggle the breakpoint.


# Press the green button in the gutter to run the script.
if __name__ == '__main__':
 print_hi('PyCharm')

# See PyCharm help at https://www.jetbrains.com/help/pycharm/&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安裝:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;pip install pyinstaller&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;執行下方指令&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;pyinstaller -F .\{檔案名稱}.py&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;範例:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;pyinstaller -F .\main.py&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;執行會出現一大串訊息，本篇只擷取部分畫面:&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/RF0ZDaJ.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;開啟資料夾查看&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/wclI2Ox.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;會建立以下&lt;/p&gt;
&lt;ul class="wp-block-list"&gt;
 &lt;li&gt;
 main.spec
 &lt;/li&gt;
 &lt;li&gt;
 build 資料夾 (log與工作檔案)
 &lt;/li&gt;
 &lt;li&gt;
 dist 資料夾(要執行的exe檔案在這裡面)
 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;打開dist會看到main.exe，點擊後會馬上出現命令提示字元後馬上又消失。&lt;br&gt;
如果想要暫停住的話可加入input()在Code內。&lt;figure class="wp-block-image"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/rrvkrP2.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;再重新pyinstaller -F .\main.py一次，重新點擊main.exe即可停留在下方畫面。&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/vmbVcrL.png" alt="" /&gt;&lt;/p&gt;</description></item><item><title>[Python] 日誌記錄第三方庫 – Loguru(附簡單的範例)</title><link>https://quietbo.com/2022/08/12/python-%E6%97%A5%E8%AA%8C%E8%A8%98%E9%8C%84%E7%AC%AC%E4%B8%89%E6%96%B9%E5%BA%AB-loguru%E9%99%84%E7%B0%A1%E5%96%AE%E7%9A%84%E7%AF%84%E4%BE%8B/</link><pubDate>Fri, 12 Aug 2022 11:01:01 +0000</pubDate><guid>https://quietbo.com/2022/08/12/python-%E6%97%A5%E8%AA%8C%E8%A8%98%E9%8C%84%E7%AC%AC%E4%B8%89%E6%96%B9%E5%BA%AB-loguru%E9%99%84%E7%B0%A1%E5%96%AE%E7%9A%84%E7%AF%84%E4%BE%8B/</guid><description>&lt;p&gt;use:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;pycharm, FastAPI, Loguru&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;一開始在學log時, 會使用標準庫 logging。&lt;br&gt;
設置上較爲繁瑣, 甚至有些在多進程多線程等特殊處理時, 還會導致日誌記錄會出現異常, 還有幾次都在找為什麼logg會印兩次…&lt;br&gt;
現在單純開發時都會使用Loguru來做一些log的紀錄,下方提供簡單的範例&lt;/p&gt;
&lt;h2 id="安裝"&gt;安裝
&lt;/h2&gt;&lt;p&gt;使用 pip 安裝即可，Python 3 版本的安裝如下：&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;pip3 install loguru&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;log.py&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;from loguru import logger
logger.add("./logs/test.log", rotation="00:00", enqueue=True, retention="30 days")

#logger.info(1)
#logger.error(2)
#logger.warning(3)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;main.py&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;import uvicorn
from log import logger
from fastapi import FastAPI

app = FastAPI()

@app.on_event("startup")
async def startup_event():
 logger.info('Hi startup')

@app.get("/")
async def root():
 return {"message": "Hello World"}


if __name__ == "__main__":
 uvicorn.run("main:app", host='127.0.0.1', port=8000, reload=True)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;執行python main.py&lt;/p&gt;
&lt;p&gt;會看到下方的&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;INFO: Will watch for changes in these directories: ['C:\\Dev\\FastAPI_demo']
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [21476] using watchgod
INFO: Started server process [4168]
INFO: Waiting for application startup.
2022-08-12 18:53:32.579 | INFO | main:startup_event:9 - Hi startup
INFO: Application startup complete.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;打開瀏覽器輸入下方:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;127.0.0.1/&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;打開logs資料夾會看到已經有印出來的檔案。&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash line-numbers"&gt;2022-08-12 18:56:21.419 | INFO | main:startup_event:9 - Hi startup
2022-08-12 18:56:27.969 | INFO | main:root:13 - {'message': 'Hello World'}&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>[Python] os.chdir 更改當前工作目錄</title><link>https://quietbo.com/2022/07/19/python-os-chdir-%E6%9B%B4%E6%94%B9%E7%95%B6%E5%89%8D%E5%B7%A5%E4%BD%9C%E7%9B%AE%E9%8C%84/</link><pubDate>Tue, 19 Jul 2022 09:49:44 +0000</pubDate><guid>https://quietbo.com/2022/07/19/python-os-chdir-%E6%9B%B4%E6%94%B9%E7%95%B6%E5%89%8D%E5%B7%A5%E4%BD%9C%E7%9B%AE%E9%8C%84/</guid><description>&lt;p&gt;語法:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="basic" class="language-basic"&gt;os.chdir(path)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;參數&lt;/p&gt;
&lt;ul class="wp-block-list"&gt;
 &lt;li&gt;
 path − 更改到新位置的目錄的完整路徑。
 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不返回任何值。沒有找到指定的路徑，會拋出FileNotFoundError&lt;/p&gt;
&lt;p&gt;舉例:&lt;br&gt;
我在跟目錄(/)的狀態下, 使用python3 絕對路徑/xxxx.py後, 要在運行別隻py檔案,&lt;/p&gt;
&lt;p&gt;使用下方兩隻py檔來做演示,路徑都在/home/ubuntu/Dev&lt;/p&gt;
&lt;p&gt;檔名:chdir.py&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;#!/usr/bin/python
# -*- coding: UTF-8 -*-

import os, sys

path = "/home/ubuntu/Dev"

# 查看當前工作目錄
retval = os.getcwd()
print("當前工作目錄:%s" % retval)

# 修改當前工作目錄
os.chdir( path )

# 查看修改後的工作目錄
retval = os.getcwd()

print("目錄修改成功:%s" % retval)

# 接著要運行的指令
os.system("python3 pping.py") &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;檔名:pping.py&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;import os
a=os.system("ping 192.168.1.101") #使用a接收返回值
print(a)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以下是在終端機執行過程:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash line-numbers"&gt;ubuntu@ubuntu:~/Dev$ cd ~
ubuntu@ubuntu:~$ python3 /home/ubuntu/Dev/chdir.py 
當前工作目錄:/home/ubuntu
目錄修改成功:/home/ubuntu/Dev
PING 192.168.1.101 (192.168.1.101) 56(84) bytes of data.
64 bytes from 192.168.1.101: icmp_seq=1 ttl=128 time=5.19 ms&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;由此可見os.getcwd是獲得終端機當下在運行python時的路徑, 而os.chdir是會修改為新的工作路徑, 若沒有修改的話, 是沒辦法透過os.system來運行pping.py的, 會出現找不到檔案的error。&lt;/p&gt;</description></item><item><title>[Python] 背景執行nohup, &amp; 與 nohup.out</title><link>https://quietbo.com/2022/07/06/python-%E8%83%8C%E6%99%AF%E5%9F%B7%E8%A1%8Cnohup-%E8%88%87-nohup-out/</link><pubDate>Wed, 06 Jul 2022 10:13:54 +0000</pubDate><guid>https://quietbo.com/2022/07/06/python-%E8%83%8C%E6%99%AF%E5%9F%B7%E8%A1%8Cnohup-%E8%88%87-nohup-out/</guid><description>&lt;h1 id=""&gt;
&lt;/h1&gt;&lt;p&gt;本篇提到的「&lt;strong&gt;背景&lt;/strong&gt;」指的是: 在終端機模式下使用 [ctrl]-c, 並不會中斷的一個情境!&lt;/p&gt;
&lt;p&gt;&lt;a href="https://quietbo.com/2021/03/10/ubuntu%e8%83%8c%e6%99%af%e5%9f%b7%e8%a1%8cpy%e6%96%b9%e6%b3%95/" target="_blank" rel="noreferrer noopener"&gt;[Linux]背景執行py方法&lt;/a&gt; 雖然是在背景執行, 不會因為[ctrl]-c而中斷, 但會因為「&lt;strong&gt;終端機關閉後而中斷&lt;/strong&gt;」。&lt;/p&gt;
&lt;p id="block-b1f3c7ea-6b97-4897-bb83-e416e7bdabac"&gt;
 中斷可能多個原因, 例如ssh連線到機器後, 操作時不小心將視窗關閉,或是網路斷線而關閉。
&lt;/p&gt;
&lt;p&gt;本次主要目的為: 「&lt;strong&gt;在離線或登出系統後，還能夠讓工作繼續進行&lt;/strong&gt;」。&lt;/p&gt;
&lt;p&gt;演示的code為my_nohup.py:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;# coding:utf-8
from datetime import datetime
from time import sleep
import logging

Log_Format = "%(levelname)s %(asctime)s - %(message)s"

logging.basicConfig(filename = "mylog.log",
 filemode = "w",
 format = Log_Format,
 level = logging.INFO)
logger = logging.getLogger()
logger.error("Our First Log Message")

while(1):
 sleep(5)

 print("print " + str(datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
 logger.info(str(datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
 # print(1/0) # 輸出錯誤時使用&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id="指令介紹"&gt;&lt;span class="ez-toc-section" id="%E6%8C%87%E4%BB%A4%E4%BB%8B%E7%B4%B9"&gt;&lt;/span&gt;指令介紹&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h1&gt;&lt;ul class="wp-block-list"&gt;
 &lt;li&gt;
 &lt;code&gt;nohup&lt;/code&gt;: no hang up的縮寫, 不斷地運行。
 &lt;/li&gt;
 &lt;li&gt;
 &lt;code&gt;&amp;&lt;/code&gt;: 在後台運行，關掉終端會停止運行。
 &lt;/li&gt;
 &lt;li&gt;
 &lt;code&gt;&amp;gt;&lt;/code&gt; : 標準輸出符號。
 &lt;/li&gt;
 &lt;li&gt;
 &lt;code&gt;-u&lt;/code&gt;: 在nohup.out內可以看到print的訊息。
 &lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="背景執行nohup-"&gt;&lt;span class="ez-toc-section" id="%E8%83%8C%E6%99%AF%E5%9F%B7%E8%A1%8Cnohup"&gt;&lt;/span&gt;背景執行(nohup, &amp;amp;)&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;nohup python3 my_nohup.py &amp;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;758865 為背景執行的PID&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/Ixd9tqD.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;執行完會出現一段，所有輸出都被重定向到一個名為nohup.out的文件中&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;nohup: ignoring input and appending output to 'nohup.out'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此時輸入ls指令會看到多出mylog.log和nohup.out&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;admins@labs:~$ ls
Dev get-pip.py mylog.log my_nohup.py nohup.out Python-3.7.9&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;試著使用cat去看看這兩隻檔案, mylog.log會每5秒打印訊息, 但nohup.out是空的。&lt;/p&gt;
&lt;p&gt;查看背景運行(若是關閉終端機後才使用指令，jobs已經無法看到後台跑得程序了, 需使用ps aux)&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;jobs -l&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;離開該終端機後, 背景仍會繼續執行這個服務, 可使用ps aux來查看。&lt;/p&gt;
&lt;h2 id="解決-nohupout打開是空白問題"&gt;&lt;span class="ez-toc-section" id="%E8%A7%A3%E6%B1%BA_nohupout%E6%89%93%E9%96%8B%E6%98%AF%E7%A9%BA%E7%99%BD%E5%95%8F%E9%A1%8C"&gt;&lt;/span&gt;[解決] nohup.out打開是空白問題&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;如果沒有指定導出的地方, 會在nohup.out檔案內, 但在執行時需使用&lt;br&gt;
python -u&lt;br&gt;
執行時使用下方指令:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;nohup python3 -u my_nohup.py &amp;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;這樣print內的訊息都會在nohup.out了, 而log則是logger寫入的資料, 是分開的檔案。&lt;/p&gt;
&lt;h2 id="指定輸出檔案導出檔案"&gt;&lt;span class="ez-toc-section" id="%E6%8C%87%E5%AE%9A%E8%BC%B8%E5%87%BA%E6%AA%94%E6%A1%88%E5%B0%8E%E5%87%BA%E6%AA%94%E6%A1%88"&gt;&lt;/span&gt;指定輸出檔案(導出檔案)&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;可以指定導到其他檔案, 下方是導到my_print.txt&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;nohup python3 -u my_nohup.py &amp;gt; my_print.txt &amp;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;沒有nohup: ignoring input and appending output to ‘nohup.out’的訊息, 也沒有看到nohup.out的檔案。&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/cg3xS8W.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;這裡的&amp;gt;其實是 1&amp;gt; 的縮寫。&lt;figure class="wp-block-table"&gt;&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;名稱&lt;/th&gt;
 &lt;th&gt;代碼&lt;/th&gt;
 &lt;th&gt;操作符號&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;標準輸入&lt;/td&gt;
 &lt;td&gt;&lt;/td&gt;
 &lt;td&gt;&amp;lt; 或&amp;laquo;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;標準輸出&lt;/td&gt;
 &lt;td&gt;1&lt;/td&gt;
 &lt;td&gt;&amp;gt;或&amp;raquo;或1&amp;gt; 或1&amp;raquo;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;標準錯誤輸出&lt;/td&gt;
 &lt;td&gt;2&lt;/td&gt;
 &lt;td&gt;2&amp;gt; 或2&amp;raquo;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;通常後台運行重定向可以寫成：&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;mkdir logs
nohup python3 -u my_nohup.py &amp;gt; logs/command.log 2&amp;gt;&amp;1 &amp;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2&amp;gt;&amp;amp;1 是將「標準錯誤輸出(2)」重定向到「標準輸出(1)」, 簡單來說就是&lt;strong&gt;標準輸出和標準錯誤輸出都在同一份檔案&lt;/strong&gt;, 導入logs文件夾下的command.log日誌文件。&lt;/p&gt;
&lt;h2 id="標準輸出與標準錯誤輸出分開儲存"&gt;&lt;span class="ez-toc-section" id="%E6%A8%99%E6%BA%96%E8%BC%B8%E5%87%BA%E8%88%87%E6%A8%99%E6%BA%96%E9%8C%AF%E8%AA%A4%E8%BC%B8%E5%87%BA%E5%88%86%E9%96%8B%E5%84%B2%E5%AD%98"&gt;&lt;/span&gt;標準輸出與標準錯誤輸出分開儲存&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;如果想要把錯誤輸出存到另一份檔案,把最後一行的註解拿掉， print(1/0)在最後運行時會出錯, 下方指令, 會把標準輸出到out.log, 標準錯誤輸出err.log&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;nohup python3 -u my_nohup.py &amp;gt; out.log 2&amp;gt;err.log &amp;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下方為故意讓程式有出錯的狀況的圖片, 會看到out.log是原本的print日期時間, 而err.log則是遇到錯誤的訊息&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/mMogv4p.png" alt="" /&gt;&lt;/p&gt;
&lt;hr class="wp-block-separator has-alpha-channel-opacity" /&gt;
&lt;p&gt;補充:&lt;br&gt;
&lt;a href="https://linux.vbird.org/linux_basic/centos7/0440processcontrol.php#nohup" target="_blank" rel="noreferrer noopener"&gt;鳥哥私房菜-離線管理問題&lt;/a&gt;&lt;/p&gt;</description></item><item><title>[Python] 日誌按天分割，保存近一個月日誌</title><link>https://quietbo.com/2022/06/30/python-%E6%97%A5%E8%AA%8C%E6%8C%89%E5%A4%A9%E5%88%86%E5%89%B2%EF%BC%8C%E4%BF%9D%E5%AD%98%E8%BF%91%E4%B8%80%E5%80%8B%E6%9C%88%E6%97%A5%E8%AA%8C/</link><pubDate>Thu, 30 Jun 2022 11:00:42 +0000</pubDate><guid>https://quietbo.com/2022/06/30/python-%E6%97%A5%E8%AA%8C%E6%8C%89%E5%A4%A9%E5%88%86%E5%89%B2%EF%BC%8C%E4%BF%9D%E5%AD%98%E8%BF%91%E4%B8%80%E5%80%8B%E6%9C%88%E6%97%A5%E8%AA%8C/</guid><description>&lt;p&gt;下方為code, 請根據自己需求去做調整, 主要是存放的路徑與log內的訊息格式&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;import datetime
import logging
import os
import pathlib
import re
from logging.handlers import TimedRotatingFileHandler


path = os.path.join(pathlib.Path(__file__).parent.absolute(), 'log')
log_folder_path = os.path.join(pathlib.Path(__file__).parent.parent.parent, 'log') # 與service同層, 自行調整parent的次數,

try:
 if not os.path.isdir(log_folder_path): # 如果日誌資料夾不存在，則建立資料夾
 os.mkdir(log_folder_path)
except Exception:
 print("建立資料夾失敗,資料夾路徑：" + log_folder_path)
 pass

log_name = 'serverlog' # 自訂log檔名稱
logger = logging.getLogger(log_name)

log_filename = datetime.datetime.now().strftime("%Y-%m-%d.log")
log_path = os.path.join(log_folder_path, log_name)
logger.setLevel(logging.DEBUG)

# when: 為一天, backupCount: 30個log檔案
file_handler = TimedRotatingFileHandler(
 filename=log_path, when="MIDNIGHT", interval=1, backupCount=30
)
file_handler.suffix = "%Y-%m-%d.log" # 可自訂
file_handler.extMatch = re.compile(r"^\d{4}-\d{2}-\d{2}.log$") # 刪除過期log檔


# format_2 = '[%(asctime)s] [%(process)d] [%(levelname)s] - %(module)s.%(funcName)s (%(filename)s:%(lineno)d) - %(message)s'

# 可自訂想要的格式, 或是網路上提供的, 像format_2就給的訊息很多, 但本身不需要那麼多訊息可以自己訂些簡單的
file_handler.setFormatter(logging.Formatter('[%(asctime)s] %(levelname)1.4s: %(module)s:%(lineno)d %(message)s'))
logger.addHandler(file_handler)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;檔案名稱如下, 名稱會照file_handler.suffix做修正。&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/9v6ifxz.png" alt="" /&gt;&lt;/p&gt;</description></item><item><title>WSGI &amp; ASGI</title><link>https://quietbo.com/2022/05/08/wsgi-asgi/</link><pubDate>Sun, 08 May 2022 12:46:31 +0000</pubDate><guid>https://quietbo.com/2022/05/08/wsgi-asgi/</guid><description>&lt;div id="ez-toc-container" class="ez-toc-v2_0_82_2 ez-toc-wrap-center counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction"&gt;
 &lt;div class="ez-toc-title-container"&gt;
 &lt;p class="ez-toc-title" style="cursor:inherit"&gt;
 Table of Contents
 &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;span class=&amp;quot;ez-toc-title-toggle&amp;quot;&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot; class=&amp;quot;ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle&amp;quot; aria-label=&amp;quot;顯示/隱藏內容目錄&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;ez-toc-js-icon-con&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;eztoc-hide&amp;quot; style=&amp;quot;display:none;&amp;quot;&amp;gt;Toggle&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;ez-toc-icon-toggle-span&amp;quot;&amp;gt;&amp;lt;svg style=&amp;quot;fill: #999;color:#999&amp;quot; xmlns=&amp;quot;http://www.w3.org/2000/svg&amp;quot; class=&amp;quot;list-377408&amp;quot; width=&amp;quot;20px&amp;quot; height=&amp;quot;20px&amp;quot; viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;/path&amp;gt;&amp;lt;/svg&amp;gt;&amp;lt;svg style=&amp;quot;fill: #999;color:#999&amp;quot; class=&amp;quot;arrow-unsorted-368013&amp;quot; xmlns=&amp;quot;http://www.w3.org/2000/svg&amp;quot; width=&amp;quot;10px&amp;quot; height=&amp;quot;10px&amp;quot; viewBox=&amp;quot;0 0 24 24&amp;quot; version=&amp;quot;1.2&amp;quot; baseProfile=&amp;quot;tiny&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;&lt;nav&gt;
 &lt;ul class='ez-toc-list ez-toc-list-level-1 ' &gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-1" href="https://quietbo.com/2022/05/08/wsgi-asgi/#%E4%BB%80%E9%BA%BC%E6%98%AF_WSGI" &gt;什麼是 WSGI?&lt;/a&gt;&lt;ul class='ez-toc-list-level-3' &gt;
 &lt;li class='ez-toc-heading-level-3'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-2" href="https://quietbo.com/2022/05/08/wsgi-asgi/#WSGI_%E8%88%87_WSGI_Server" &gt;WSGI 與 WSGI Server&lt;/a&gt;
 &lt;/li&gt;
 &lt;/ul&gt;
 &lt;/li&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&amp;gt;
 &amp;lt;a class=&amp;quot;ez-toc-link ez-toc-heading-3&amp;quot; href=&amp;quot;https://quietbo.com/2022/05/08/wsgi-asgi/#%E4%BB%80%E9%BA%BC%E6%98%AF_ASGI&amp;quot; &amp;gt;什麼是 ASGI?&amp;lt;/a&amp;gt;
&amp;lt;/li&amp;gt;
&amp;lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&amp;gt;
 &amp;lt;a class=&amp;quot;ez-toc-link ez-toc-heading-4&amp;quot; href=&amp;quot;https://quietbo.com/2022/05/08/wsgi-asgi/#%E7%B8%BD%E7%B5%90_WSGI_%E8%88%87_ASGI&amp;quot; &amp;gt;總結: WSGI 與 ASGI&amp;lt;/a&amp;gt;
&amp;lt;/li&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
 &lt;/ul&gt;&lt;/nav&gt;
&lt;/div&gt;
&lt;h2 id="什麼是-wsgi"&gt;&lt;span class="ez-toc-section" id="%E4%BB%80%E9%BA%BC%E6%98%AF_WSGI"&gt;&lt;/span&gt;什麼是 WSGI?&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;Web Server Gateway Interface，的縮寫(Web伺服器閘道器介面)，是一種協議，這個協議制定了一套規則，規定HTTP Request要如何與Application Server溝通。&lt;/p&gt;
&lt;ul class="wp-block-list"&gt;
 &lt;li&gt;
 WSGI應用是一個單調用、同步接口，即輸入一個請求，返回一個響應，無法支持長連接或者WebSocket
 &lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="wsgi-與-wsgi-server"&gt;&lt;span class="ez-toc-section" id="WSGI_%E8%88%87_WSGI_Server"&gt;&lt;/span&gt;WSGI 與 WSGI Server&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h3&gt;&lt;p&gt;可以將WSGI Server理解成處理 HTTP Request 與 Python 可理解的 Input/Output 的中繼站(Middleware)&lt;figure class="wp-block-image"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/JFpxNWj.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;所有支援 WSGI 協定的 Server 都可稱為 WSGI Server，現在比較常見的WSGI Server是gunicorn及 uwsgi。&lt;/p&gt;
&lt;h2 id="什麼是-asgi"&gt;&lt;span class="ez-toc-section" id="%E4%BB%80%E9%BA%BC%E6%98%AF_ASGI"&gt;&lt;/span&gt;什麼是 ASGI?&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;ul class="wp-block-list"&gt;
 &lt;li&gt;
 Asynchronous Server Gateway Interface(異步服務器網關接口)
 &lt;/li&gt;
 &lt;li&gt;
 ASGI 是 WSGI 的繼承者，已經存在的WSGI應用可以直接在ASGI服務器中運行
 &lt;/li&gt;
 &lt;li&gt;
 ASGI 代表異步服務器網關接口，是爲異步、同步應用程序提供標準，支持 WSGI 不支持當前 web 開發中的一些新的協議標準
 &lt;/li&gt;
 &lt;li&gt;
 介於網絡協議服務和Python應用之間的標準接口，能夠處理多種通用的協議類型，包括HTTP，HTTP2和WebSocket。
 &lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="總結-wsgi-與-asgi"&gt;&lt;span class="ez-toc-section" id="%E7%B8%BD%E7%B5%90_WSGI_%E8%88%87_ASGI"&gt;&lt;/span&gt;總結: WSGI 與 ASGI&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt; &lt;figure class="wp-block-image"&gt;
&lt;/h2&gt;&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/0b6uf83.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;ul class="wp-block-list"&gt;
 &lt;li&gt;
 相同之處:&lt;ul&gt;
 &lt;li&gt;
 WSGI 與 ASGI都指定接口並位於 Web 服務器和 Python Web 應用程序或框架之間。
 &lt;/li&gt;
 &lt;/ul&gt;
 &lt;/li&gt;
 &lt;li&gt;
 兩者的區別:&lt;ul&gt;
 &lt;li&gt;
 WSGI是基於HTTP協議模式的，不支持WebSocket
 &lt;/li&gt;
 &lt;li&gt;
 ASGI的誕生則是為了解決Python常用的WSGI不支持當前Web開發中的一些新的協議標準。
 &lt;/li&gt;
 &lt;li&gt;
 ASGI對於WSGI原有的模式的支持和WebSocket的擴展，即ASGI是WSGI的擴展。
 &lt;/li&gt;
 &lt;/ul&gt;
 &lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Python] pymysql.err.IntegrityError 解決</title><link>https://quietbo.com/2022/04/15/python-pymysql-err-integrityerror-%E8%A7%A3%E6%B1%BA/</link><pubDate>Fri, 15 Apr 2022 03:19:05 +0000</pubDate><guid>https://quietbo.com/2022/04/15/python-pymysql-err-integrityerror-%E8%A7%A3%E6%B1%BA/</guid><description>&lt;p&gt;通常遇到這狀況代表有設定unique的欄位, 被重複了,&lt;br&gt;
而且要新增的一筆資料又與該欄位有重複的值,則會報錯,&lt;/p&gt;
&lt;p&gt;假設我的欄位id已經有202204150012的資料時, 要再增加一筆id是202204150012的資料, 錯誤訊息如下, 會告知是哪個欄位重複與重複的value&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;(pymysql.err.IntegrityError) (1062, "Duplicate entry '202204150012' for key 'tb_order.id'")&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;解決方式1:&lt;br&gt;
將該欄位的unique拿掉&lt;/p&gt;
&lt;p&gt;解決方式2:&lt;br&gt;
做異常處理與回滾(rollback)&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;try:
 db.commit()
except:
 # 回滾
 db.rollback()
finally:
# 關閉數據庫連接
db.close()&lt;/code&gt;&lt;/pre&gt;
&lt;pre class="wp-block-preformatted"&gt;解決方式3:例外處理時跳過&lt;/pre&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;try:
 .... 
except IntegrityError as error:
 # 獨立處理重複
 result1 = re.search('Duplicate entry', str(error))
 if result1:
 logger.error('Duplicate entry')
 pass
except Exception as error:
 # 其他例外處理 ...
 &lt;/code&gt;&lt;/pre&gt;</description></item><item><title>[Pycharm] 導出&amp;導入虛擬環境(venv導出requirements)</title><link>https://quietbo.com/2022/04/06/pycharm-%E5%B0%8E%E5%87%BA%E5%B0%8E%E5%85%A5%E8%99%9B%E6%93%AC%E7%92%B0%E5%A2%83venv%E5%B0%8E%E5%87%BArequirements/</link><pubDate>Wed, 06 Apr 2022 05:24:22 +0000</pubDate><guid>https://quietbo.com/2022/04/06/pycharm-%E5%B0%8E%E5%87%BA%E5%B0%8E%E5%85%A5%E8%99%9B%E6%93%AC%E7%92%B0%E5%A2%83venv%E5%B0%8E%E5%87%BArequirements/</guid><description>&lt;h2 id="導出虛擬環境"&gt;導出虛擬環境
&lt;/h2&gt;&lt;p&gt;一般命令為導出的是系統環境，不是虛擬環境(venv)&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;pip freeze &amp;gt; requirements.txt&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在windows終端下是不可以使用的，使用以下代碼進行導出，運行後會產生requirements.txt&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;import os
import platform
import sys
import subprocess

# 當前目錄
project_root = os.path.dirname(os.path.realpath(__file__))
# project_root = os.path.realpath(__file__)
print('當前目錄' + project_root)

# 依據目前使用不同的系統會使用不同的command,目前使用linux及Windows
if platform.system() == 'Linux':
 command = sys.executable + ' -m pip freeze &amp;gt; ' + project_root + '/requirements.txt'
if platform.system() == 'Windows':
 command = '"' + sys.executable + '"' + ' -m pip freeze &amp;gt; "' + project_root + '\\requirements.txt"'
# 生成requirements的命令
print(command)
#
# 執行command
# os.system(command) #路徑有空格時不可用
os.popen(command) # 路徑有空格可用&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="安装requirement"&gt;安装requirement
&lt;/h2&gt;&lt;p&gt;開啟新的專案想使用requirement時，打開終端機輸入:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;pip install -r requirement.txt&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>[Python|FastAPI] 返回沒有雙引號的字串(返回純文本)PlainTextResponse</title><link>https://quietbo.com/2022/03/31/pythonfastapi-%E8%BF%94%E5%9B%9E%E6%B2%92%E6%9C%89%E9%9B%99%E5%BC%95%E8%99%9F%E7%9A%84%E5%AD%97%E4%B8%B2%E8%BF%94%E5%9B%9E%E7%B4%94%E6%96%87%E6%9C%ACplaintextresponse/</link><pubDate>Thu, 31 Mar 2022 10:26:15 +0000</pubDate><guid>https://quietbo.com/2022/03/31/pythonfastapi-%E8%BF%94%E5%9B%9E%E6%B2%92%E6%9C%89%E9%9B%99%E5%BC%95%E8%99%9F%E7%9A%84%E5%AD%97%E4%B8%B2%E8%BF%94%E5%9B%9E%E7%B4%94%E6%96%87%E6%9C%ACplaintextresponse/</guid><description>&lt;p&gt;問題:&lt;br&gt;
對方是要的訊息Hello World，不是要”Hello World”&lt;/p&gt;
&lt;p&gt;原本的FastAPI寫法如下:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;from fastapi import FastAPI
import uvicorn

app = FastAPI()


@app.get("/")
async def root():
 return "Hello World"

if __name__ == "__main__":
 uvicorn.run("main:app", host="127.0.0.1", port=8000)&lt;/code&gt;&lt;/pre&gt;&lt;figure class="wp-block-image is-style-default"&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/f23g0hl.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;可以看到最常見的postman發的請求得到是”Hello World”&lt;/p&gt;
&lt;p&gt;解決方式:&lt;br&gt;
使用:&lt;a class="link" href="https://fastapi.tiangolo.com/advanced/custom-response/#plaintextresponse" target="_blank" rel="noopener"
 &gt;PlainTextResponse&lt;/a&gt;&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;from fastapi import FastAPI
import uvicorn
from fastapi.responses import PlainTextResponse

app = FastAPI()


@app.get("/", response_class=PlainTextResponse)
async def root():
 return "Hello World"

if __name__ == "__main__":
 uvicorn.run("main:app", host="127.0.0.1", port=8000)&lt;/code&gt;&lt;/pre&gt;&lt;figure class="wp-block-image is-style-default"&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/VHdSY2i.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;可以看到還滿順利的出現了單純只有文字的Hello World&lt;/p&gt;
&lt;p&gt;不一定要放在response_class，以下方式也能成功:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;from fastapi import FastAPI
import uvicorn
from fastapi.responses import PlainTextResponse

app = FastAPI()

def get_text(parameters):
 text = PlainTextResponse(parameters)
 return text


@app.get("/")
async def root():
 op = get_text('hello bocky')
 return op

if __name__ == "__main__":
 uvicorn.run("main:app", host="127.0.0.1", port=8000)&lt;/code&gt;&lt;/pre&gt;&lt;figure class="wp-block-image is-style-default"&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/VpbKCPd.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;</description></item><item><title>[Python] ‘cryptography’ package is required for sha256_password or caching_sha2_password auth methods</title><link>https://quietbo.com/2022/03/30/python-cryptography-package-is-required-for-sha256_password-or-caching_sha2_password-auth-methods/</link><pubDate>Wed, 30 Mar 2022 02:56:35 +0000</pubDate><guid>https://quietbo.com/2022/03/30/python-cryptography-package-is-required-for-sha256_password-or-caching_sha2_password-auth-methods/</guid><description>&lt;p&gt;環境:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;windows10
mysql Ver 8.0.28
python3.7, mysql+pymysql&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;開發時要連線到MySQL時出錯，錯誤訊息如下:&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/Xr9yP8Z.png" alt="" /&gt;&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;cryptography' package is required for sha256_password or caching_sha2_password auth methods"
RuntimeError: 'cryptography' package is required for sha256_password or caching_sha2_password auth methods&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;去google才得知:&lt;br&gt;
MySQL 自8.0+ 版本後，默認的身份認證插件由mysql_native_password 變為了caching_sha2_password,&lt;br&gt;
網上提供的作法，有些答案都是去MySQL中更改默認的認證方式，但我不建議這麼做，原因就是未來部屬時，問題仍有可能會再次出現。&lt;/p&gt;
&lt;p&gt;解決方式:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash line-numbers"&gt;pip3 install cryptography&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;密碼學:&lt;br&gt;
什麼是cryptography?可&lt;a class="link" href="https://cryptography.io/en/latest/" target="_blank" rel="noopener"
 &gt;參考連結&lt;/a&gt;&lt;/p&gt;</description></item><item><title>[Python] LinePay串接Online APIs – 問題 (5/5)</title><link>https://quietbo.com/2022/03/14/python-linepay%E4%B8%B2%E6%8E%A5online-apis-%E5%95%8F%E9%A1%8C-5-5/</link><pubDate>Mon, 14 Mar 2022 05:44:59 +0000</pubDate><guid>https://quietbo.com/2022/03/14/python-linepay%E4%B8%B2%E6%8E%A5online-apis-%E5%95%8F%E9%A1%8C-5-5/</guid><description>&lt;div class="wp-block-image is-style-default"&gt;
 &lt;figure class="aligncenter size-full is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://quietbo.com/uploads/2022/03/chrome_iLlqqg3OhM.png" alt="" class="wp-image-793" width="334" height="119" srcset="https://quietbo.com/uploads/2022/03/chrome_iLlqqg3OhM.png 334w, https://quietbo.com/uploads/2022/03/chrome_iLlqqg3OhM-300x107.png 300w" sizes="auto, (max-width: 334px) 100vw, 334px" /&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;ul class="wp-block-list"&gt;
 &lt;li&gt;
 linepay v2 的Payment-check api 在&lt;a href="chrome-extension://efaidnbmnnnibpcajpcglclefindmkaj/viewer.html?pdfurl=http%3A%2F%2Fwww.hrp.scu.edu.tw%2F.upload%2Fdissertation%2F1498720302032.pdf&amp;clen=3977681&amp;chunk=true"&gt;LINE Pay: Overview&lt;/a&gt;這邊找到的,僅供測試用。
 &lt;/li&gt;
 &lt;li&gt;
 建議開發使用新的版本，目前v3。
 &lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>[Python] LinePay串接Online APIs – 串接v3(含code) (4/5)</title><link>https://quietbo.com/2022/03/14/python-linepay%E4%B8%B2%E6%8E%A5online-apis-%E4%B8%B2%E6%8E%A5v3%E5%90%ABcode-4-5/</link><pubDate>Mon, 14 Mar 2022 05:38:31 +0000</pubDate><guid>https://quietbo.com/2022/03/14/python-linepay%E4%B8%B2%E6%8E%A5online-apis-%E4%B8%B2%E6%8E%A5v3%E5%90%ABcode-4-5/</guid><description>&lt;p&gt;以下測試環境及工具使用:&lt;/p&gt;
&lt;ul class="wp-block-list"&gt;
 &lt;li&gt;
 windows 10
 &lt;/li&gt;
 &lt;li&gt;
 Sandbox
 &lt;/li&gt;
 &lt;li&gt;
 linePay文檔
 &lt;/li&gt;
 &lt;li&gt;
 python 3.7
 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以下使用Request API-&amp;gt; Check Payment Status API -&amp;gt; Confirm API。&lt;/p&gt;
&lt;p&gt;操作流程如下:&lt;/p&gt;
&lt;ol class="wp-block-list"&gt;
 &lt;li&gt;
 channel_id 填入自己的channel id
 &lt;/li&gt;
 &lt;li&gt;
 channel_secret 填入自己的channel secret
 &lt;/li&gt;
 &lt;li&gt;
 開啟瀏覽器貼上付款web_url
 &lt;/li&gt;
 &lt;li&gt;
 付款成功後將最下方的transaction_id填上
 &lt;/li&gt;
 &lt;li&gt;
 重新運行
 &lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;import time
import json
import requests
import hashlib
import hmac
import base64


def get_auth_signature (secret, uri, body, nonce):
 """
 用於製作密鑰
 :param secret: your channel secret
 :param uri: uri
 :param body: request body
 :param nonce: uuid or timestamp(時間戳)
 :return:
 """
 str_sign = secret + uri + body + nonce
 return base64.b64encode(hmac.new(str.encode(secret), str.encode(str_sign), digestmod=hashlib.sha256).digest()).decode("utf-8")

channel_id = "your channel id"
channel_secret = "your channel secret"
uri = "/v3/payments/request"
nonce = str(round(time.time() * 1000)) # nonce = str(uuid.uuid4())
transaction_id = ''

headers = {
 'Content-Type': 'application/json',
 'X-LINE-ChannelId': channel_id,
 'X-LINE-Authorization-Nonce': nonce,
}

def do_request_payment():
 '''此api僅使用文檔中必填的資料'''
 request_options = {
 "amount": 2000,
 "currency": 'TWD',
 "orderId": nonce,
 "packages": [{
 "id": '20220314I001',
 "amount": 2000,
 "name": '鬼滅之刃公仔',
 "products": [{
 "name": '竈門禰豆子',
 "quantity": 1,
 "price": 1000
 },{
 "name": '我妻善逸',
 "quantity": 1,
 "price": 1000
 }]
 }],
 "redirectUrls": {
 "confirmUrl": 'https://quietbo.com/2022/03/14/python-linepay%e4%b8%b2%e6%8e%a5online-apis-%e5%95%8f%e9%a1%8c-5-5/',
 "cancelUrl": 'https://fastapi.tiangolo.com/zh/tutorial/bigger-applications/'
 }
 }
 json_body = json.dumps(request_options)


 headers['X-LINE-Authorization-Nonce'] = nonce
 headers['X-LINE-Authorization'] = get_auth_signature(channel_secret, uri, json_body, nonce)
 response = requests.post("https://sandbox-api-pay.line.me"+uri, headers=headers, data=json_body)
 print(response.text)
 dict_response = json.loads(response.text)

 if dict_response.get('returnCode') == "0000":
 info = dict_response.get('info')
 web_url = info.get('paymentUrl').get('web')
 transaction_id = str(info.get('transactionId'))
 print(f"付款web_url:{web_url}")
 print(f"交易序號:{transaction_id}")

def do_checkout(transaction_id):
 print("transaction_id={}".format(transaction_id))

 conf_data = """{"amount": 2000, "currency": "TWD"}"""
 checkout_url = f"/v3/payments/requests/{transaction_id}/check"
 headers['X-LINE-Authorization'] = get_auth_signature(channel_secret, checkout_url, conf_data, nonce)
 response = requests.get("https://sandbox-api-pay.line.me"+checkout_url, headers=headers, data=conf_data)
 print(response.text)
 response = json.loads(response.text)
 if str(response.get('returnCode')) == "0110":
 return True
 return False

def do_confirm(transaction_id):

 con_url = f"/v3/payments/{transaction_id}/confirm"
 conf_data = """{"amount": 2000, "currency": "TWD"}"""
 headers['X-LINE-Authorization'] = get_auth_signature(channel_secret, con_url, conf_data, nonce)
 response = requests.post("https://sandbox-api-pay.line.me"+con_url, headers=headers, data=conf_data)
 print(response.text)
 response = json.loads(response.text)

 return response.get('returnMessage')

if __name__ == "__main__":
 do_request_payment() # 向linepay請求付款

 # 填入已付款後的交易序號後下方註解拿掉
 # transaction_id = "your transaction_id" # ex: transaction_id = 2022031400707390210
 # status = do_checkout(transaction_id) # 檢查訂單狀態
 # if status == True:
 # print(do_confirm(transaction_id)) # 確認訂單&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>[Python] LinePay串接Online APIs – 後台查看 (3/5)</title><link>https://quietbo.com/2022/03/14/python-linepay%E4%B8%B2%E6%8E%A5online-apis-%E5%BE%8C%E5%8F%B0%E6%9F%A5%E7%9C%8B-3-5/</link><pubDate>Sun, 13 Mar 2022 17:23:22 +0000</pubDate><guid>https://quietbo.com/2022/03/14/python-linepay%E4%B8%B2%E6%8E%A5online-apis-%E5%BE%8C%E5%8F%B0%E6%9F%A5%E7%9C%8B-3-5/</guid><description>&lt;figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-3 is-layout-flex wp-block-gallery-is-layout-flex"&gt; &lt;figure class="wp-block-image size-large"&gt;&lt;img loading="lazy" decoding="async" width="334" height="119" data-id="793" src="https://quietbo.com/uploads/2022/03/chrome_iLlqqg3OhM.png" alt="" class="wp-image-793" srcset="https://quietbo.com/uploads/2022/03/chrome_iLlqqg3OhM.png 334w, https://quietbo.com/uploads/2022/03/chrome_iLlqqg3OhM-300x107.png 300w" sizes="auto, (max-width: 334px) 100vw, 334px" /&gt;&lt;/figure&gt; &lt;/figure&gt; 
&lt;p&gt;&lt;a class="link" href="https://pay.line.me/portal/tw/auth/login#" target="_blank" rel="noopener"
 &gt;linepay測試用後台&lt;/a&gt;&lt;figure class="wp-block-image"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/K45uiot.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;登入後找右上角的「測試環境」&lt;figure class="wp-block-image"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/ALTOU8d.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;右上角可將語言轉成繁體中文&lt;figure class="wp-block-image"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/vmLeYqM.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;左方管理交易-&amp;gt;交易紀錄，可以查看到之前的交易紀錄:&lt;figure class="wp-block-image"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/31RxWwk.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;</description></item><item><title>[Python] LinePay串接Online APIs – 初步了解流程及使用postman測試api v2 (2/5)</title><link>https://quietbo.com/2022/03/14/python-linepay%E4%B8%B2%E6%8E%A5online-apis-%E5%88%9D%E6%AD%A5%E4%BA%86%E8%A7%A3%E6%B5%81%E7%A8%8B%E5%8F%8A%E4%BD%BF%E7%94%A8postman%E6%B8%AC%E8%A9%A6api-v2-2-5/</link><pubDate>Sun, 13 Mar 2022 17:22:34 +0000</pubDate><guid>https://quietbo.com/2022/03/14/python-linepay%E4%B8%B2%E6%8E%A5online-apis-%E5%88%9D%E6%AD%A5%E4%BA%86%E8%A7%A3%E6%B5%81%E7%A8%8B%E5%8F%8A%E4%BD%BF%E7%94%A8postman%E6%B8%AC%E8%A9%A6api-v2-2-5/</guid><description>&lt;p&gt;因有些人只想了解linepay的運作方式, 提供一些簡單可使用的方式。&lt;/p&gt;
&lt;p&gt;以下測試環境及工具使用:&lt;/p&gt;
&lt;ul class="wp-block-list"&gt;
 &lt;li&gt;
 Sandbox
 &lt;/li&gt;
 &lt;li&gt;
 postman
 &lt;/li&gt;
 &lt;li&gt;
 linePay文檔
 &lt;/li&gt;
 &lt;li&gt;
 Online APIs 文檔:&lt;a href="https://pay.line.me/tw/developers/apis/onlineApis?locale=zh_TW"&gt;網址&lt;/a&gt;
 &lt;/li&gt;
 &lt;li&gt;
 按下&lt;a href="https://pay.line.me/documents/online_v2_en.html"&gt;此處&lt;/a&gt; 查看以前的API文件(v2)
 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;本次postman的簡易流程&lt;br&gt;
簡易流程圖&lt;a class="link" href="https://i.imgur.com/N2ftauj.jpg" target="_blank" rel="noopener"
 &gt;網址&lt;/a&gt;&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/N2ftauj.jpg" alt="" /&gt;&lt;/p&gt;
&lt;div id="ez-toc-container" class="ez-toc-v2_0_82_2 ez-toc-wrap-center counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction"&gt;
 &lt;div class="ez-toc-title-container"&gt;
 &lt;p class="ez-toc-title" style="cursor:inherit"&gt;
 Table of Contents
 &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;span class=&amp;quot;ez-toc-title-toggle&amp;quot;&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot; class=&amp;quot;ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle&amp;quot; aria-label=&amp;quot;顯示/隱藏內容目錄&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;ez-toc-js-icon-con&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;eztoc-hide&amp;quot; style=&amp;quot;display:none;&amp;quot;&amp;gt;Toggle&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;ez-toc-icon-toggle-span&amp;quot;&amp;gt;&amp;lt;svg style=&amp;quot;fill: #999;color:#999&amp;quot; xmlns=&amp;quot;http://www.w3.org/2000/svg&amp;quot; class=&amp;quot;list-377408&amp;quot; width=&amp;quot;20px&amp;quot; height=&amp;quot;20px&amp;quot; viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;/path&amp;gt;&amp;lt;/svg&amp;gt;&amp;lt;svg style=&amp;quot;fill: #999;color:#999&amp;quot; class=&amp;quot;arrow-unsorted-368013&amp;quot; xmlns=&amp;quot;http://www.w3.org/2000/svg&amp;quot; width=&amp;quot;10px&amp;quot; height=&amp;quot;10px&amp;quot; viewBox=&amp;quot;0 0 24 24&amp;quot; version=&amp;quot;1.2&amp;quot; baseProfile=&amp;quot;tiny&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;&lt;nav&gt;
 &lt;ul class='ez-toc-list ez-toc-list-level-1 ' &gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-1" href="https://quietbo.com/2022/03/14/python-linepay%e4%b8%b2%e6%8e%a5online-apis-%e5%88%9d%e6%ad%a5%e4%ba%86%e8%a7%a3%e6%b5%81%e7%a8%8b%e5%8f%8a%e4%bd%bf%e7%94%a8postman%e6%b8%ac%e8%a9%a6api-v2-2-5/#%E5%9F%BA%E6%9C%AC%E8%A8%AD%E5%AE%9A" &gt;基本設定&lt;/a&gt;
 &lt;/li&gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-2" href="https://quietbo.com/2022/03/14/python-linepay%e4%b8%b2%e6%8e%a5online-apis-%e5%88%9d%e6%ad%a5%e4%ba%86%e8%a7%a3%e6%b5%81%e7%a8%8b%e5%8f%8a%e4%bd%bf%e7%94%a8postman%e6%b8%ac%e8%a9%a6api-v2-2-5/#request_%E8%AB%8B%E6%B1%82%E8%A8%82%E5%96%AE" &gt;request 請求訂單&lt;/a&gt;
 &lt;/li&gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-3" href="https://quietbo.com/2022/03/14/python-linepay%e4%b8%b2%e6%8e%a5online-apis-%e5%88%9d%e6%ad%a5%e4%ba%86%e8%a7%a3%e6%b5%81%e7%a8%8b%e5%8f%8a%e4%bd%bf%e7%94%a8postman%e6%b8%ac%e8%a9%a6api-v2-2-5/#confirm_%E7%A2%BA%E8%AA%8D" &gt;confirm 確認&lt;/a&gt;
 &lt;/li&gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-4" href="https://quietbo.com/2022/03/14/python-linepay%e4%b8%b2%e6%8e%a5online-apis-%e5%88%9d%e6%ad%a5%e4%ba%86%e8%a7%a3%e6%b5%81%e7%a8%8b%e5%8f%8a%e4%bd%bf%e7%94%a8postman%e6%b8%ac%e8%a9%a6api-v2-2-5/#Check_Payment_Status_%E6%9F%A5%E7%9C%8B%E8%A8%82%E5%96%AE%E7%8B%80%E6%85%8B" &gt;Check Payment Status 查看訂單狀態&lt;/a&gt;
 &lt;/li&gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-5" href="https://quietbo.com/2022/03/14/python-linepay%e4%b8%b2%e6%8e%a5online-apis-%e5%88%9d%e6%ad%a5%e4%ba%86%e8%a7%a3%e6%b5%81%e7%a8%8b%e5%8f%8a%e4%bd%bf%e7%94%a8postman%e6%b8%ac%e8%a9%a6api-v2-2-5/#refurnd_%E9%80%80%E6%AC%BE" &gt;refurnd 退款&lt;/a&gt;
 &lt;/li&gt;
 &lt;/ul&gt;&lt;/nav&gt;
&lt;/div&gt;
&lt;h2 id="基本設定"&gt;&lt;span class="ez-toc-section" id="%E5%9F%BA%E6%9C%AC%E8%A8%AD%E5%AE%9A"&gt;&lt;/span&gt;基本設定&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;請先下載&lt;a class="link" href="https://www.postman.com/" target="_blank" rel="noopener"
 &gt;postman&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;domain&lt;/strong&gt;(v2測試用)&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;https://sandbox-api-pay.line.me/v2/payments&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在現有的&lt;strong&gt;Headers&lt;/strong&gt;添加&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="json" class="language-json line-numbers"&gt;Content-Type:application/json
X-LINE-ChannelId:商戶的Channel ID
X-LINE-ChannelSecret:商戶的Channel Secret&lt;/code&gt;&lt;/pre&gt;&lt;figure class="wp-block-image"&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/xwo8UJj.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="request-請求訂單"&gt;&lt;span class="ez-toc-section" id="request_%E8%AB%8B%E6%B1%82%E8%A8%82%E5%96%AE"&gt;&lt;/span&gt;request 請求訂單&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;API:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;POST {domain}/request&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Request Body:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="json" class="language-json line-numbers"&gt;{
 "amount": 1,
 "currency": "TWD", 
 "productName": "MyProd",
 "productImageUrl": "https://cimg.cnyes.cool/prod/news/4556115/l/79b7b76238dcaa28d626ec007bff576f.jpg",
 "confirmUrl": "http://127.0.0.1:3000",
 "orderId": "Order202203110011"
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Payment Reserve Response:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="json" class="language-json line-numbers"&gt;{
 "returnCode": "0000",
 "returnMessage": "Success.",
 "info": {
 "paymentUrl": {
 "web": "https://sandbox-web-pay.line.me/web/payment/wait?transactionReserveId=WVZub2tRakxRbzk0NWVsa1VMZ1pyTzhOSk00QXJqNXgvbTZIeXZ2NklpL2ZiMHlBUGN4SnJrTG4xVWh6bFA1cg",
 "app": "line://pay/payment/WVZub2tRakxRbzk0NWVsa1VMZ1pyTzhOSk00QXJqNXgvbTZIeXZ2NklpL2ZiMHlBUGN4SnJrTG4xVWh6bFA1cg"
 },
 "transactionId": 2022031100707222710,
 "paymentAccessToken": "785453599850"
 }
}&lt;/code&gt;&lt;/pre&gt;&lt;figure class="wp-block-image"&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/TRf6Xju.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;取得info.paymentUrl.web後, 使用瀏覽器打開如下:&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/KqzzWBQ.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;點擊付款:&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/96WKw9t.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;付款成功如下:&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/iqFRyLj.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;補充:&lt;br&gt;
為什麼結帳後會原本的網頁會出現下圖?&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/fSpv3o3.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;文檔內的說明如下&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;Merchant's URL that the buyer is redirected to after selecting a payment method and entering the payment password in LINE Pay.
On the redirected URL, Merchant can call Confirm Payment API and complete the payment
LINE Pay passes an additional parameter, "transactionId"

Reference Detailed Explanation and Exceptional Case of ConfirmUrl&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;簡單來說就是:想讓結帳完的顧客看到什麼畫面。&lt;/p&gt;
&lt;h2 id="confirm-確認"&gt;&lt;span class="ez-toc-section" id="confirm_%E7%A2%BA%E8%AA%8D"&gt;&lt;/span&gt;confirm 確認&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;API:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;POST {domain}/{transactionId}/confirm&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;範例:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;https://sandbox-api-pay.line.me/v2/payments/2022031400707322810/confirm&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Headers&lt;/strong&gt;添加&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash line-numbers"&gt;X-LINE-MerchantDeviceType: POS
X-LINE-MerchantDeviceProfileId: DUMMY&lt;/code&gt;&lt;/pre&gt;&lt;figure class="wp-block-image"&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/zX0wqPs.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Request Body:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="json" class="language-json line-numbers"&gt;{
 "amount": 1,
 "currency": "TWD"
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Response成功的Json如下:&lt;br&gt;
(補充:此次訂單是重新發起的新的訂單,所以transactionId與orderId會與上面請求訂單時的資料不一樣, 主要目的是呈現成功的結果)&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="json" class="language-json line-numbers"&gt;{
 "returnCode": "0000",
 "returnMessage": "Success.",
 "info": {
 "transactionId": 2022031400707322810,
 "orderId": "dev202203140002",
 "payInfo": [
 {
 "method": "CREDIT_CARD",
 "amount": 1,
 "maskedCreditCardNumber": "************1111"
 }
 ]
 }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;若失敗或是orderId有重複, 則會告知錯誤。&lt;/p&gt;
&lt;h2 id="check-payment-status-查看訂單狀態"&gt;&lt;span class="ez-toc-section" id="Check_Payment_Status_%E6%9F%A5%E7%9C%8B%E8%A8%82%E5%96%AE%E7%8B%80%E6%85%8B"&gt;&lt;/span&gt;Check Payment Status 查看訂單狀態&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;API&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;GET {domain}?transactionId={transactionId}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;範例:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;https://sandbox-api-pay.line.me/v2/payments?transactionId=2022031400707322810&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Response成功的Json如下:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="json" class="language-json line-numbers"&gt;{
 "returnCode": "0000",
 "returnMessage": "Success.",
 "info": [
 {
 "transactionId": 2022031400707322810,
 "transactionDate": "2022-03-13T16:11:08Z",
 "transactionType": "PAYMENT",
 "productName": "MyProd",
 "currency": "TWD",
 "payInfo": [
 {
 "method": "CREDIT_CARD",
 "amount": 1
 }
 ],
 "orderId": "dev202203140002"
 }
 ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意:&lt;br&gt;
正常來說是要先檢查是否付款後才執行confirm這支API，但因為v2是需要先進行confirm這支API才有辦法使用，否則會出現:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="json" class="language-json line-numbers"&gt;{
 "returnCode": "1150",
 "returnMessage": "Transaction record not found."
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;若是使用v3則可正常先進行Check Payment Status 後再進行確認。&lt;/p&gt;
&lt;h2 id="refurnd-退款"&gt;&lt;span class="ez-toc-section" id="refurnd_%E9%80%80%E6%AC%BE"&gt;&lt;/span&gt;refurnd 退款&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;取消已付款的交易。&lt;/p&gt;
&lt;p&gt;API:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;POST {dimain}/{transactionId}/refund&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Headers&lt;/strong&gt;添加&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash line-numbers"&gt;X-LINE-MerchantDeviceType: POS
X-LINE-MerchantDeviceProfileId: DUMMY&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;refundAmount: 退款金額&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="json" class="language-json line-numbers"&gt;{
 "refundAmount": 1
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Response:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="json" class="language-json line-numbers"&gt;{
 "returnCode": "0000",
 "returnMessage": "Success.",
 "info": {
 "refundTransactionId": 2022031400707327211,
 "refundTransactionDate": "2022-03-13T17:05:50Z"
 }
}&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>[Python] LinePay串接Online APIs – 申請測試帳號 (1/5)</title><link>https://quietbo.com/2022/03/14/python-linepay%E4%B8%B2%E6%8E%A5online-apis-%E7%94%B3%E8%AB%8B%E6%B8%AC%E8%A9%A6%E5%B8%B3%E8%99%9F-1-5/</link><pubDate>Sun, 13 Mar 2022 17:17:51 +0000</pubDate><guid>https://quietbo.com/2022/03/14/python-linepay%E4%B8%B2%E6%8E%A5online-apis-%E7%94%B3%E8%AB%8B%E6%B8%AC%E8%A9%A6%E5%B8%B3%E8%99%9F-1-5/</guid><description>&lt;p&gt;以下測試環境使用:&lt;/p&gt;
&lt;ul class="wp-block-list"&gt;
 &lt;li&gt;
 Sandbox
 &lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="一創建sandbox帳號"&gt;一、創建Sandbox帳號
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://pay.line.me/tw/developers/techsupport/sandbox/testflow?locale=zh_TW" target="_blank" rel="noopener"
 &gt;測試流程文件網址&lt;/a&gt;&lt;/p&gt;
&lt;ul class="wp-block-list"&gt;
 &lt;li&gt;
 LinePay建立Sandbox:&lt;a href="https://pay.line.me/tw/developers/techsupport/sandbox/testflow?locale=zh_TW"&gt;Sandbox網址&lt;/a&gt;
 &lt;/li&gt;
 &lt;li&gt;
 正式LinePay商戶請使用:&lt;a href="https://pay.line.me/portal/tw/main?isFooterConventionChanged=true"&gt;網址&lt;/a&gt;
 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;填入下方訊息, 及使用中的信箱, 此處我是使用與line相同的信箱，若是以有相同信箱會跳出:此email已註冊過Sandbox ID。請輸入其他email以註冊Sandbox。&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/wxZlyNd.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;創建成功如下圖(有興趣可自行點擊後查看)&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/TyR7AIv.png" alt="" /&gt;&lt;/p&gt;
&lt;h2 id="二收信並登入商家"&gt;二、收信並登入商家
&lt;/h2&gt;&lt;p&gt;到信箱收信如下:&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/agbkGVt.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;使用剛才收到的來登入Merchant Center:&lt;a class="link" href="https://pay.line.me/portal/tw/auth/login#" target="_blank" rel="noopener"
 &gt;網址&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;使用收到的測試帳號及密碼登入&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/ABRSthV.png" alt="" /&gt;&lt;/p&gt;
&lt;h2 id="三取得channel-id及channel-secret-key"&gt;三、取得Channel ID及Channel Secret Key &lt;figure class="wp-block-image"&gt;
&lt;/h2&gt;&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/xVp3hpJ.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;紅框內的要保留好, 不要外流。&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/hcN9p8I.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;補充:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;Sandbox: 指測試帳號的url及後台等等環境
v2/v3指的是在串接api時的linepay版本&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>[Python 3.6] f-Strings (字串雙引號前加f)</title><link>https://quietbo.com/2022/02/21/python-3-6-f-strings-%E5%AD%97%E4%B8%B2%E9%9B%99%E5%BC%95%E8%99%9F%E5%89%8D%E5%8A%A0f/</link><pubDate>Mon, 21 Feb 2022 07:03:38 +0000</pubDate><guid>https://quietbo.com/2022/02/21/python-3-6-f-strings-%E5%AD%97%E4%B8%B2%E9%9B%99%E5%BC%95%E8%99%9F%E5%89%8D%E5%8A%A0f/</guid><description>&lt;p&gt;Python 3.6之前式字串格式化:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;str.format()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;處理多個引數和更長的字串時，程式碼很冗長&lt;/p&gt;
&lt;p&gt;f-Strings 比 %-formatting 和 str.format()更輕鬆，且更快。&lt;br&gt;
大小寫f都可以使用:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="basic" class="language-basic"&gt;&amp;gt;&amp;gt;&amp;gt; name = "Bocky"
&amp;gt;&amp;gt;&amp;gt; age = 18
&amp;gt;&amp;gt;&amp;gt; f"name={name}, age={age}"
'name=Bocky, age=18'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;也可以運算:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;&amp;gt;&amp;gt;&amp;gt; f"{2*100}"
'200'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用function:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;&amp;gt;&amp;gt;&amp;gt; def to_lowercase(input):
... return input.lower()
...
&amp;gt;&amp;gt;&amp;gt; name = "BOCKY"
&amp;gt;&amp;gt;&amp;gt; f"{to_lowercase(name)} is funny."
'bocky is funny.'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a class="link" href="https://docs.python.org/3/reference/lexical_analysis.html#f-strings" target="_blank" rel="noopener"
 &gt;文檔:2.4.3. Formatted string literals&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://iter01.com/585538.html" target="_blank" rel="noopener"
 &gt;參考2&lt;/a&gt;&lt;/p&gt;</description></item><item><title>[Python] 不打印轉義字符串，字串不轉義處理(\t\f)</title><link>https://quietbo.com/2022/02/17/python-%E4%B8%8D%E6%89%93%E5%8D%B0%E8%BD%89%E7%BE%A9%E5%AD%97%E7%AC%A6%E4%B8%B2%EF%BC%8C%E5%AD%97%E4%B8%B2%E4%B8%8D%E8%BD%89%E7%BE%A9%E8%99%95%E7%90%86tf/</link><pubDate>Thu, 17 Feb 2022 07:26:33 +0000</pubDate><guid>https://quietbo.com/2022/02/17/python-%E4%B8%8D%E6%89%93%E5%8D%B0%E8%BD%89%E7%BE%A9%E5%AD%97%E7%AC%A6%E4%B8%B2%EF%BC%8C%E5%AD%97%E4%B8%B2%E4%B8%8D%E8%BD%89%E7%BE%A9%E8%99%95%E7%90%86tf/</guid><description>&lt;ol class="wp-block-list"&gt;
 &lt;li&gt;
 在轉義字符前多加一個\
 &lt;/li&gt;
 &lt;li&gt;
 字符串前面加上&amp;#8217;r&amp;#8217;
 &lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;print('123\n123\t123')&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;結果如下:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;123
123 123&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在轉義字符前多加一個（\）&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;print('123\\n123\\t123')&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;結果如下:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;123\n123\t123&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用r，整個字串不轉義&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;print(r'123\n123\t123')&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;結果如下:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;123\n123\t123&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="範例.wp-block-heading"&gt;範例
&lt;/h2&gt;&lt;p&gt;最需要注意的是，如果再windows下，如果不使用r，使用\t會出現下圖&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;C:\\Dev\\mytoolbox\\myfile\\testfile.txt&lt;/code&gt;&lt;/pre&gt;
&lt;img decoding="async" src="https://i.imgur.com/SCoKLFT.png" alt="" /&gt; 
會發現\t變成一個tab的功能，但若使用r的話即可解決</description></item><item><title>[Python] File “manage.py”, line 17 ) from exc ^ SyntaxError: invalid syntax (已解決)</title><link>https://quietbo.com/2022/01/17/python-file-manage-py-line-17-from-exc-syntaxerror-invalid-syntax-%E5%B7%B2%E8%A7%A3%E6%B1%BA/</link><pubDate>Mon, 17 Jan 2022 10:27:31 +0000</pubDate><guid>https://quietbo.com/2022/01/17/python-file-manage-py-line-17-from-exc-syntaxerror-invalid-syntax-%E5%B7%B2%E8%A7%A3%E6%B1%BA/</guid><description>&lt;p&gt;我在env內，有python2.7與python3.8。&lt;br&gt;
當使用 python 運行命令時，Django 無法預測確切的 python 版本。&lt;/p&gt;
&lt;p&gt;執行下列指令後出現錯誤:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;python manage.py runserver&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;問題訊息如下:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt; File "manage.py", line 17
 ) from exc
 ^
SyntaxError: invalid syntax&lt;/code&gt;&lt;/pre&gt;&lt;figure class="wp-block-image"&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/nzdZu0Z.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;解決方式:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;python3 manage.py runserver
python3 manage.py runserver 0.0.0.0:8899 # 轉port為8899&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;參考:&lt;a class="link" href="https://stackoverflow.com/questions/42611593/how-to-solve-syntaxerror-on-autogenerated-manage-py" target="_blank" rel="noopener"
 &gt;How to solve SyntaxError on autogenerated manage.py?&lt;/a&gt;&lt;/p&gt;</description></item><item><title>[Mac|M1] ModuleNotFoundError: No module named ‘pip._internal.cli.main’ (已解決)</title><link>https://quietbo.com/2022/01/17/macm1-modulenotfounderror-no-module-named-pip-_internal-cli-main-%E5%B7%B2%E8%A7%A3%E6%B1%BA/</link><pubDate>Mon, 17 Jan 2022 07:01:50 +0000</pubDate><guid>https://quietbo.com/2022/01/17/macm1-modulenotfounderror-no-module-named-pip-_internal-cli-main-%E5%B7%B2%E8%A7%A3%E6%B1%BA/</guid><description>&lt;p&gt;問題訊息如下:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;$ pip install --upgrade pip
Traceback (most recent call last):
 File "/usr/local/bin/pip", line 6, in &amp;lt;module&amp;gt;
 from pip._internal.cli.main import main
ModuleNotFoundError: No module named 'pip._internal.cli.main'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;解決方式:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash line-numbers"&gt;curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python3 get-pip.py --force-reinstall&lt;/code&gt;&lt;/pre&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;Defaulting to user installation because normal site-packages is not writeable
Collecting pip
 Using cached pip-21.3.1-py3-none-any.whl (1.7 MB)
Installing collected packages: pip
 WARNING: The scripts pip, pip3 and pip3.8 are installed in '/Users/bocky/Library/Python/3.8/bin' which is not on PATH.
 Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed pip-21.3.1
WARNING: You are using pip version 19.2.3; however, version 21.3.1 is available.
You should consider upgrading via the '/Applications/Xcode.app/Contents/Developer/usr/bin/python3 -m pip install --upgrade pip' command.&lt;/code&gt;&lt;/pre&gt;&lt;figure class="wp-block-image"&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/ZxKs6aB.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;訊息告知建議執行的內容:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash line-numbers"&gt;/Applications/Xcode.app/Contents/Developer/usr/bin/python3 -m pip install --upgrade pip&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下方為執行結果:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;Defaulting to user installation because normal site-packages is not writeable
Requirement already satisfied: pip in ./Library/Python/3.8/lib/python/site-packages (21.3.1)&lt;/code&gt;&lt;/pre&gt;&lt;figure class="wp-block-image"&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/LwzulX6.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;解決!&lt;/p&gt;</description></item><item><title>[Python] Django第一個Urls與View</title><link>https://quietbo.com/2021/11/28/python-django%E7%AC%AC%E4%B8%80%E5%80%8Burls%E8%88%87view/</link><pubDate>Sun, 28 Nov 2021 09:13:19 +0000</pubDate><guid>https://quietbo.com/2021/11/28/python-django%E7%AC%AC%E4%B8%80%E5%80%8Burls%E8%88%87view/</guid><description>&lt;ol class="wp-block-list"&gt;
 &lt;li&gt;
 定義視圖函數&lt;br /&gt;books\views.py:
 &lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;from django.shortcuts import render
from django.http import HttpResponse

#定義視圖函數
def hello(request):
 return HttpResponse("&amp;lt;h1&amp;gt;Hello, world.世界你好.&amp;lt;/h1&amp;gt;")&lt;/code&gt;&lt;/pre&gt;
&lt;ol class="wp-block-list" start="2"&gt;
 &lt;li&gt;
 修改項目(mydjango) urls.py文件
 &lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;from django.contrib import admin
from django.urls import path, include

urlpatterns = [
 path('books/', include('books.urls')),
 path('admin/', admin.site.urls),
]&lt;/code&gt;&lt;/pre&gt;
&lt;ol class="wp-block-list" start="3"&gt;
 &lt;li&gt;
 在books的資料夾新增 urls.py文件
 &lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;from django.urls import path
from . import views

urlpatterns = [
 path('hello/', views.hello, name='hello'),
]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;建立完成後的資料如下，執行&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;python manage.py runserver&lt;/code&gt;&lt;/pre&gt;&lt;figure class="wp-block-image"&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/A4uX13g.png" alt="" /&gt; &lt;/figure&gt; &lt;figure class="wp-block-image"&gt;&lt;img decoding="async" src="https://i.imgur.com/gkEr4Ol.png" alt="" /&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;開啟瀏覽器，輸入&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;http://127.0.0.1:8000/books/hello/&lt;/code&gt;&lt;/pre&gt;&lt;figure class="wp-block-image"&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/cjoWs3K.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="url配置"&gt;URL配置
&lt;/h2&gt;&lt;ol class="wp-block-list"&gt;
 &lt;li&gt;
 urlpatterns: 路由模式列表,通過URL模式映射到視圖
 &lt;/li&gt;
 &lt;li&gt;
 path函數： 返回urlpatterns元素&lt;br /&gt;定義：path(route, view, kwargs=None, name=None)&lt;br /&gt;route：路由模式,&lt;br /&gt;view:可以是視圖函數、視圖類或include函數返回值&lt;br /&gt;path(&amp;#8221;, views.home, name=&amp;#8217;home&amp;#8217;)&lt;br /&gt;path(&amp;#8221;, Home.as_view(), name=&amp;#8217;home&amp;#8217;)&lt;br /&gt;path(&amp;#8216;blog/&amp;#8217;, include(&amp;#8216;blog.urls&amp;#8217;))
 &lt;/li&gt;
 &lt;li&gt;
 include函數：導入其他的模塊,include(&amp;#8216;books.urls&amp;#8217;)是導入books.urls模塊
 &lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>[Python] 創建一個Django專案</title><link>https://quietbo.com/2021/11/16/python-%E5%89%B5%E5%BB%BA%E4%B8%80%E5%80%8Bdjango%E5%B0%88%E6%A1%88/</link><pubDate>Mon, 15 Nov 2021 16:08:12 +0000</pubDate><guid>https://quietbo.com/2021/11/16/python-%E5%89%B5%E5%BB%BA%E4%B8%80%E5%80%8Bdjango%E5%B0%88%E6%A1%88/</guid><description>&lt;p&gt;使用：Mac M1&lt;br&gt;
Python 3.8&lt;br&gt;
Django:3.2&lt;/p&gt;
&lt;h2 id="建立環境"&gt;建立環境
&lt;/h2&gt;&lt;p&gt;可參考：&lt;a class="link" href="https://quietbo.com/2021/06/27/mac-pro-m1-%e5%ae%89%e8%a3%9dvirtualenv/" target="_blank" rel="noopener"
 &gt;安裝virtualenv&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;進入env後，安裝及查看Django版本：&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;pip install django
pip list&lt;/code&gt;&lt;/pre&gt;&lt;figure class="wp-block-image"&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/YDA0rRK.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="建立專案"&gt;建立專案
&lt;/h2&gt;&lt;p&gt;尋找一個位置，建立第一個專案：&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;django-admin startproject mydjango&lt;/code&gt;&lt;/pre&gt;
&lt;img decoding="async" src="https://i.imgur.com/33w2bsR.png" alt="" /&gt; 
創建的資料結構如下： 
&lt;img decoding="async" src="https://i.imgur.com/AREpKuM.png" alt="" /&gt; 
&lt;p&gt;執行方式：&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;python manage.py runserver&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;若想更改默認端口：&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;python manage.py runserver 0.0.0.0:8899&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;執行成功如下圖：&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/T83LNyC.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;開啟瀏覽器，輸入：&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;http://127.0.0.1:8000/&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;第一次運行，會看到下圖畫面：&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/xIuSCBD.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;停止方式：Control + C&lt;/p&gt;
&lt;p&gt;此時，會多出現一個檔案db.sqlite3&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/2pFmXot.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Django主要提供了四種數據庫引擎：&lt;/p&gt;
&lt;ol class="wp-block-list"&gt;
 &lt;li&gt;
 django.db.backends.postgresql
 &lt;/li&gt;
 &lt;li&gt;
 django.db.backends.mysql
 &lt;/li&gt;
 &lt;li&gt;
 django.db.backends.sqlite3
 &lt;/li&gt;
 &lt;li&gt;
 django.db.backends.oracle
 &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;打開setting.py會看到默認引擎是sqlite3，&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases

DATABASES = {
 'default': {
 'ENGINE': 'django.db.backends.sqlite3',
 'NAME': BASE_DIR / 'db.sqlite3',
 }
}&lt;/code&gt;&lt;/pre&gt;&lt;figure class="wp-block-image"&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/pcR3yH3.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;MySQL設置方式:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;DATABASES = {
 'default': {
 'ENGINE': 'django.db.backends.mysql',
 'NAME': 'djangodb',
 'USER': 'root',
 'PASSWORD': '12345',
 'HOST': '127.0.0.1',
 }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果需要更多的配置信息，可以指定配置文件：&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;DATABASES = {
 'default': {
 'ENGINE': 'django.db.backends.mysql',
 'OPTIONS':{
 'read_default_file': '/path/to/my.cnf',
 },
 }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配置文件：&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;# my.cnf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[client]&lt;/p&gt;
&lt;p&gt;databases = djangodb user = root password = 12345 default-character-set=utf8&lt;/p&gt;
&lt;p&gt;PostgreSQL數據庫配置:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;DATABASES = {
 'default': {
 'ENGINE': 'django.db.backends.postgresql',
 'NAME': 'mydatabase',
 'USER': 'mydatabaseuser',
 'PASSWORD': 'mypassword',
 'HOST': '127.0.0.1',
 'PORT': '5432',
 }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;初始化：&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;python manage.py migrate&lt;/code&gt;&lt;/pre&gt;&lt;figure class="wp-block-image"&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/udBptue.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;h3 id="創建應用程序"&gt;創建應用程序
&lt;/h3&gt;&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;python manage.py startapp books&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;生成books，如下的資料結構&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;.
├── books
│&amp;nbsp;&amp;nbsp; ├── __init__.py
│&amp;nbsp;&amp;nbsp; ├── admin.py
│&amp;nbsp;&amp;nbsp; ├── apps.py
│&amp;nbsp;&amp;nbsp; ├── migrations
│&amp;nbsp;&amp;nbsp; │&amp;nbsp;&amp;nbsp; └── __init__.py
│&amp;nbsp;&amp;nbsp; ├── models.py
│&amp;nbsp;&amp;nbsp; ├── tests.py
│&amp;nbsp;&amp;nbsp; └── views.py
├── db.sqlite3
├── manage.py
└── mydjango
 ├── __init__.py
 ├── asgi.py
 ├── settings.py
 ├── urls.py
 └── wsgi.py&lt;/code&gt;&lt;/pre&gt;&lt;figure class="wp-block-image"&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/RbOLpWV.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;ul class="wp-block-list"&gt;
 &lt;li&gt;
 admin :網站管理設置
 &lt;/li&gt;
 &lt;li&gt;
 apps :註冊應用相關
 &lt;/li&gt;
 &lt;li&gt;
 migration ：數據庫的升級文件包，會自動升級專案的數據庫
 &lt;/li&gt;
 &lt;li&gt;
 models ：定義模型
 &lt;/li&gt;
 &lt;li&gt;
 tests :測試相關代碼
 &lt;/li&gt;
 &lt;li&gt;
 views ：定義視圖函式
 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;主要程式撰寫是在views及models&lt;/p&gt;</description></item><item><title>[Python] break、continue、pass、return及exit的用法與區別</title><link>https://quietbo.com/2021/11/05/python-break%E3%80%81continue%E3%80%81pass%E3%80%81return%E5%8F%8Aexit%E7%9A%84%E7%94%A8%E6%B3%95%E8%88%87%E5%8D%80%E5%88%A5/</link><pubDate>Thu, 04 Nov 2021 16:53:04 +0000</pubDate><guid>https://quietbo.com/2021/11/05/python-break%E3%80%81continue%E3%80%81pass%E3%80%81return%E5%8F%8Aexit%E7%9A%84%E7%94%A8%E6%B3%95%E8%88%87%E5%8D%80%E5%88%A5/</guid><description>&lt;ul class="wp-block-list"&gt;
 &lt;li&gt;
 break 結束循環語句
 &lt;/li&gt;
 &lt;li&gt;
 continue 跳出本次循環，繼續下一個循環
 &lt;/li&gt;
 &lt;li&gt;
 pass 不做任何事情，站位而已
 &lt;/li&gt;
 &lt;li&gt;
 return 退出整個函數(def)
 &lt;/li&gt;
 &lt;li&gt;
 exit 結束整個程序(進程)
 &lt;/li&gt;
&lt;/ul&gt;
&lt;div id="ez-toc-container" class="ez-toc-v2_0_82_2 ez-toc-wrap-center counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction"&gt;
 &lt;div class="ez-toc-title-container"&gt;
 &lt;p class="ez-toc-title" style="cursor:inherit"&gt;
 Table of Contents
 &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;span class=&amp;quot;ez-toc-title-toggle&amp;quot;&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot; class=&amp;quot;ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle&amp;quot; aria-label=&amp;quot;顯示/隱藏內容目錄&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;ez-toc-js-icon-con&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;eztoc-hide&amp;quot; style=&amp;quot;display:none;&amp;quot;&amp;gt;Toggle&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;ez-toc-icon-toggle-span&amp;quot;&amp;gt;&amp;lt;svg style=&amp;quot;fill: #999;color:#999&amp;quot; xmlns=&amp;quot;http://www.w3.org/2000/svg&amp;quot; class=&amp;quot;list-377408&amp;quot; width=&amp;quot;20px&amp;quot; height=&amp;quot;20px&amp;quot; viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;/path&amp;gt;&amp;lt;/svg&amp;gt;&amp;lt;svg style=&amp;quot;fill: #999;color:#999&amp;quot; class=&amp;quot;arrow-unsorted-368013&amp;quot; xmlns=&amp;quot;http://www.w3.org/2000/svg&amp;quot; width=&amp;quot;10px&amp;quot; height=&amp;quot;10px&amp;quot; viewBox=&amp;quot;0 0 24 24&amp;quot; version=&amp;quot;1.2&amp;quot; baseProfile=&amp;quot;tiny&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;&lt;nav&gt;
 &lt;ul class='ez-toc-list ez-toc-list-level-1 ' &gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-1" href="https://quietbo.com/2021/11/05/python-break%e3%80%81continue%e3%80%81pass%e3%80%81return%e5%8f%8aexit%e7%9a%84%e7%94%a8%e6%b3%95%e8%88%87%e5%8d%80%e5%88%a5/#break" &gt;break&lt;/a&gt;
 &lt;/li&gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-2" href="https://quietbo.com/2021/11/05/python-break%e3%80%81continue%e3%80%81pass%e3%80%81return%e5%8f%8aexit%e7%9a%84%e7%94%a8%e6%b3%95%e8%88%87%e5%8d%80%e5%88%a5/#continue" &gt;continue&lt;/a&gt;
 &lt;/li&gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-3" href="https://quietbo.com/2021/11/05/python-break%e3%80%81continue%e3%80%81pass%e3%80%81return%e5%8f%8aexit%e7%9a%84%e7%94%a8%e6%b3%95%e8%88%87%e5%8d%80%e5%88%a5/#pass" &gt;pass&lt;/a&gt;
 &lt;/li&gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-4" href="https://quietbo.com/2021/11/05/python-break%e3%80%81continue%e3%80%81pass%e3%80%81return%e5%8f%8aexit%e7%9a%84%e7%94%a8%e6%b3%95%e8%88%87%e5%8d%80%e5%88%a5/#return" &gt;return&lt;/a&gt;
 &lt;/li&gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-5" href="https://quietbo.com/2021/11/05/python-break%e3%80%81continue%e3%80%81pass%e3%80%81return%e5%8f%8aexit%e7%9a%84%e7%94%a8%e6%b3%95%e8%88%87%e5%8d%80%e5%88%a5/#exit" &gt;exit&lt;/a&gt;
 &lt;/li&gt;
 &lt;/ul&gt;&lt;/nav&gt;
&lt;/div&gt;
&lt;h2 id="break"&gt;&lt;span class="ez-toc-section" id="break"&gt;&lt;/span&gt;break&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;用來終止循環語句，即使循環條件沒有False或者序列還沒被完全遞歸完，也會停止執行循環語句。&lt;/p&gt;
&lt;p&gt;break語句用在while和for循環中。&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;def config():
 for num in '12345':
 if num == '3':
 break
 print('當前數字:', num)
 print('=' * 10)

config()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;結果如下：&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;當前數字: 1
當前數字: 2
==========&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="continue"&gt;&lt;span class="ez-toc-section" id="continue"&gt;&lt;/span&gt;continue&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;continue 語句跳出&lt;strong&gt;本次&lt;/strong&gt;循環，然後繼續進行下一輪循環。&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;def config():
 for num in '12345':
 if num == '3':
 continue
 print('當前數字:', num)
 print('=' * 10)

config()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;輸出結果：當for迴圈到3時，被跳過了。&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;當前數字: 1
當前數字: 2
當前數字: 4
當前數字: 5
==========&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="pass"&gt;&lt;span class="ez-toc-section" id="pass"&gt;&lt;/span&gt;pass&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;空語句，pass 不做任何事情，一般用做佔位語句，是為了保持程序結構的完整性。&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python"&gt;def config():
 for num in '12345':
 if num == '3':
 pass
 print('當前數字:', num)
 print('=' * 10)

config()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;結果如下：&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;當前數字: 1
當前數字: 2
當前數字: 3
當前數字: 4
當前數字: 5
==========&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;補充：&lt;/p&gt;
&lt;blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"&gt;
 &lt;p&gt;
 為什麼要站位？
 &lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;事實上站位就是要先預留位置，回頭再補上具體的代碼實現。
很多時候我們在開發的時候，會把已知的判斷條件或函式寫好，然後在對應的塊中寫上pass，後續再慢慢完善這些站位的部分。&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="return"&gt;&lt;span class="ez-toc-section" id="return"&gt;&lt;/span&gt;return&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;return 語句就是將結果返回到調用的地方，並把控制權也一起返回。&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python"&gt;def config():
 for num in '12345':
 if num == '3':
 return f'for迴圈在 {num} 時回傳了'
 print('當前數字:', num)
 print('=' * 10)

print(config())
print('上方function已返回')&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;結果如下：&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;當前數字: 1
當前數字: 2
for迴圈在 3 時回傳了
上方function已返回&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="exit"&gt;&lt;span class="ez-toc-section" id="exit"&gt;&lt;/span&gt;exit&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;用來結束整個程序（進程）。&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python"&gt;def config():
 for num in '12345':
 if num == '3':
 exit()
 print('當前數字:', num)
 print('=' * 10)

config()
print('*' * 10) #程式已結束所以不會印出&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;顯示如下：&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;當前數字: 1
當前數字: 2&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>[Python] 有序的Dict – OrderedDict (必學)</title><link>https://quietbo.com/2021/07/22/python-%E6%9C%89%E5%BA%8F%E7%9A%84dict-ordereddict-%E5%BF%85%E5%AD%B8/</link><pubDate>Wed, 21 Jul 2021 17:00:01 +0000</pubDate><guid>https://quietbo.com/2021/07/22/python-%E6%9C%89%E5%BA%8F%E7%9A%84dict-ordereddict-%E5%BF%85%E5%AD%B8/</guid><description>&lt;p&gt;特性:&lt;strong&gt;依據key被插入的先後做排序，如果更新了某個key的值，不會影響排序位置，除非是把key刪除後又重新插入。後續加入的key都會從最末做添加&lt;/strong&gt;。&lt;br&gt;
本篇沒做增刪查改的範例。&lt;/p&gt;
&lt;h2 id="dict一般常用的"&gt;dict(一般常用的)
&lt;/h2&gt;&lt;p&gt;一般常用的dict都會說是無序，但其實還是有一定的順序，是&lt;strong&gt;按照hash來存儲的，和存儲的數據結構有關&lt;/strong&gt;(本篇不多說明)，但通常這個跟我們一般認真的序列有一點不一樣，因為不是填入時的順序。&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;example_dict = dict(
 name='Bocky',
 phone='0912-345-678',
 address='Taiwan-Taipei',
 age='18'
)
print(example_dict)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;輸出結果:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="" class=" line-numbers"&gt;{'phone': '0912-345-678', 'age': '18', 'name': 'Bocky', 'address': 'Taiwan-Taipei'}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="ordereddict"&gt;OrderedDict
&lt;/h2&gt;&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;from collections import OrderedDict
import json
# 錯誤示範，沒有照順序排列的效果(與一般dict結果一樣)
example_ordered_dict_0 = OrderedDict(
 name='Bocky',
 phone='0912-345-678',
 address='Taiwan-Taipei',
 age='18'
)
print('錯誤示範的輸出:\n{}'.format(example_ordered_dict_0))
print("="*20)

example_ordered_dict_1 = OrderedDict([
 ('name', 'Bocky'),
 ('phone_number', '0912-345-678'),
 ('address', 'Taiwan-Taipei'),
 ('age', '18')
])
print("OrderedDict輸出結果:\n{}".format(example_ordered_dict_1))
print("="*20)

print("添加一個key為interest到最末端:")
example_ordered_dict_1['interest'] = 'sleep'
print(example_ordered_dict_1)
print("="*20)

print("把OrderedDict轉成字串,並剔除空白:")
print (json.dumps(example_ordered_dict_1).replace(" ", ""))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;輸出結果:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="" class=" line-numbers"&gt;錯誤示範的輸出:
OrderedDict([('phone', '0912-345-678'), ('age', '18'), ('name', 'Bocky'), ('address', 'Taiwan-Taipei')])
====================
OrderedDict輸出結果:
OrderedDict([('name', 'Bocky'), ('phone_number', '0912-345-678'), ('address', 'Taiwan-Taipei'), ('age', '18')])
====================
添加一個key為interest到最末端:
OrderedDict([('name', 'Bocky'), ('phone_number', '0912-345-678'), ('address', 'Taiwan-Taipei'), ('age', '18'), ('interest', 'sleep')])
====================
把OrderedDict轉成字串,並剔除空白:
{"name":"Bocky","phone_number":"0912-345-678","address":"Taiwan-Taipei","age":"18","interest":"sleep"}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果是要a~z排序的話就使用sorted，網路上很多參考，但這就不需要使用OrderedDict了，一般dict就可以做到，只是排序拼接而已，我自己工作上是很常用:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="" class=" line-numbers"&gt;data = "&amp;".join("{0}={1}".format(str(k), str(example_ordered_dict_1[k])) for k in sorted(example_ordered_dict_1.keys()))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;輸出結果:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="" class=""&gt;address=Taiwan-Taipei&amp;age=18&amp;interest=sleep&amp;name=Bocky&amp;phone_number=0912-345-678&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>[安裝]Mac pro M1 安裝virtualenv</title><link>https://quietbo.com/2021/06/27/mac-pro-m1-%E5%AE%89%E8%A3%9Dvirtualenv/</link><pubDate>Sun, 27 Jun 2021 11:55:45 +0000</pubDate><guid>https://quietbo.com/2021/06/27/mac-pro-m1-%E5%AE%89%E8%A3%9Dvirtualenv/</guid><description>&lt;p&gt;目前自帶版本有:&lt;br&gt;
Python 2.7.16&lt;br&gt;
Python 3.8.2&lt;/p&gt;
&lt;p&gt;查詢路徑：&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash line-numbers"&gt;which python3 # which python&lt;/code&gt;&lt;/pre&gt;&lt;figure class="wp-block-image"&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/cjtmWq2.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;ol class="wp-block-list"&gt;
 &lt;li&gt;
 安裝virtualenv&lt;br /&gt;用pip就可以安裝 virtualenv，可以同時用在 Python 2 和 3，
 &lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash line-numbers"&gt;pip install virtualenv&lt;/code&gt;&lt;/pre&gt;
&lt;ol class="wp-block-list" start="2"&gt;
 &lt;li&gt;
 創建虛擬環境
 &lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash line-numbers"&gt;mkdir work_venv # 建立一個名為work_venv的資料夾
python3 -m virtualenv XXXvenv # 創建名為XXvenv的虛擬機&lt;/code&gt;&lt;/pre&gt;&lt;figure class="wp-block-image"&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/PXPLVuo.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;ol class="wp-block-list" start="3"&gt;
 &lt;li&gt;
 進入/安裝模組/離開虛擬環境
 &lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash line-numbers"&gt;source XXvenv/bin/activate

# 進到虛擬環境，最前面就會多（XXvenv）
pip list&lt;/code&gt;&lt;/pre&gt;&lt;figure class="wp-block-image"&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/unecAMW.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash line-numbers"&gt;pip install XXXX # 安裝模組
pip install -r requirements.txt # 導入requirements.txt(路徑自行填寫)
deactivate # 離開虛擬環境&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>[Python]字串轉型態ast.literal_eval，且為什麼不建議eval(必學)</title><link>https://quietbo.com/2021/06/03/python-%E5%AD%97%E4%B8%B2%E8%BD%89%E5%9E%8B%E6%85%8Bast-literal_eval%EF%BC%8C%E4%B8%94%E7%82%BA%E4%BB%80%E9%BA%BC%E4%B8%8D%E5%BB%BA%E8%AD%B0eval%E5%BF%85%E5%AD%B8/</link><pubDate>Thu, 03 Jun 2021 09:40:06 +0000</pubDate><guid>https://quietbo.com/2021/06/03/python-%E5%AD%97%E4%B8%B2%E8%BD%89%E5%9E%8B%E6%85%8Bast-literal_eval%EF%BC%8C%E4%B8%94%E7%82%BA%E4%BB%80%E9%BA%BC%E4%B8%8D%E5%BB%BA%E8%AD%B0eval%E5%BF%85%E5%AD%B8/</guid><description>&lt;p&gt;三分鐘學習一個小知識，還有範例直接看!&lt;/p&gt;
&lt;p&gt;當python在做型態轉換，str轉dict、list、tuple、set或是int時，有些人會使用eval 或 ast.literal_eval，但eval是不推的，安全性是其中重要的原因。&lt;br&gt;
若要單純轉換型態，我。&lt;/p&gt;
&lt;p&gt;稍微講一下eval會說是危險原因:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;# coding:utf-8

"""
輸入下方指令:
"1000"
"1+3"
"[0, 1, [2, 2]]"
"(1, 3, 5, [7])"
"{'A': 'aa', 'B': 'bb', 'C': 'cc'}"
"__import__('os').system('ls /')"
"""
std = input('please input: ')
eval_std = eval(std)
print('input: ',eval_std, type(eval_std))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以上5種輸入，下方為輸出結果:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;input: 1000 &amp;lt;type 'int'&amp;gt;
input: 4 &amp;lt;type 'int'&amp;gt;
input: [0, 1, [2, 2]] &amp;lt;type 'list'&amp;gt;
input: (1, 3, 5, [7]) &amp;lt;type 'tuple'&amp;gt;
input: {'A': 'aa', 'C': 'cc', 'B': 'bb'} &amp;lt;type 'dict'&amp;gt;

bin boot cdrom dev etc home lib lib32 lib64 libx32 lost+found media mnt opt proc root run sbin snap srv swapfile sys tmp usr var VBox.log
input: 0 &amp;lt;type 'int'&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;eval 不只是可以轉型態、將輸入做處理，甚至系統的命令都能執行!&lt;br&gt;
如果今天(使用者)輸入的內容是輸入刪除文件、顯示目錄結構等命令，那是很大的危險，所以要轉型態是不建議使用eval的!(本篇不介紹惡意操作的指令有哪些)&lt;/p&gt;
&lt;p&gt;使用下方程式:ast.literal_eval&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;# coding:utf-8
import ast

"""
輸入下方指令:
"1000"
"1+3" # 會報錯
"[0, 1, [2, 2]]"
"(1, 3, 5, [7])"
"{'A': 'aa', 'B': 'bb', 'C': 'cc'}"
"__import__('os').system('ls /')" # 會報錯
"""
std = input('please input: ')
ast_std = ast.literal_eval(std)
print('input: %s %s'% (ast_std, type(ast_std)))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ast.literal_eval會去判斷要解析的內容是否安全，不安全就報錯，我們只要處理報錯的處理就好，比起找回刪除的檔案或是被偷的資料，這輕鬆多了。&lt;/p&gt;
&lt;p&gt;結論:字符串進行類型轉換，一律用ast.literal_eval()&lt;/p&gt;
&lt;p&gt;連結:&lt;a class="link" href="https://docs.python.org/2/library/ast.html" target="_blank" rel="noopener"
 &gt;python document&lt;/a&gt;&lt;/p&gt;</description></item><item><title>[Python]實現php serialize函數</title><link>https://quietbo.com/2021/04/28/python%E5%AF%A6%E7%8F%BEphp-serialize%E5%87%BD%E6%95%B8/</link><pubDate>Wed, 28 Apr 2021 08:50:46 +0000</pubDate><guid>https://quietbo.com/2021/04/28/python%E5%AF%A6%E7%8F%BEphp-serialize%E5%87%BD%E6%95%B8/</guid><description>&lt;p&gt;不同的程式語言之間物件的傳遞，就必須把物件序列化為標準格式，比如XML，但更好的方法是序列化為JSON，因為JSON表示出來就是一個字串，可以被所有語言讀取，也可以方便地儲存到磁碟或者通過網路傳輸。&lt;/p&gt;
&lt;p&gt;舉例A公司用php撰寫後序列化(物件轉字串)傳送到B公司，而B公司用Python反序列化時要用到。&lt;br&gt;
通常是用在Python編程環境和PHP編程環境，相互之間需要&lt;code&gt;進行數據交換&lt;/code&gt;時。&lt;figure class="wp-block-image"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/NTe1vwR.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;pip3 install phpserialize&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;導入庫：&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;import phpserialize&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;利用dumps 進行序列化（物件轉字串）：&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;phpserialize.dumps(vary)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用loads 進行反序列化（字串轉物件）：&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;phpserialize.loads(formated_string)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a class="link" href="https://blog.csdn.net/whatday/article/details/106987049" target="_blank" rel="noopener"
 &gt;來源1&lt;/a&gt;&lt;/p&gt;</description></item><item><title>[Python]並發編程的三種方式</title><link>https://quietbo.com/2021/04/19/python-%E4%B8%A6%E7%99%BC%E7%B7%A8%E7%A8%8B%E7%9A%84%E4%B8%89%E7%A8%AE%E6%96%B9%E5%BC%8F/</link><pubDate>Mon, 19 Apr 2021 08:07:14 +0000</pubDate><guid>https://quietbo.com/2021/04/19/python-%E4%B8%A6%E7%99%BC%E7%B7%A8%E7%A8%8B%E7%9A%84%E4%B8%89%E7%A8%AE%E6%96%B9%E5%BC%8F/</guid><description>&lt;p&gt;1.多進程(Process)&lt;br&gt;
2.多線程(Thread)&lt;br&gt;
3.多協程(Coroutine)&lt;/p&gt;
&lt;div id="ez-toc-container" class="ez-toc-v2_0_82_2 ez-toc-wrap-center counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction"&gt;
 &lt;div class="ez-toc-title-container"&gt;
 &lt;p class="ez-toc-title" style="cursor:inherit"&gt;
 Table of Contents
 &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;span class=&amp;quot;ez-toc-title-toggle&amp;quot;&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot; class=&amp;quot;ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle&amp;quot; aria-label=&amp;quot;顯示/隱藏內容目錄&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;ez-toc-js-icon-con&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;eztoc-hide&amp;quot; style=&amp;quot;display:none;&amp;quot;&amp;gt;Toggle&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;ez-toc-icon-toggle-span&amp;quot;&amp;gt;&amp;lt;svg style=&amp;quot;fill: #999;color:#999&amp;quot; xmlns=&amp;quot;http://www.w3.org/2000/svg&amp;quot; class=&amp;quot;list-377408&amp;quot; width=&amp;quot;20px&amp;quot; height=&amp;quot;20px&amp;quot; viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;/path&amp;gt;&amp;lt;/svg&amp;gt;&amp;lt;svg style=&amp;quot;fill: #999;color:#999&amp;quot; class=&amp;quot;arrow-unsorted-368013&amp;quot; xmlns=&amp;quot;http://www.w3.org/2000/svg&amp;quot; width=&amp;quot;10px&amp;quot; height=&amp;quot;10px&amp;quot; viewBox=&amp;quot;0 0 24 24&amp;quot; version=&amp;quot;1.2&amp;quot; baseProfile=&amp;quot;tiny&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;&lt;nav&gt;
 &lt;ul class='ez-toc-list ez-toc-list-level-1 ' &gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-1" href="https://quietbo.com/2021/04/19/python-%e4%b8%a6%e7%99%bc%e7%b7%a8%e7%a8%8b%e7%9a%84%e4%b8%89%e7%a8%ae%e6%96%b9%e5%bc%8f/#1%E4%BB%80%E9%BA%BC%E6%98%AFCPU%E5%AF%86%E9%9B%86%E5%9E%8B%E8%A8%88%E7%AE%97%E3%80%81IO%E5%AF%86%E9%9B%86%E5%9E%8B%E8%A8%88%E7%AE%97" &gt;1.什麼是CPU密集型計算、IO密集型計算?&lt;/a&gt;
 &lt;/li&gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-2" href="https://quietbo.com/2021/04/19/python-%e4%b8%a6%e7%99%bc%e7%b7%a8%e7%a8%8b%e7%9a%84%e4%b8%89%e7%a8%ae%e6%96%b9%e5%bc%8f/#2%E5%A4%9A%E9%80%B2%E7%A8%8B%E3%80%81%E5%A4%9A%E7%B7%9A%E7%A8%8B%E3%80%81%E5%A4%9A%E5%8D%94%E7%A8%8B%E7%9A%84%E5%B0%8D%E6%AF%94" &gt;2.多進程、多線程、多協程的對比&lt;/a&gt;&lt;ul class='ez-toc-list-level-3' &gt;
 &lt;li class='ez-toc-heading-level-3'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-3" href="https://quietbo.com/2021/04/19/python-%e4%b8%a6%e7%99%bc%e7%b7%a8%e7%a8%8b%e7%9a%84%e4%b8%89%e7%a8%ae%e6%96%b9%e5%bc%8f/#%E5%A4%9A%E9%80%B2%E7%A8%8BProcessmultiprocessing" &gt;多進程Process(multiprocessing)&lt;/a&gt;
 &lt;/li&gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-3'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-4" href="https://quietbo.com/2021/04/19/python-%e4%b8%a6%e7%99%bc%e7%b7%a8%e7%a8%8b%e7%9a%84%e4%b8%89%e7%a8%ae%e6%96%b9%e5%bc%8f/#%E5%A4%9A%E7%B7%9A%E7%A8%8BThreadthreading" &gt;多線程Thread(threading)&lt;/a&gt;
 &lt;/li&gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-3'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-5" href="https://quietbo.com/2021/04/19/python-%e4%b8%a6%e7%99%bc%e7%b7%a8%e7%a8%8b%e7%9a%84%e4%b8%89%e7%a8%ae%e6%96%b9%e5%bc%8f/#%E5%A4%9A%E5%8D%94%E7%A8%8BCoroutineasycio_%E2%80%93_%E7%95%B0%E6%AD%A5io" &gt;多協程Coroutine(asycio) &amp;#8211; 異步io&lt;/a&gt;
 &lt;/li&gt;
 &lt;/ul&gt;
 &lt;/li&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&amp;gt;
 &amp;lt;a class=&amp;quot;ez-toc-link ez-toc-heading-6&amp;quot; href=&amp;quot;https://quietbo.com/2021/04/19/python-%e4%b8%a6%e7%99%bc%e7%b7%a8%e7%a8%8b%e7%9a%84%e4%b8%89%e7%a8%ae%e6%96%b9%e5%bc%8f/#3_%E5%A6%82%E4%BD%95%E6%A0%B9%E6%93%9A%E4%BB%BB%E5%8B%99%E9%81%B8%E6%93%87%E5%B0%8D%E6%87%89%E7%9A%84%E6%8A%80%E8%A1%93&amp;quot; &amp;gt;3. 如何根據任務選擇對應的技術?&amp;lt;/a&amp;gt;
&amp;lt;/li&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
 &lt;/ul&gt;&lt;/nav&gt;
&lt;/div&gt;
&lt;h2 id="1什麼是cpu密集型計算io密集型計算"&gt;&lt;span class="ez-toc-section" id="1%E4%BB%80%E9%BA%BC%E6%98%AFCPU%E5%AF%86%E9%9B%86%E5%9E%8B%E8%A8%88%E7%AE%97%E3%80%81IO%E5%AF%86%E9%9B%86%E5%9E%8B%E8%A8%88%E7%AE%97"&gt;&lt;/span&gt;1.什麼是CPU密集型計算、IO密集型計算?&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;bound在這邊是限制的意思。&lt;/p&gt;
&lt;p&gt;CPU密集型(CPU-bound):&lt;br&gt;
CPU密集型也叫計算密集型，指的是I/O在很短的時間就可以完成，CPU需要大量的計算和處理。特點是CPU占用率極高。&lt;br&gt;
例如:壓縮/解壓縮、加密/解密、正則表達式搜索。&lt;/p&gt;
&lt;p&gt;IO密集型(I/O-bound):&lt;br&gt;
指的是系統運作大部分的狀況CPU在等I/O的讀寫。CPU占用率相對的會較低。&lt;br&gt;
例如:文件處理、爬蟲網路、讀寫數據庫。&lt;/p&gt;
&lt;p&gt;小總結:&lt;/p&gt;
&lt;blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"&gt;
 &lt;p&gt;
 若程式依賴大量的外部連結(內存、硬碟、網路、DB..等等外部連結)就是IO密集型。若其他的只在CPU運算，則是CPU密集型。
 &lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="2多進程多線程多協程的對比"&gt;&lt;span class="ez-toc-section" id="2%E5%A4%9A%E9%80%B2%E7%A8%8B%E3%80%81%E5%A4%9A%E7%B7%9A%E7%A8%8B%E3%80%81%E5%A4%9A%E5%8D%94%E7%A8%8B%E7%9A%84%E5%B0%8D%E6%AF%94"&gt;&lt;/span&gt;2.多進程、多線程、多協程的對比&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;這三個是有一個級聯關係的。一個進程中可以包含和啟動多個線程，一個線程中可以啟動多個協程。&lt;br&gt;
協程的概念比較新，在任務中可以啟動很多的協程，但本身都在一個線程中進行。&lt;/p&gt;
&lt;h3 id="多進程processmultiprocessing"&gt;&lt;span class="ez-toc-section" id="%E5%A4%9A%E9%80%B2%E7%A8%8BProcessmultiprocessing"&gt;&lt;/span&gt;多進程Process(multiprocessing)&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h3&gt;&lt;ul class="wp-block-list"&gt;
 &lt;li&gt;
 優點:可以利用多核CPU並行運算
 &lt;/li&gt;
 &lt;li&gt;
 缺點:占用資源最多，可啟動數目比線程少
 &lt;/li&gt;
 &lt;li&gt;
 適用於:CPU密集型計算
 &lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="多線程threadthreading"&gt;&lt;span class="ez-toc-section" id="%E5%A4%9A%E7%B7%9A%E7%A8%8BThreadthreading"&gt;&lt;/span&gt;多線程Thread(threading)&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h3&gt;&lt;ul class="wp-block-list"&gt;
 &lt;li&gt;
 優點:相比進程，更輕量級，占用的資源更少。&lt;br /&gt;這裡的資源指的是每個線程運行都要包含自己的一些變量存儲，存儲到內存區域
 &lt;/li&gt;
 &lt;li&gt;
 缺點:&lt;br /&gt;相比進程:多線程只能併發執行，不能利用多CPU(GIL-全局解釋器鎖)&lt;br /&gt;相比協程:啟動數目有限制，佔用內存資源，有線程切換開銷
 &lt;/li&gt;
 &lt;li&gt;
 適用於:IO密集型計算、同時運型的任務數木要求不多
 &lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="多協程coroutineasycio-8211-異步io"&gt;&lt;span class="ez-toc-section" id="%E5%A4%9A%E5%8D%94%E7%A8%8BCoroutineasycio_%E2%80%93_%E7%95%B0%E6%AD%A5io"&gt;&lt;/span&gt;多協程Coroutine(asycio) – 異步io&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h3&gt;&lt;ul class="wp-block-list"&gt;
 &lt;li&gt;
 優點:內存開銷最少，啟動協程數量最多(甚至到幾萬個)。
 &lt;/li&gt;
 &lt;li&gt;
 缺點:支持的庫有限制(aiohttp vs requests)、代碼實現複雜。&lt;br /&gt;目前有很多技術是不支持協程的，例如requests這個爬蟲常用的類庫，但在python協程中是不支持的，&lt;br /&gt;所以要用協程來進行爬蟲的話，可以用aiohttp。&lt;br /&gt;相比進程、線程，代碼實現複雜，且要考慮的點也較多。
 &lt;/li&gt;
 &lt;li&gt;
 適用於:IO密集型計算、需要超多任務運行、但有現成庫支持的場景。
 &lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="3-如何根據任務選擇對應的技術"&gt;&lt;span class="ez-toc-section" id="3_%E5%A6%82%E4%BD%95%E6%A0%B9%E6%93%9A%E4%BB%BB%E5%8B%99%E9%81%B8%E6%93%87%E5%B0%8D%E6%87%89%E7%9A%84%E6%8A%80%E8%A1%93"&gt;&lt;/span&gt;3. 如何根據任務選擇對應的技術?&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;img decoding="async" src="https://i.imgur.com/yoFF8Xt.png" alt="" /&gt; 
&lt;p&gt;來源:&lt;a class="link" href="https://www.youtube.com/watch?v=qwkc9S85JHs" target="_blank" rel="noopener"
 &gt;youtube&lt;/a&gt;&lt;br&gt;
蚂蚁学Python【Python并发编程】怎样选择多线程多进程多协程&lt;/p&gt;</description></item><item><title>[安裝]Python 2.7以及Python virtualenv</title><link>https://quietbo.com/2021/03/24/python-2-7%E4%BB%A5%E5%8F%8Apython-virtual-environment-%E5%AE%89%E8%A3%9D/</link><pubDate>Wed, 24 Mar 2021 10:51:20 +0000</pubDate><guid>https://quietbo.com/2021/03/24/python-2-7%E4%BB%A5%E5%8F%8Apython-virtual-environment-%E5%AE%89%E8%A3%9D/</guid><description>&lt;p&gt;因ubuntu從18.04開始，內建的python版本都是為3.6以上 (舊的內建2.7)，所以要手動輸入版本號&lt;/p&gt;
&lt;div id="ez-toc-container" class="ez-toc-v2_0_82_2 ez-toc-wrap-center counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction"&gt;
 &lt;div class="ez-toc-title-container"&gt;
 &lt;p class="ez-toc-title" style="cursor:inherit"&gt;
 Table of Contents
 &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;span class=&amp;quot;ez-toc-title-toggle&amp;quot;&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot; class=&amp;quot;ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle&amp;quot; aria-label=&amp;quot;顯示/隱藏內容目錄&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;ez-toc-js-icon-con&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;eztoc-hide&amp;quot; style=&amp;quot;display:none;&amp;quot;&amp;gt;Toggle&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;ez-toc-icon-toggle-span&amp;quot;&amp;gt;&amp;lt;svg style=&amp;quot;fill: #999;color:#999&amp;quot; xmlns=&amp;quot;http://www.w3.org/2000/svg&amp;quot; class=&amp;quot;list-377408&amp;quot; width=&amp;quot;20px&amp;quot; height=&amp;quot;20px&amp;quot; viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;/path&amp;gt;&amp;lt;/svg&amp;gt;&amp;lt;svg style=&amp;quot;fill: #999;color:#999&amp;quot; class=&amp;quot;arrow-unsorted-368013&amp;quot; xmlns=&amp;quot;http://www.w3.org/2000/svg&amp;quot; width=&amp;quot;10px&amp;quot; height=&amp;quot;10px&amp;quot; viewBox=&amp;quot;0 0 24 24&amp;quot; version=&amp;quot;1.2&amp;quot; baseProfile=&amp;quot;tiny&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;&lt;nav&gt;
 &lt;ul class='ez-toc-list ez-toc-list-level-1 ' &gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-1" href="https://quietbo.com/2021/03/24/python-2-7%e4%bb%a5%e5%8f%8apython-virtual-environment-%e5%ae%89%e8%a3%9d/#%E5%AE%89%E8%A3%9Dpython27" &gt;安裝python2.7&lt;/a&gt;
 &lt;/li&gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-2" href="https://quietbo.com/2021/03/24/python-2-7%e4%bb%a5%e5%8f%8apython-virtual-environment-%e5%ae%89%e8%a3%9d/#%E5%AE%89%E8%A3%9Dpip%E5%A5%97%E4%BB%B6" &gt;安裝pip套件&lt;/a&gt;
 &lt;/li&gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-3" href="https://quietbo.com/2021/03/24/python-2-7%e4%bb%a5%e5%8f%8apython-virtual-environment-%e5%ae%89%e8%a3%9d/#%E4%BD%BF%E7%94%A8pip%E5%AE%89%E8%A3%9Dvirtualenv" &gt;使用pip安裝virtualenv&lt;/a&gt;
 &lt;/li&gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-4" href="https://quietbo.com/2021/03/24/python-2-7%e4%bb%a5%e5%8f%8apython-virtual-environment-%e5%ae%89%e8%a3%9d/#%E7%82%BAvirtualenv%E8%A3%BD%E4%BD%9C%E5%88%A5%E5%90%8D" &gt;為virtualenv製作別名&lt;/a&gt;
 &lt;/li&gt;
 &lt;/ul&gt;&lt;/nav&gt;
&lt;/div&gt;
&lt;h2 id="安裝python27"&gt;&lt;span class="ez-toc-section" id="%E5%AE%89%E8%A3%9Dpython27"&gt;&lt;/span&gt;安裝python2.7&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash line-numbers"&gt;sudo apt update
sudo apt install python2.7 -y&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;檢查一下python2.7版本:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;python2.7 -V&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;輸出結果:&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/w4o7c6Q.png" alt="" /&gt;&lt;/p&gt;
&lt;h2 id="安裝pip套件"&gt;&lt;span class="ez-toc-section" id="%E5%AE%89%E8%A3%9Dpip%E5%A5%97%E4%BB%B6"&gt;&lt;/span&gt;安裝pip套件&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;這邊的作法是下載&lt;code&gt;get-pip.py&lt;/code&gt;來安裝。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;:&lt;br&gt;
第3行的URL不一定是最新的，若有跳出錯誤訊息是URL找不到，請自行更換成錯誤訊息跳出的URL。&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash line-numbers"&gt;cd ~
cd 下載
curl https://bootstrap.pypa.io/pip/2.7/get-pip.py -o get-pip.py
python2.7 get-pip.py &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;若安裝成功，最後會看到這個訊息:&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/UIkuliG.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;(可略過不做)&lt;br&gt;
為使用pip套件建立別名:&lt;br&gt;
後面的指令pip2請自行改成&lt;code&gt;python2.7 -m pip&lt;/code&gt;&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash line-numbers"&gt;cd ~
touch .bash_aliases
echo "alias pip2='python2.7 -m pip'" &amp;gt;&amp;gt; .bash_aliases
source .bash_aliases
pip2 -V&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;輸出結果:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;pip 20.3.4 from /home/ubuntu/.local/lib/python2.7/site-packages/pip (python 2.7)&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="使用pip安裝virtualenv"&gt;&lt;span class="ez-toc-section" id="%E4%BD%BF%E7%94%A8pip%E5%AE%89%E8%A3%9Dvirtualenv"&gt;&lt;/span&gt;使用pip安裝virtualenv&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;日後為每個專案製作一個專屬的python environment&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash line-numbers"&gt;pip2 install virtualenv
# 等同於 python2.7 -m pip install virtualenv&lt;/code&gt;&lt;/pre&gt;&lt;figure class="wp-block-image"&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/u9rTOFG.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;h2 id="為virtualenv製作別名"&gt;&lt;span class="ez-toc-section" id="%E7%82%BAvirtualenv%E8%A3%BD%E4%BD%9C%E5%88%A5%E5%90%8D"&gt;&lt;/span&gt;為virtualenv製作別名&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;這是因為如果安裝其他python版本的virtualenv，用別名來區分使用的版本。&lt;strong&gt;也可以略過，後續指令virtialenv2.7自行替換成virtualenv&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash line-numbers"&gt;echo "alias virtualenv2.7='python2.7 -m virtualenv'" &amp;gt;&amp;gt; ~/.bash_aliases
source .bash_aliases
# 測試一下
virtualenv2.7 --version
# 輸出結果
# virtualenv 20.4.3 from /home/ubuntu/.local/lib/python2.7/site-packages/virtualenv/__init__.pyc&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;製作一個test_venv專屬的python environment。&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash line-numbers"&gt;mkdir python27_venv
cd python27_venv
virtualenv2.7 test_venv # 方法1:有製作別名(上方操作)才可使用此方法
python27_venv python2.7 -m virtualenv test_venv # 方法2&lt;/code&gt;&lt;/pre&gt;&lt;figure class="wp-block-image"&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/IBxbyKT.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;創建完後進入虛擬環境:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;source ~/python27_venv/test_venv/bin/activate&lt;/code&gt;&lt;/pre&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash line-numbers"&gt;# 命令列多出前綴(test_venv)。表示已經啟用此虛擬環境
(test_venv)$ python -V
Python 2.7.17 # 輸出結果
(test_venv)$ pip list

(test_venv)$ deactivate # 離開虛擬環境

# 前綴消失，表示已經關閉虛擬環境&lt;/code&gt;&lt;/pre&gt;&lt;figure class="wp-block-image"&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/YhCSlD5.png" alt="" /&gt; &lt;/figure&gt; &lt;figure class="wp-block-image"&gt;&lt;img decoding="async" src="https://i.imgur.com/xuP235Q.png" alt="" /&gt;&lt;/figure&gt;&lt;/p&gt;</description></item><item><title>[Linux]背景執行py方法</title><link>https://quietbo.com/2021/03/10/ubuntu%E8%83%8C%E6%99%AF%E5%9F%B7%E8%A1%8Cpy%E6%96%B9%E6%B3%95/</link><pubDate>Wed, 10 Mar 2021 10:33:33 +0000</pubDate><guid>https://quietbo.com/2021/03/10/ubuntu%E8%83%8C%E6%99%AF%E5%9F%B7%E8%A1%8Cpy%E6%96%B9%E6%B3%95/</guid><description>&lt;p&gt;2022/07/06 – 新增&lt;a href="https://quietbo.com/2022/07/06/python-%e8%83%8c%e6%99%af%e5%9f%b7%e8%a1%8cnohup-%e8%88%87-nohup-out/?preview_id=847&amp;preview_nonce=4fb57ac562&amp;preview=true" data-type="URL" data-id="https://quietbo.com/2022/07/06/python-%e8%83%8c%e6%99%af%e5%9f%b7%e8%a1%8cnohup-%e8%88%87-nohup-out/?preview_id=847&amp;preview_nonce=4fb57ac562&amp;preview=true" target="_blank" rel="noreferrer noopener"&gt;[Python] 背景執行nohup, &amp;amp; 與 nohup.out&lt;/a&gt;&lt;/p&gt;
&lt;hr class="wp-block-separator has-alpha-channel-opacity" /&gt;
&lt;p&gt;主要介紹在linux下使用Terminal來背景執行python的幾種方式，&lt;br&gt;
執行3隻python檔，每5秒、10秒、15秒各別顯示當前時間。&lt;/p&gt;
&lt;p&gt;以下為python範例:&lt;br&gt;
test.py、test2.py、test3.py這三隻同時使用背景來執行的畫面。&lt;/p&gt;
&lt;p&gt;執行test.py後，會顯示跳出PID為25270。&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;# coding:utf-8
from datetime import datetime
from time import sleep

while(1):
 count = 1
 sleep(5)
 print(str(count) + " : " + str(datetime.now().strftime('%Y-%m-%d %H:%M:%S')))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果想讓程式跑在背景，在結尾的地方加個&amp;amp;&lt;br&gt;
python 背景執行指令如下:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python"&gt;python 程式碼名稱 &amp;&lt;/code&gt;&lt;/pre&gt;&lt;figure class="wp-block-image"&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/26SgbQS.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;再執行一隻test2.py，不會讓原本的test.py停住，仍在背景繼續執行，並且顯示test2.py新的PID。&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;# coding:utf-8
from datetime import datetime
from time import sleep

while(1):
 count = 2
 sleep(10)
 print(str(count) + " : " + str(datetime.now().strftime('%Y-%m-%d %H:%M:%S')))&lt;/code&gt;&lt;/pre&gt;&lt;figure class="wp-block-image"&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/qs2nJvo.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;再執行test3.py。&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="python" class="language-python line-numbers"&gt;# coding:utf-8
from datetime import datetime
from time import sleep

while(1):
 count = 3
 sleep(15)
 print(str(count) + " : " + str(datetime.now().strftime('%Y-%m-%d %H:%M:%S')))&lt;/code&gt;&lt;/pre&gt;&lt;figure class="wp-block-image"&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/vemyMSe.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;查詢背景運行的程式:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;ps -ef&lt;/code&gt;&lt;/pre&gt;&lt;figure class="wp-block-image"&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/IczNFtg.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;想停止某隻程式的話，輸入下方指令:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;kill PID&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下圖為停止第一支test.py的程式。&lt;/p&gt;
&lt;img decoding="async" src="https://i.imgur.com/XGJJtqK.png" alt="" /&gt; 
kill掉後原本的Terminal會出現已終止的程式名稱。 
&lt;img decoding="async" src="https://i.imgur.com/1If2w51.png" alt="" /&gt; 
原本的test2.py和test3.py還會繼續執行。 
&lt;img decoding="async" src="https://i.imgur.com/ucgmhz8.png" alt="" /&gt;</description></item></channel></rss>