From 98682c1d716df975e027c6fd88231e429bf41fc3 Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Sun, 14 Aug 2016 22:48:06 +0800 Subject: [PATCH 01/37] =?UTF-8?q?Create=20=E4=BA=A4=E6=8F=9B=E5=85=A9?= =?UTF-8?q?=E5=80=8Bshelve=20objects.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\345\205\251\345\200\213shelve objects.md" | 209 ++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 "questions/standard_lib/\344\272\244\346\217\233\345\205\251\345\200\213shelve objects.md" diff --git "a/questions/standard_lib/\344\272\244\346\217\233\345\205\251\345\200\213shelve objects.md" "b/questions/standard_lib/\344\272\244\346\217\233\345\205\251\345\200\213shelve objects.md" new file mode 100644 index 0000000..f90ce25 --- /dev/null +++ "b/questions/standard_lib/\344\272\244\346\217\233\345\205\251\345\200\213shelve objects.md" @@ -0,0 +1,209 @@ +# 如何交換兩個 shelve objects + +## 問題 + +假定 `db1`, `db2` 是 `shelve` objects: + +```python +if switch_d1_and_db2: + func(db1, db2) +else: + func(db2, db1) +``` + +怎麼才能改寫成: + +```python +if switch_d1_and_db2: + db1, db2 = db2, db1 # 错误写法 +func(db1, db2) +``` + +`db1, db2 = db2, db1` 肯定是不行的,怎麼改寫呢? + +所謂不行可以見以下範例: + +`define.py`: + +```python +import shelve +db1 = shelve.open('db1', writeback = True) +db2 = shelve.open('db2', writeback = True) +db1['name'] = 'db1' +db2['name'] = 'db2' +db1.close() +db2.close() +``` + +`switch.py`: + +```python +import shelve +db1 = shelve.open('db1', writeback = True) +db2 = shelve.open('db2', writeback = True) +db1, db2 = db2, db1 +print db1 +print db2 +db1.close() +db2.close() +``` + +`check.py`: + +```python +import shelve +db1 = shelve.open('db1', writeback = True) +db2 = shelve.open('db2', writeback = True) +print 'db1:', db1 +print 'db2:', db2 +``` + +測試: + +``` +$ python define.py +$ python check.py +db1: {'name': 'db1'} +db2: {'name': 'db2'} +$ python switch.py +{'name': 'db2'} +{'name': 'db1'} +$ python check.py +db1: {'name': 'db1'} +db2: {'name': 'db2'} +``` + +雖然 switch 成功, 但是最後 check 還是失敗, 代表改變沒有正確反映在 db 中。 + +問題出自 [segmentfault](https://segmentfault.com/q/1010000006116287/a-1020000006119818), by [littlealias](https://segmentfault.com/u/littlealias) + +## 回答 + +你好, 我研究這個問題一陣之後結論是: + +1. 太難做到而且你想要使用的語法跟你要做的事情並不 match +2. 我覺得用原本的方法沒有什麼不好 +3. 如果你想要做到你定義的這種交換, 那我有一個不算是太漂亮的替代方案, 你可以參考 + +以下針對上述三點說明: + +對於第一點, 你想要: + +```python +db1, db2 = db2, db1 +``` + +這邊不論 `db1`, `db2` 是哪種 object, 這種交換式的意義在於 + +> 讓 `db1` 這個變數參考到原本 `db2` 所參考的 object, 並讓 `db2` 這個變數參考到原本 `db1` 所參考到的 object。 + +但是你想要做的事情是: + +> 讓 `db1` 這個 file 和 `db2` 這個 file 的內容互換 + +仔細想一想, 這兩件事情並不相同, 換個方式來說, `db1, db2 = db2, db1`, 只會讓變數參考的東西互換(變數名稱不等於 db 的 file 名稱), 但是每個文件的內容還是沒有互換。 + +所以 **使用這種語法來互換跟你要達到的效果並不一致**。 + +第二點就不多說明了, 因為合理, 只是你可能不喜歡。 + +第三點我給了一個不怎麼漂亮的替代方案, 就是簡單定義一個 `shelf` 的代理類 `ShelfProxy`, 這個類盡量模擬 `Shelf` 類的行為(僅是介面上相似), 並且重載了運算符 `^` 定義為交換: + +```python +import shelve + +class ShelfProxy: + + def __init__(self, *args, **kwargs): + self.args = args + self.kwargs = kwargs + self.file = args[0] + self.loaddb() + + @classmethod + def open(cls, *args, **kwargs): + return cls(*args, **kwargs) + + def __getattr__(self, name): + return getattr(self.dic, name) + + def __setitem__(self, name, value): + self.dic[name] = value + + def __getitem__(self, name): + return self.dic[name] + + def __xor__(self, other): + self.dic, other.dic = other.dic, self.dic + return True + + def __str__(self): + return str(self.dic) + + def loaddb(self): + db = shelve.open(*self.args, **self.kwargs) + self.dic = dict(db.items()) + db.close() + + def close(self): + newdb = shelve.open(self.file, *self.args[1:], **self.kwargs) + for key in newdb.keys(): + del newdb[key] + for key, value in self.dic.items(): + newdb[key] = value + newdb.close() +``` + +我將 `^` 定義為 **內容上的交換**, 之所以選 `^` 只是因為我想不到比較適合的符號, 一般來說重載不會這樣進行, 而且也不太會返回其他類的實例, 不過我這邊為求方便且針對你想要一個簡單介面這一點, 出此下策。 + +接著我們定義一些測試的 function: + +```python +def define(): + db1 = ShelfProxy.open('db1', writeback=True) + db2 = ShelfProxy.open('db2', writeback=True) + db1['name'] = 'db1' + db2['name'] = 'db2' + db1.close() + db2.close() + +def check(): + db1 = ShelfProxy.open('db1', writeback=True) + db2 = ShelfProxy.open('db2', writeback=True) + print('db1:', db1) + print('db2:', db2) + db1.close() + db2.close() + +def switch(): + print('switch') + db1 = ShelfProxy.open('db1', writeback=True) + db2 = ShelfProxy.open('db2', writeback=True) + db1 ^ db2 + db1.close() + db2.close() +``` + +測試代碼: + +```python +if __name__ == '__main__': + define() + check() + switch() + check() +``` + +結果: + +``` +db1: {'name': 'db1'} +db2: {'name': 'db2'} +switch +db1: {'name': 'db2'} +db2: {'name': 'db1'} +``` + +### 結論 + +大部分的時候, 你可以用跟 `Shelf` 相同的介面來操作 `ShelfProxy`, 整體效果也類似, 但是你不覺得寫了那麼多, 還是使用一開始的方法比較簡單嗎XD From 2f5cfcf540f26546036618521faf392e57d82eec Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Sun, 14 Aug 2016 22:48:44 +0800 Subject: [PATCH 02/37] Update contents.md --- contents.md | 1 + 1 file changed, 1 insertion(+) diff --git a/contents.md b/contents.md index d6b2a29..15199be 100644 --- a/contents.md +++ b/contents.md @@ -98,6 +98,7 @@ * [一個需要傳入參數的 python 程序如何封裝成可執行文件](questions/standard_lib/一個需要傳入參數的python程序如何封裝成可執行文件.md) * [一個結構化顯示文件的腳本,迭代是否有問題](questions/standard_lib/一個結構化顯示文件的腳本,迭代是否有問題.md) * [如何在 python raw_input 中使用 tab 鍵補全](questions/standard_lib/如何在python raw_input中使用tab鍵補全.md) + * [交換兩個 shelve objects](questions/standard_lib/交換兩個shelve objects.md) * pip * [pip 無法在安裝 pyinstaller](questions/pip/pip無法在安裝pyinstaller.md) From 1777a52d0f27cdccc4542ccd83876816c52352ca Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Sun, 14 Aug 2016 22:49:11 +0800 Subject: [PATCH 03/37] Update contents.md --- contents.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contents.md b/contents.md index 15199be..8d233be 100644 --- a/contents.md +++ b/contents.md @@ -134,11 +134,11 @@ * [燈泡開關問題](questions/algorithm/燈泡開關問題.md) * math - * [Python怎麼通過input獲取矩陣](questions/math/Python怎麼通過input獲取矩陣.md) + * [Python 怎麼通過 input 獲取矩陣](questions/math/Python怎麼通過input獲取矩陣.md) ## 大數據與機器學習 * data mining - * [python3中有聚類(主要是k-means)的函數或者模塊嗎](questions/data_mining/python3中有聚類(主要是k-means)的函數或者模塊嗎.md) + * [python3 中有聚類(主要是k-means)的函數或者模塊嗎](questions/data_mining/python3中有聚類(主要是k-means)的函數或者模塊嗎.md) ## Python 實作與開發環境 From ea67930c2cefe4c68e22d125e5b88af6f56f81fb Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Sun, 14 Aug 2016 22:50:18 +0800 Subject: [PATCH 04/37] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index de346d2..c74952e 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ 這個 repository 收集了一些我自己感覺比較有趣或實用的問題,每篇都會附上原發問者的問題以及我的回答,問題可能經過潤飾,但我盡量維持原貌,回答的部分也多是個人見解,只是希望做個整理並且與有興趣的人分享. -由於問題滿雜的,我只能憑我的直覺將之分類歸檔,目前一共收錄了 72 個問題,大家有興趣的可以參閱[目錄](contents.md). +由於問題滿雜的,我只能憑我的直覺將之分類歸檔,目前一共收錄了 73 個問題,大家有興趣的可以參閱[目錄](contents.md). 如果你有任何的意見或想要討論,都歡迎你開個 issue 來討論唷! From ba7f29258ab5c51e257ab28ffc34be66627aaef0 Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Tue, 16 Aug 2016 01:48:44 +0800 Subject: [PATCH 05/37] =?UTF-8?q?Create=20=E7=82=BA=E4=BB=80=E9=BA=BC?= =?UTF-8?q?=E9=80=99=E5=85=A9=E6=AE=B5=20python=20lambda=20=E5=87=BA?= =?UTF-8?q?=E7=8F=BE=E4=B8=8D=E5=90=8C=E7=9A=84=E7=B5=90=E6=9E=9C.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...14\347\232\204\347\265\220\346\236\234.md" | 151 ++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 "questions/scope/\347\202\272\344\273\200\351\272\274\351\200\231\345\205\251\346\256\265 python lambda \345\207\272\347\217\276\344\270\215\345\220\214\347\232\204\347\265\220\346\236\234.md" diff --git "a/questions/scope/\347\202\272\344\273\200\351\272\274\351\200\231\345\205\251\346\256\265 python lambda \345\207\272\347\217\276\344\270\215\345\220\214\347\232\204\347\265\220\346\236\234.md" "b/questions/scope/\347\202\272\344\273\200\351\272\274\351\200\231\345\205\251\346\256\265 python lambda \345\207\272\347\217\276\344\270\215\345\220\214\347\232\204\347\265\220\346\236\234.md" new file mode 100644 index 0000000..96edcd0 --- /dev/null +++ "b/questions/scope/\347\202\272\344\273\200\351\272\274\351\200\231\345\205\251\346\256\265 python lambda \345\207\272\347\217\276\344\270\215\345\220\214\347\232\204\347\265\220\346\236\234.md" @@ -0,0 +1,151 @@ +# 為什麼這兩段 python lambda 出現不同的結果 + +## 問題 + +寫了這樣一段代碼: + +```python +[i(4) for i in [(lambda y: print('y=', y, '; x=', x, ' ; n + x = ', y + x)) for x in range(10)]] +``` + +發現輸出如下: + +``` +y= 4 ; x= 9 ; n + x = 13 +y= 4 ; x= 9 ; n + x = 13 +y= 4 ; x= 9 ; n + x = 13 +y= 4 ; x= 9 ; n + x = 13 +y= 4 ; x= 9 ; n + x = 13 +y= 4 ; x= 9 ; n + x = 13 +y= 4 ; x= 9 ; n + x = 13 +y= 4 ; x= 9 ; n + x = 13 +y= 4 ; x= 9 ; n + x = 13 +y= 4 ; x= 9 ; n + x = 13 +``` + +修改了一下: + +```python +import functools + +[f(4) for f in [functools.partial(lambda x, y: print('y=', y, '; x=', x, ' ; y + x = ', y + x), y) for y in range(10)]] +``` + +輸出如下: + +``` +y= 4 ; x= 0 ; y + x = 4 +y= 4 ; x= 1 ; y + x = 5 +y= 4 ; x= 2 ; y + x = 6 +y= 4 ; x= 3 ; y + x = 7 +y= 4 ; x= 4 ; y + x = 8 +y= 4 ; x= 5 ; y + x = 9 +y= 4 ; x= 6 ; y + x = 10 +y= 4 ; x= 7 ; y + x = 11 +y= 4 ; x= 8 ; y + x = 12 +y= 4 ; x= 9 ; y + x = 13 +``` + +不知道為什麼會有這樣的差異,請指教 + +問題出自 [segmentfault](https://segmentfault.com/q/1010000006121417/a-1020000006121940), by [kavlez](https://segmentfault.com/u/kavlez) + +## 回答 + +你問的這個問題不是那麼好理解, 不過我慢慢說看看能接受多少。 + +### 第一段 code + +首先我們看到你寫的第一段 code: + +```python +[i(4) for i in [(lambda y: print('y=', y, '; x=', x, ' ; n + x = ', y + x)) for x in range(10)]] +``` + +我們先專心看內層的 list comprehension: + +```python +funclist1 = [(lambda y: print('y=', y, '; x=', x, ' ; n + x = ', y + x)) for x in range(10)] +``` + +這段我們可以寫成一段等價的 code: + +```python +def produce_functions(): + funclist = [] + for x in range(10): + def ld(y): + print('y=', y, '; x=', x, ' ; n + x = ', y + x) + funclist.append(ld) + return funclist + +funclist2 = produce_functions() +``` + +我們隨意地來測試一下: + +```python +>>> funclist1[0](4) +y= 4 ; x= 9 ; n + x = 13 + +>>> funclist2[0](4) +y= 4 ; x= 9 ; n + x = 13 +``` + +希望大家看到這裡可以接受兩者除了一個用 lambda funciton 一個用 normal function 但是其實行為上是一致的。 + +接著請大家仔細看上面那段等價的 code, 你想到了甚麼呢? 沒錯! decorator 裡面會出現的 **閉包(closure)** !! 在這裡 `x` 不就是 **free variable** 嗎? 所以 `x` 並不會被綁死在 `ld` 中, 他參考到一個非全域的變數 `x`。我要說的是, 製造出來的 10 個 function 全部都參考到同一個 `x`, `for x in range(10)` 很容易誤導大家, 以為有十個不同的 `x` 然後製造了 10 個不同的 function。其實你跟我都明白, 這裡只有一個 `x` 變數, 只是他的值在改變, 但是說到底 `x` 就那麼一個。 + +為了避免空口說白話, 我證明我說的給大家看: + +```python +>>> funclist1[0].__code__.co_freevars +('x',) +>>> funclist2[0].__code__.co_freevars +('x',) +``` + +好, 那 `x` 的值在製造完之後究竟是多少呢? + +```python +>>> funclist2[0].__closure__ +(,) + +>>> funclist2[0].__closure__[0] + + +>>> funclist2[0].__closure__[0].cell_contents +9 +``` + +沒錯, 是 9 !, 所有所有製造出來的 function 全部都會參考到這個 `x`, 所以他們的 `x` 值就是 9 ! + +所以, 出現這個結果也就不意外了: + +```python +y= 4 ; x= 9 ; n + x = 13 +y= 4 ; x= 9 ; n + x = 13 +y= 4 ; x= 9 ; n + x = 13 +... +``` + +### 第二段 code + +接著我們來看第二段 code (一樣 focus 在內層): + +```python +import functools + +[functools.partial(lambda x, y: print('y=', y, '; x=', x, ' ; y + x = ', y + x), y) for y in range(10)] +``` + +`partial(func, a)` 會凍結 `func` 的第一個引數(會綁定 a 值) + +所以上面這段 code 會從 0~9 凍結這個 lambda function 的第一個引數, 這邊不同於 free variables, 這裡不是讓第一個引數 `x` 參考到同一個人, 而是直接綁死(代定) 0~9, 所以這裡每一個製造出來的 functions 全部都不一樣, 且可以當成 x 指定為 0~9。 + +經過上述講解, 應該大致可以明白兩者不同之處了。 + +### 結論 + +* `partial` 會直接凍結引數, 使變數代入定值 +* 一般的 function 會直接參考到 free variable 而不是代入定值 From 70bd6bc5a18d2457c4132e9940d1366e9beaf579 Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Tue, 16 Aug 2016 01:49:15 +0800 Subject: [PATCH 06/37] Update contents.md --- contents.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contents.md b/contents.md index 8d233be..6dce4ea 100644 --- a/contents.md +++ b/contents.md @@ -29,6 +29,9 @@ * star expression * [關於 python * 和 ** 的問題](questions/star/關於python*和**的問題.md) +* variable scope(global/local/nonlocal/closure) + * [為什麼這兩段 python lambda 出現不同的結果](questions/scope/為什麼這兩段 python lambda 出現不同的結果.md) + ## 控制流程與迭代 * if(if/elif/else) From 4cee401cbf612060be195a8e24691fac952ea555 Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Tue, 16 Aug 2016 01:49:29 +0800 Subject: [PATCH 07/37] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c74952e..00fb170 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ 這個 repository 收集了一些我自己感覺比較有趣或實用的問題,每篇都會附上原發問者的問題以及我的回答,問題可能經過潤飾,但我盡量維持原貌,回答的部分也多是個人見解,只是希望做個整理並且與有興趣的人分享. -由於問題滿雜的,我只能憑我的直覺將之分類歸檔,目前一共收錄了 73 個問題,大家有興趣的可以參閱[目錄](contents.md). +由於問題滿雜的,我只能憑我的直覺將之分類歸檔,目前一共收錄了 74 個問題,大家有興趣的可以參閱[目錄](contents.md). 如果你有任何的意見或想要討論,都歡迎你開個 issue 來討論唷! From 5cf6f92a4057fdfe8ecd8a7da8fa0c0e8d27df8e Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Tue, 16 Aug 2016 02:00:14 +0800 Subject: [PATCH 08/37] =?UTF-8?q?Create=20Python=20=E7=8D=B2=E5=8F=96?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E8=B7=AF=E5=BE=91=E5=8F=8A=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E7=9B=AE=E9=8C=84(=5F=5Ffile=5F=5F=20=E7=9A=84=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E6=96=B9=E6=B3=95).md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...7\347\224\250\346\226\271\346\263\225).md" | 158 ++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 "questions/standard_lib/Python \347\215\262\345\217\226\346\226\207\344\273\266\350\267\257\345\276\221\345\217\212\346\226\207\344\273\266\347\233\256\351\214\204(__file__ \347\232\204\344\275\277\347\224\250\346\226\271\346\263\225).md" diff --git "a/questions/standard_lib/Python \347\215\262\345\217\226\346\226\207\344\273\266\350\267\257\345\276\221\345\217\212\346\226\207\344\273\266\347\233\256\351\214\204(__file__ \347\232\204\344\275\277\347\224\250\346\226\271\346\263\225).md" "b/questions/standard_lib/Python \347\215\262\345\217\226\346\226\207\344\273\266\350\267\257\345\276\221\345\217\212\346\226\207\344\273\266\347\233\256\351\214\204(__file__ \347\232\204\344\275\277\347\224\250\346\226\271\346\263\225).md" new file mode 100644 index 0000000..85081f2 --- /dev/null +++ "b/questions/standard_lib/Python \347\215\262\345\217\226\346\226\207\344\273\266\350\267\257\345\276\221\345\217\212\346\226\207\344\273\266\347\233\256\351\214\204(__file__ \347\232\204\344\275\277\347\224\250\346\226\271\346\263\225).md" @@ -0,0 +1,158 @@ +# Python 獲取文件路徑及文件目錄(`__file__` 的使用方法) + +## 問題 + +我正在學習Python,不過遇到一些問題,想請教: + +`os` module 中的 `os.path.dirname(__file__)` 和 `os.path.abspath(__file__)` + +運行 `os.path.dirname(__file__)` 時候,為什麼返回的是空白呢? 是不是因為他運行的是相對路徑??? + +如果是的話: + +1. 我怎麼能夠知道,括號內的文件是以相對路徑還是絕對路徑被運行的? +2. 為什麼我運行下面例子腳本的時候,這個文件是以相對路徑被運行的呢? + +比如我下面的例子: + +```python +import os + +print (os.path.dirname(__file__)) +print (os.path.abspath(__file__)) +print (os.path.abspath(os.path.dirname(__file__))) +print (os.path.dirname(os.path.abspath(__file__))) +``` + +![测试][1] + [1]: https://segmentfault.com/img/bVzRXy + +PS:附加問題 +`os.path.abspath(os.path.dirname(__file__))` 和 `os.path.dirname(os.path.abspath(__file__))` 性質是否一樣呢? + +問題出自 [segmentfault](https://segmentfault.com/q/1010000006126582/a-1020000006127638), by [nodinner](https://segmentfault.com/u/nodinner) + +## 回答 + +建議你可以稍微瀏覽一下 Python doc: [os.path](https://docs.python.org/3.5/library/os.path.html), 你就會明白囉: + +我放上跟你問題相關的幾個條目: + +* `os.path.abspath(path)` + * Return a normalized absolutized version of the pathname path. On most platforms, this is equivalent to calling the function normpath() as follows: normpath(join(os.getcwd(), path)). + +* `os.path.normpath(path)` + * Normalize a pathname by collapsing redundant separators and up-level references so that A//B, A/B/, A/./B and A/foo/../B all become A/B. This string manipulation may change the meaning of a path that contains symbolic links. On Windows, it converts forward slashes to backward slashes. To normalize case, use normcase(). + +* `os.path.dirname(path)` + * Return the directory name of pathname path. This is the first element of the pair returned by passing path to the function split(). + +* `os.path.split(path)` + * Split the pathname path into a pair, (head, tail) where tail is the last pathname component and head is everything leading up to that. The tail part will never contain a slash; if path ends in a slash, tail will be empty. If there is no slash in path, head will be empty. If path is empty, both head and tail are empty. Trailing slashes are stripped from head unless it is the root (one or more slashes only). In all cases, join(head, tail) returns a path to the same location as path (but the strings may differ). Also see the functions dirname() and basename(). + +我們做以下觀察: + +`test.py` + +```python +import os + +print(__file__) +print(os.path.dirname(__file__)) +print(os.path.abspath(__file__)) +print(os.path.abspath(os.path.dirname(__file__))) +print(os.path.dirname(os.path.abspath(__file__))) +``` + +運行: + +``` +$ pwd +/home/dokelung +$ python test.py +``` + +結果: + +``` +test.py + +/home/dokelung/test.py +/home/dokelung +/home/dokelung +``` + +首先 `__file__` 的值其實就是在命令列上 invoke Python 時給的 script 名稱: + +```python +$ python test.py # 此時 __file__ 是 test.py +$ python ../test.py # 此時 __file__ 是 ../test.py +$ python hello/../test.py # 此時 __file__ 是 hello/../test.py +``` + +在這裡, 因為 `__file__` 的值為 `test.py`, 所以 `print(__file__)` 的結果是 `test.py` 也就不意外了。 + +接著, `os.path.dirname(__file__)`之所以得出空白(空字串), 是因為 `__file__` 就只是一個單純的名稱(非路徑) 且 `dirname` 也只是很單純的利用 `os.path.split()` 來切割這個名稱(這當然沒甚麼好切的, 連路徑分割符都沒有): + +```python +>>> import os +>>> os.path.split('test.py') +('', 'test.py') +>>> os.path.split('test.py')[0] +'' +``` + +我分會發現切出來的 `head` 是空字串, 所以 `dirname` 的結果是空白。 + +`abspath` 動用了 `os.getcwd()` 所以即便給定的是單純的名稱, 也能返回路徑: + +```python +>>> os.getcwd() +'/home/dokelung' + +>>> os.path.join(os.getcwd(), 'test.py') +'/home/dokelung/test.py' + +>>> os.path.normpath(os.path.join(os.getcwd(), 'test.py')) +'/home/dokelung/test.py' +``` + +而 `os.path.abspath(os.path.dirname(__file__))` 的結果就等於是 `os.getcwd()` 的結果去接上 `dirname` 得到的空字串: + +```python +>>> os.path.dirname('test.py') +'' + +>>> os.path.join(os.getcwd(), os.path.dirname('test.py')) +'/home/dokelung/' +``` + +最後, `os.path.dirname(os.path.abspath(__file__))` 的結果是這麼來的: + +```python +>>> os.path.abspath('test.py') +'/home/dokelung/test.py' + +>>> os.path.split(os.path.abspath('test.py')) +('/home/dokelung', 'test.py') + +>>> os.path.split(os.path.abspath('test.py'))[0] +'/home/dokelung' +``` + +希望講到這裡有讓你明白! + +## 結論 +現在簡要的回答你的問題 + +1. 為什麼 `dirname` 出現空白? + * 因為你運行的時候給的是單純的名稱, 所以 `__file__` 是單純的名字非路徑 + +2. 我怎么能够知道,括号内的文件是以相对路径还是绝对路径被运行的? + * 很簡單, 就看你怎麼運行 Python 的 + +3. 为什么我运行下面例子脚本的时候,这个文件是以相对路径被运行的呢? + * 因為 `$ python 1.py` 你自己給了相對路徑 + +4. `os.path.abspath(os.path.dirname(__file__))` 和 `os.path.dirname(os.path.abspath(__file__))` 性质是否一样呢? + * 基本上一樣 From 8112c0e548cdc8f7a5707e9a918da779d86e6382 Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Tue, 16 Aug 2016 02:00:49 +0800 Subject: [PATCH 09/37] Update contents.md --- contents.md | 1 + 1 file changed, 1 insertion(+) diff --git a/contents.md b/contents.md index 6dce4ea..2b4a138 100644 --- a/contents.md +++ b/contents.md @@ -102,6 +102,7 @@ * [一個結構化顯示文件的腳本,迭代是否有問題](questions/standard_lib/一個結構化顯示文件的腳本,迭代是否有問題.md) * [如何在 python raw_input 中使用 tab 鍵補全](questions/standard_lib/如何在python raw_input中使用tab鍵補全.md) * [交換兩個 shelve objects](questions/standard_lib/交換兩個shelve objects.md) + * [Python 獲取文件路徑及文件目錄(__file__ 的使用方法)](questions/standard_lib/Python 獲取文件路徑及文件目錄(__file__ 的使用方法).md) * pip * [pip 無法在安裝 pyinstaller](questions/pip/pip無法在安裝pyinstaller.md) From 3c6db7789490cee1b38a282ded8e3585932da975 Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Tue, 16 Aug 2016 02:01:13 +0800 Subject: [PATCH 10/37] Update contents.md --- contents.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contents.md b/contents.md index 2b4a138..4d4ff67 100644 --- a/contents.md +++ b/contents.md @@ -102,7 +102,7 @@ * [一個結構化顯示文件的腳本,迭代是否有問題](questions/standard_lib/一個結構化顯示文件的腳本,迭代是否有問題.md) * [如何在 python raw_input 中使用 tab 鍵補全](questions/standard_lib/如何在python raw_input中使用tab鍵補全.md) * [交換兩個 shelve objects](questions/standard_lib/交換兩個shelve objects.md) - * [Python 獲取文件路徑及文件目錄(__file__ 的使用方法)](questions/standard_lib/Python 獲取文件路徑及文件目錄(__file__ 的使用方法).md) + * [Python 獲取文件路徑及文件目錄(`__file__` 的使用方法)](questions/standard_lib/Python 獲取文件路徑及文件目錄(__file__ 的使用方法).md) * pip * [pip 無法在安裝 pyinstaller](questions/pip/pip無法在安裝pyinstaller.md) From 1668b76aaf23f756eae332a56852b3a81987163b Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Tue, 16 Aug 2016 02:01:25 +0800 Subject: [PATCH 11/37] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 00fb170..eb54157 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ 這個 repository 收集了一些我自己感覺比較有趣或實用的問題,每篇都會附上原發問者的問題以及我的回答,問題可能經過潤飾,但我盡量維持原貌,回答的部分也多是個人見解,只是希望做個整理並且與有興趣的人分享. -由於問題滿雜的,我只能憑我的直覺將之分類歸檔,目前一共收錄了 74 個問題,大家有興趣的可以參閱[目錄](contents.md). +由於問題滿雜的,我只能憑我的直覺將之分類歸檔,目前一共收錄了 75 個問題,大家有興趣的可以參閱[目錄](contents.md). 如果你有任何的意見或想要討論,都歡迎你開個 issue 來討論唷! From 795261f2db97e520bb145e8e1b36eee42cee84c4 Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Tue, 16 Aug 2016 02:15:45 +0800 Subject: [PATCH 12/37] =?UTF-8?q?Create=20=E4=B8=80=E5=80=8B=E6=95=B8?= =?UTF-8?q?=E6=9C=80=E5=BE=8C=E4=B8=80=E4=BD=8D=E6=98=AF6=EF=BC=8C?= =?UTF-8?q?=E7=A7=BB=E5=8B=95=E5=88=B0=E9=A6=96=E4=BD=8D=E6=98=AF=E5=8E=9F?= =?UTF-8?q?=E4=BE=86=E6=95=B8=E7=9A=84=E4=B8=89=E5=80=8D=EF=BC=8C=E6=B1=82?= =?UTF-8?q?=E9=80=99=E5=80=8B=E6=95=B8.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...02\351\200\231\345\200\213\346\225\270.md" | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 "questions/algorithm/\344\270\200\345\200\213\346\225\270\346\234\200\345\276\214\344\270\200\344\275\215\346\230\2576\357\274\214\347\247\273\345\213\225\345\210\260\351\246\226\344\275\215\346\230\257\345\216\237\344\276\206\346\225\270\347\232\204\344\270\211\345\200\215\357\274\214\346\261\202\351\200\231\345\200\213\346\225\270.md" diff --git "a/questions/algorithm/\344\270\200\345\200\213\346\225\270\346\234\200\345\276\214\344\270\200\344\275\215\346\230\2576\357\274\214\347\247\273\345\213\225\345\210\260\351\246\226\344\275\215\346\230\257\345\216\237\344\276\206\346\225\270\347\232\204\344\270\211\345\200\215\357\274\214\346\261\202\351\200\231\345\200\213\346\225\270.md" "b/questions/algorithm/\344\270\200\345\200\213\346\225\270\346\234\200\345\276\214\344\270\200\344\275\215\346\230\2576\357\274\214\347\247\273\345\213\225\345\210\260\351\246\226\344\275\215\346\230\257\345\216\237\344\276\206\346\225\270\347\232\204\344\270\211\345\200\215\357\274\214\346\261\202\351\200\231\345\200\213\346\225\270.md" new file mode 100644 index 0000000..8de074f --- /dev/null +++ "b/questions/algorithm/\344\270\200\345\200\213\346\225\270\346\234\200\345\276\214\344\270\200\344\275\215\346\230\2576\357\274\214\347\247\273\345\213\225\345\210\260\351\246\226\344\275\215\346\230\257\345\216\237\344\276\206\346\225\270\347\232\204\344\270\211\345\200\215\357\274\214\346\261\202\351\200\231\345\200\213\346\225\270.md" @@ -0,0 +1,103 @@ +# 一個數最後一位是6,移動到首位是原來數的三倍,求這個數 + +## 問題 + +題目:一個數最後一位是6,移動到首位是原來數的三倍,求這個數 +要求:速度最優 + +大神們快來踴躍探討~~~ + +問題出自 [segmentfault](https://segmentfault.com/q/1010000006135723/a-1020000006139815), by [prolifes](https://segmentfault.com/u/prolifes) + +## 回答 + +### 各路大神的回答 + +#### [citaret](https://segmentfault.com/u/citaret) 的回答 + +先贴上一版: + +```python +x = 6 +xs = [] +while True: + xs.append(x // 3) + x = x % 3 * 10 + x // 3 + if x == 6: + print ''.join(str(x) for x in xs) + break +``` + +输出: + +``` +2068965517241379310344827586 +``` + +原理是手算,把每次得到的商的末位补到被除数的最后,然后继续除法,直到末位为6,且余数为0停止。 + +#### [hsfzxjy](https://segmentfault.com/u/hsfzxjy) 的回答 + +由於數學公式的使用請大家前往問題原出處查看 [回答](https://segmentfault.com/q/1010000006135723/a-1020000006139815) + +### 我的回答 + +下午看到這題的時候就有了個想法, 手邊沒電腦只好等到現在... + +後來看到 @citaret 的答案就發現剛好是反向的想法, 下面是我的作法: + +```python +x = 6 +last_carry = 0 +result = 6 +radix = 10 + +while True: + c1, x = divmod(x * 3, 10) + c2, x = divmod(x + last_carry, 10) + last_carry = c1 + c2 + + if x==6 and last_carry==0: + return result + + result += (x * radix) + radix *= 10 +``` + +想法就剛好是反過來, 我一步一步地乘上去 + +* 每次把 `x` 乘 3 + * 把個位數加上 `last_carry` 就是下次的 `x` + * 把十位數的進位留下來當作下次的 `last_carry` + * 做到 `x==6` 且無進位的時候 + +用圖來思考長這樣: + +``` +0 <-- last carry + \ +1 8 = 6 X 3 + \ (0 + 8 = 8) +2 4 = 8 X 3 + \ (1 + 4 = 5) +1 5 = 5 X 3 +... +``` + +用 `timeit` 稍微測了一下時間(各運行 1000000 次), 共測三次: + +``` +# first +dokelung: 17.301649590954185 +citaret: 18.24915363173932 + +# second +dokelung: 19.257807812653482 +citaret: 17.994877750985324 + +# third +dokelung: 17.0617663115263 +citaret: 18.355605391785502 +``` + +時間看起來差不多, 不過我自認為代碼沒有很漂亮... From de29b6fd044201de27685af0e4e02ab5075295a0 Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Tue, 16 Aug 2016 02:16:21 +0800 Subject: [PATCH 13/37] Update contents.md --- contents.md | 1 + 1 file changed, 1 insertion(+) diff --git a/contents.md b/contents.md index 4d4ff67..a33a49a 100644 --- a/contents.md +++ b/contents.md @@ -136,6 +136,7 @@ * [分群問題](questions/algorithm/分群問題.md) * [找出所有組合-笛卡爾積問題](questions/algorithm/找出所有組合-笛卡爾積問題.md) * [燈泡開關問題](questions/algorithm/燈泡開關問題.md) + * [一個數最後一位是 6,移動到首位是原來數的三倍,求這個數](algorithm/一個數最後一位是6,移動到首位是原來數的三倍,求這個數.md) * math * [Python 怎麼通過 input 獲取矩陣](questions/math/Python怎麼通過input獲取矩陣.md) From 4c4a01dafa79ea2c269d11a33b7ca4da773df903 Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Tue, 16 Aug 2016 02:16:54 +0800 Subject: [PATCH 14/37] Update contents.md --- contents.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contents.md b/contents.md index a33a49a..ff166ad 100644 --- a/contents.md +++ b/contents.md @@ -136,7 +136,7 @@ * [分群問題](questions/algorithm/分群問題.md) * [找出所有組合-笛卡爾積問題](questions/algorithm/找出所有組合-笛卡爾積問題.md) * [燈泡開關問題](questions/algorithm/燈泡開關問題.md) - * [一個數最後一位是 6,移動到首位是原來數的三倍,求這個數](algorithm/一個數最後一位是6,移動到首位是原來數的三倍,求這個數.md) + * [一個數最後一位是 6,移動到首位是原來數的三倍,求這個數](questions/algorithm/一個數最後一位是6,移動到首位是原來數的三倍,求這個數.md) * math * [Python 怎麼通過 input 獲取矩陣](questions/math/Python怎麼通過input獲取矩陣.md) From 0a518d5c3e057902c64e297dfa415140c71dcd82 Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Tue, 16 Aug 2016 02:17:16 +0800 Subject: [PATCH 15/37] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eb54157..01a6131 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ 這個 repository 收集了一些我自己感覺比較有趣或實用的問題,每篇都會附上原發問者的問題以及我的回答,問題可能經過潤飾,但我盡量維持原貌,回答的部分也多是個人見解,只是希望做個整理並且與有興趣的人分享. -由於問題滿雜的,我只能憑我的直覺將之分類歸檔,目前一共收錄了 75 個問題,大家有興趣的可以參閱[目錄](contents.md). +由於問題滿雜的,我只能憑我的直覺將之分類歸檔,目前一共收錄了 76 個問題,大家有興趣的可以參閱[目錄](contents.md). 如果你有任何的意見或想要討論,都歡迎你開個 issue 來討論唷! From 94fe5906c55edf3301e498f363b57b088a661a88 Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Tue, 16 Aug 2016 16:23:40 +0800 Subject: [PATCH 16/37] =?UTF-8?q?Create=20=E9=97=9C=E6=96=BC=20class=20var?= =?UTF-8?q?iable.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...351\227\234\346\226\274 class variable.md" | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 "draft/\351\227\234\346\226\274 class variable.md" diff --git "a/draft/\351\227\234\346\226\274 class variable.md" "b/draft/\351\227\234\346\226\274 class variable.md" new file mode 100644 index 0000000..f00ccb3 --- /dev/null +++ "b/draft/\351\227\234\346\226\274 class variable.md" @@ -0,0 +1,94 @@ +首先你寫在 class 裡面但不在 method 裡面的 variable 是 class variable + +這個 variable 對於該類別及其子類別的類別和實體而言都只有一份, 看下面這個例子: + +```python +class A: + _dict = {} + def __init__(self): + self._dict.update({'a':'a'}) + +class B(A): + + def __init__(self): + self._dict.update({'b':'b'}) + +if __name__=='__main__': + a = A() + b = B() + print(a._dict) + print(b._dict) + print(A._dict) + print(B._dict) +``` + +``` +{'b': 'b', 'a': 'a'} +{'b': 'b', 'a': 'a'} +{'b': 'b', 'a': 'a'} +{'b': 'b', 'a': 'a'} +``` + +這裡你看到的所有 `_dict` 都參考到同一個物件 + +但是下面這個情況就不太一樣了: + +```python +class A: + _dict = {} + def __init__(self): + self._dict = {} + self._dict.update({'a':'a'}) + +class B(A): + + def __init__(self): + self._dict.update({'b':'b'}) + +class C(A): + + def __init__(self): + super().__init__() + self._dict.update({'c':'c'}) + +if __name__=='__main__': + a = A() + b = B() + c = C() + print(a._dict) + print(b._dict) + print(c._dict) + print(A._dict) + print(B._dict) + print(C._dict) +``` + +``` +{'a': 'a'} +{'b': 'b'} +{'c': 'c', 'a': 'a'} +{'b': 'b'} +{'b': 'b'} +{'b': 'b'} +``` + +咦?! 怎麼變成這樣了呢? 這邊如果搞懂的話就全盤皆通了: + +首先 A 及其子類別都共有一個 class variable, 叫做 `_dict` + +當我們初始化 a 的時候, `self._dict = {}` 會讓 a 裡面新產生一個變數叫做 `_dict`, 因為這次 `self._dict` 出現在等號左邊。注意! 這裡我們已經有兩個不同的東西了, 一個是 class variable `_dict`, 另一個是 instance variable `_dict`, 從此以後, a 裡面拿 `self._dict` 的時候就都是拿到 instance variable 了! + +接著看 b, b 並沒有讓 variable 出現在等號左邊, 所以沒有建立新的變數, 現在 b 中的 `self._dict` 仍然指涉 class variable `_dict` + +c 的情況就比較特別了, 藉由 `super` 他呼叫了 A 的 `__init__`, 上面說過了, 這會讓 c 中新建立一個 instance variable `_dict`, 這個變數因為 `A.__init__` 和 `C.__init__`, 所以會有兩個鍵值對 + + +最後 `A._dict`, `B._dict` 和 `C._dict` 就很容易理解了, 他們都是參考到同一個 class variable, 所以值都一樣。 + +### 小結 + +讓我們來整理一下, 這邊一共會有 3 個 `_dict`: + +1. class variable `_dict` +2. instance variable of a +3. instance variable of c From 03eb5cfdab9da311bb39823d4a922ac09a8a929a Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Sat, 27 Aug 2016 17:54:54 +0800 Subject: [PATCH 17/37] =?UTF-8?q?Create=20=E5=B0=8DPython=E8=AA=9E?= =?UTF-8?q?=E6=B3=95=E5=AD=97=E4=B8=B2=E6=B1=82=E5=80=BC.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...27\344\270\262\346\261\202\345\200\274.md" | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 "questions/\345\260\215Python\350\252\236\346\263\225\345\255\227\344\270\262\346\261\202\345\200\274.md" diff --git "a/questions/\345\260\215Python\350\252\236\346\263\225\345\255\227\344\270\262\346\261\202\345\200\274.md" "b/questions/\345\260\215Python\350\252\236\346\263\225\345\255\227\344\270\262\346\261\202\345\200\274.md" new file mode 100644 index 0000000..5874273 --- /dev/null +++ "b/questions/\345\260\215Python\350\252\236\346\263\225\345\255\227\344\270\262\346\261\202\345\200\274.md" @@ -0,0 +1,46 @@ +# 對 Python 語法字串求值 + +## 問題 + +讀 csv 文件的時候讀到這樣的 str: + +```python +["item1", "item2", "item3"] +``` + +顯然這是一個 list +可是我該如何把它轉化成 list 呢? +用 `list()` 的話每個字符會被當成一個 item +用切詞的方法也應該可以但會麻煩 +但是有沒有直接的方法呢? + +問題出自 [segmentfault](https://segmentfault.com/q/1010000006152237/a-1020000006152877), by [persona](https://segmentfault.com/u/persona) + +## 回答 + +使用 `eval`, 不過要小心他的風險: + +```python +In [1]: s = '["item1", "item2", "item3"]' + +In [2]: lst = eval(s) + +In [3]: lst +Out[3]: ['item1', 'item2', 'item3'] +``` + +* [Python doc - eval](https://docs.python.org/3/library/functions.html#eval) + +對於 Python 的 subset 進行求值, 使用 `ast.literal_eval` 是對的。 + + +```python +# by manong +>>> import ast +>>> ast.literal_eval('["item1", "item2", "item3"]') +['item1', 'item2', 'item3'] +``` + +下面文章值得一讀: + +[Using python's eval() vs. ast.literal_eval()?](http://stackoverflow.com/questions/15197673/using-pythons-eval-vs-ast-literal-eval) From 290315bfb85de9b6c2e571dbea59477f3efb3536 Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Sat, 27 Aug 2016 17:57:17 +0800 Subject: [PATCH 18/37] =?UTF-8?q?Rename=20questions/=E5=B0=8DPython?= =?UTF-8?q?=E8=AA=9E=E6=B3=95=E5=AD=97=E4=B8=B2=E6=B1=82=E5=80=BC.md=20to?= =?UTF-8?q?=20questions/eval/=E5=B0=8DPython=E8=AA=9E=E6=B3=95=E5=AD=97?= =?UTF-8?q?=E4=B8=B2=E6=B1=82=E5=80=BC.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...46\263\225\345\255\227\344\270\262\346\261\202\345\200\274.md" | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename "questions/\345\260\215Python\350\252\236\346\263\225\345\255\227\344\270\262\346\261\202\345\200\274.md" => "questions/eval/\345\260\215Python\350\252\236\346\263\225\345\255\227\344\270\262\346\261\202\345\200\274.md" (100%) diff --git "a/questions/\345\260\215Python\350\252\236\346\263\225\345\255\227\344\270\262\346\261\202\345\200\274.md" "b/questions/eval/\345\260\215Python\350\252\236\346\263\225\345\255\227\344\270\262\346\261\202\345\200\274.md" similarity index 100% rename from "questions/\345\260\215Python\350\252\236\346\263\225\345\255\227\344\270\262\346\261\202\345\200\274.md" rename to "questions/eval/\345\260\215Python\350\252\236\346\263\225\345\255\227\344\270\262\346\261\202\345\200\274.md" From 1b659dda8e7c0ec93b48dbe2e95e13ff91aa0b63 Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Sat, 27 Aug 2016 17:59:03 +0800 Subject: [PATCH 19/37] Update contents.md --- contents.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/contents.md b/contents.md index ff166ad..1b28bd0 100644 --- a/contents.md +++ b/contents.md @@ -19,18 +19,23 @@ ## 函式 +* star expression + * [關於 python * 和 ** 的問題](questions/star/關於python*和**的問題.md) + +* variable scope(global/local/nonlocal/closure) + * [為什麼這兩段 python lambda 出現不同的結果](questions/scope/為什麼這兩段 python lambda 出現不同的結果.md) + +## 內建函式 + * len * [怎麼判斷函數或方法多次使用是否需要定義臨時變量](questions/len/怎麼判斷函數或方法多次使用是否需要定義臨時變量.md) * sort * [Python排序問題](questions/sort/Python排序問題.md) * [sorted函數中key參數的作用原理](questions/sort/sorted函數中key參數的作用原理.md) - -* star expression - * [關於 python * 和 ** 的問題](questions/star/關於python*和**的問題.md) - -* variable scope(global/local/nonlocal/closure) - * [為什麼這兩段 python lambda 出現不同的結果](questions/scope/為什麼這兩段 python lambda 出現不同的結果.md) + +* eval + * [對 Python 語法字串求值](questions/eval/對Python語法字串求值.md) ## 控制流程與迭代 From 9507aa2757b86a9ac6b2dad9b5fff714cc1f38df Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Sat, 27 Aug 2016 17:59:38 +0800 Subject: [PATCH 20/37] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 01a6131..5f23ae6 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ 這個 repository 收集了一些我自己感覺比較有趣或實用的問題,每篇都會附上原發問者的問題以及我的回答,問題可能經過潤飾,但我盡量維持原貌,回答的部分也多是個人見解,只是希望做個整理並且與有興趣的人分享. -由於問題滿雜的,我只能憑我的直覺將之分類歸檔,目前一共收錄了 76 個問題,大家有興趣的可以參閱[目錄](contents.md). +由於問題滿雜的,我只能憑我的直覺將之分類歸檔,目前一共收錄了 77 個問題,大家有興趣的可以參閱[目錄](contents.md). 如果你有任何的意見或想要討論,都歡迎你開個 issue 來討論唷! From 0a340a5ec305f489937daa4a6e01d96de21f8129 Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Sat, 27 Aug 2016 20:02:38 +0800 Subject: [PATCH 21/37] =?UTF-8?q?Create=20Django=20CSRF=20verification=20f?= =?UTF-8?q?ailed=20=E5=95=8F=E9=A1=8C.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...cation failed \345\225\217\351\241\214.md" | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 "questions/django/Django CSRF verification failed \345\225\217\351\241\214.md" diff --git "a/questions/django/Django CSRF verification failed \345\225\217\351\241\214.md" "b/questions/django/Django CSRF verification failed \345\225\217\351\241\214.md" new file mode 100644 index 0000000..f146839 --- /dev/null +++ "b/questions/django/Django CSRF verification failed \345\225\217\351\241\214.md" @@ -0,0 +1,93 @@ +# Django CSRF verification failed 問題 + +## 問題 + +**urls.py** + +```python +from django.conf.urls import url +from django.contrib import admin +from blog import views +urlpatterns = [ + url(r'^admin/', admin.site.urls), + url(r'^$', views.index), + url(r'^abc$',views.handler), +] +``` + +**views.py** + +```python +# -*- coding: utf-8 -*- +from django.shortcuts import render +from django.http import HttpResponse + +# Create your views here. + +def index(request): + return render(request,"index.html") + + +def handler(request): + return HttpResponse("

name:

" + request.POST['username']) +``` + +**index.html** + +```python + + + + + index page + + +
+ + +
+ + + +``` + +我在谷歌瀏覽器下點擊這個提交後出現了: +![图片描述][1] + +我又直接打開abc網站出現了: +![图片描述][2] + +請問這是什麼問題啊要怎麼解決啊? + + + [1]: https://segmentfault.com/img/bVz3ih + [2]: https://segmentfault.com/img/bVz3iq + +問題出自 [segmentfault](https://segmentfault.com/q/1010000006170144/a-1020000006171703), by [dzxczxsb](https://segmentfault.com/u/dzxczxsb) + +## 回答 + +在 Django 中, 使用 post 的時候很可能會出現以下錯誤: + +```python +Forbidden(403): +CSRF verification failed. Request aborted. +Reason given for failure: + CSRF token missing or incorrect. +``` + +這是因為 Django 幫我們啟動了 **CSRF攻擊** 的防護,CSRF(cross-site request forgery) 是惡意的跨站請求或偽裝使用者的攻擊,攻擊者會欺騙用戶的瀏覽器去訪問一個認證過的網站並且執行一些惡意的操作。由於用戶的瀏覽器已經被該網站認證過了,所以該網站會放心的讓這些操作被執行(即便這些操作並非該網站要求的或是不是用戶自願的)。 + +所以我們的伺服器需要一些有保護的措施。常見的一種防護手段,就是使用一個伺服器產生的亂數 token,夾帶在送給客戶端的表單中,當客戶端送回表單時,伺服器檢查這個 token 是不是自己發出,便可以防止攻擊。 + +由於在 `settings.py` 檔中的 `MIDDLEWARE_CLASSES` 中有預設的 `'django.middleware.csrf.CsrfViewMiddleware'`,所以 Django 在這裡便會要求 CSRF token 驗證,為了讓我們的網站更安全,我們還是照著遊戲規則一步一步來吧! + +在html的`
`中加入`{% csrf_token %}`如下: + +```html +... + {% csrf_token %} +... +``` + +就可以解決問題了 From 65f6fdc7c5b938f08ebadd00641f44d5cc53561a Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Sat, 27 Aug 2016 20:03:24 +0800 Subject: [PATCH 22/37] Update contents.md --- contents.md | 1 + 1 file changed, 1 insertion(+) diff --git a/contents.md b/contents.md index 1b28bd0..674eb3e 100644 --- a/contents.md +++ b/contents.md @@ -122,6 +122,7 @@ * [django 如何一個 url 綁定多個視圖](questions/django/django如何一個url綁定多個視圖.md) * [django 模版中變量引用變量被當作字符串處理而不是變量值](questions/django/django模版中變量引用變量被當作字符串處理而不是變量值.md) * [網頁根目錄改成子目錄後文件如何調用](questions/django/網頁根目錄改成子目錄後文件如何調用.md) + * [Django CSRF verification failed 問題](questions/django/Django CSRF verification failed 問題.md) * flask/jinja * [jinja2 macro caller](questions/jinja/jinja2_macro_caller.md) From c3e6df04c9d655b374fbb4b4e6a0470045b12fd1 Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Sat, 27 Aug 2016 20:03:45 +0800 Subject: [PATCH 23/37] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5f23ae6..95be61a 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ 這個 repository 收集了一些我自己感覺比較有趣或實用的問題,每篇都會附上原發問者的問題以及我的回答,問題可能經過潤飾,但我盡量維持原貌,回答的部分也多是個人見解,只是希望做個整理並且與有興趣的人分享. -由於問題滿雜的,我只能憑我的直覺將之分類歸檔,目前一共收錄了 77 個問題,大家有興趣的可以參閱[目錄](contents.md). +由於問題滿雜的,我只能憑我的直覺將之分類歸檔,目前一共收錄了 78 個問題,大家有興趣的可以參閱[目錄](contents.md). 如果你有任何的意見或想要討論,都歡迎你開個 issue 來討論唷! From fc2c02ab145590633f8a650820b19e7af1b5bfcc Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Sun, 26 Mar 2017 19:13:48 +0800 Subject: [PATCH 24/37] Update contents.md --- contents.md | 156 ++++++++++++++++++++++++++-------------------------- 1 file changed, 78 insertions(+), 78 deletions(-) diff --git a/contents.md b/contents.md index 674eb3e..feb6c3a 100644 --- a/contents.md +++ b/contents.md @@ -3,158 +3,158 @@ ## 內建型態與 collections 容器 * string - * [Python 中字串的 bitwise or 怎麼實現?](questions/string/Python中字串的bitwise or怎麼實現.md) - * [給定一個字串,回傳所有的可能組合](questions/string/給定一個字串,回傳所有的可能組合.md) - * [如何讓列表所有元素首字母變大寫](questions/string/如何讓列表所有元素首字母變大寫.md) - * [轉換一個字串為浮點數會報錯](questions/string/轉換一個字串為浮點數會報錯.md) + * [Python 中字串的 bitwise or 怎麼實現?](questions/string/Python中字串的bitwise or怎麼實現.md) + * [給定一個字串,回傳所有的可能組合](questions/string/給定一個字串,回傳所有的可能組合.md) + * [如何讓列表所有元素首字母變大寫](questions/string/如何讓列表所有元素首字母變大寫.md) + * [轉換一個字串為浮點數會報錯](questions/string/轉換一個字串為浮點數會報錯.md) * list - * [遍歷二維串列最外圈](questions/list/遍歷二維串列最外圈.md) - * [list 使用 append 最後為什麼會把前面的元素都修改掉](questions/list/list使用append最後為什麼會把前面的元素都修改掉.md) - * [python 列表取交集](questions/list/python列表取交集.md) + * [遍歷二維串列最外圈](questions/list/遍歷二維串列最外圈.md) + * [list 使用 append 最後為什麼會把前面的元素都修改掉](questions/list/list使用append最後為什麼會把前面的元素都修改掉.md) + * [python 列表取交集](questions/list/python列表取交集.md) * collections - * [會 php 和 Python 的大神進來幫忙轉換一段代碼](questions/collections/會php和python的大神進來幫忙轉換一段代碼.md) - * [Top K Frequent Elements](questions/collections/Top_K_Frequent_Elements.md) + * [會 php 和 Python 的大神進來幫忙轉換一段代碼](questions/collections/會php和python的大神進來幫忙轉換一段代碼.md) + * [Top K Frequent Elements](questions/collections/Top_K_Frequent_Elements.md) ## 函式 * star expression - * [關於 python * 和 ** 的問題](questions/star/關於python*和**的問題.md) + * [關於 python * 和 ** 的問題](questions/star/關於python*和**的問題.md) * variable scope(global/local/nonlocal/closure) - * [為什麼這兩段 python lambda 出現不同的結果](questions/scope/為什麼這兩段 python lambda 出現不同的結果.md) + * [為什麼這兩段 python lambda 出現不同的結果](questions/scope/為什麼這兩段 python lambda 出現不同的結果.md) ## 內建函式 * len - * [怎麼判斷函數或方法多次使用是否需要定義臨時變量](questions/len/怎麼判斷函數或方法多次使用是否需要定義臨時變量.md) + * [怎麼判斷函數或方法多次使用是否需要定義臨時變量](questions/len/怎麼判斷函數或方法多次使用是否需要定義臨時變量.md) * sort - * [Python排序問題](questions/sort/Python排序問題.md) - * [sorted函數中key參數的作用原理](questions/sort/sorted函數中key參數的作用原理.md) + * [Python排序問題](questions/sort/Python排序問題.md) + * [sorted函數中key參數的作用原理](questions/sort/sorted函數中key參數的作用原理.md) * eval - * [對 Python 語法字串求值](questions/eval/對Python語法字串求值.md) + * [對 Python 語法字串求值](questions/eval/對Python語法字串求值.md) ## 控制流程與迭代 * if(if/elif/else) - * [if 語句的 and or 運算](questions/if/if 語句的 and or 運算.md) + * [if 語句的 and or 運算](questions/if/if 語句的 and or 運算.md) * iteration(iterable/iterater/comprehension/generator/generator expression) - * [如何將列表中的元組整個迭代出](questions/iteration/如何將列表中的元組整個迭代出來.md) - * [一個求質(素)數的編程題](questions/iteration/一個求質(素)數的編程題.md) - * [Python 如何合併 list of lists](questions/iteration/Python 如何合併 list of lists.md)(待補充) - * [如何從一個複雜的結構中優雅的提取出一列數據](questions/iteration/如何從一個複雜的結構中優雅的提取出一列數據.md) - * [如何把 tuple 轉成 dictionary](questions/iteration/如何把tuple轉成dictionary.md) - * [Python 的 list 有沒有類似 js 的 find 方法](questions/iteration/Python的list有沒有類似js的find方法.md) - * [python 中既然生成器表達式比列表解析快, 那為什麼不全部使用生成器表達式](questions/iteration/python中既然生成器表達式比列表解析快, 那為什麼不全部使用生成器表達式.md) + * [如何將列表中的元組整個迭代出](questions/iteration/如何將列表中的元組整個迭代出來.md) + * [一個求質(素)數的編程題](questions/iteration/一個求質(素)數的編程題.md) + * [Python 如何合併 list of lists](questions/iteration/Python 如何合併 list of lists.md)(待補充) + * [如何從一個複雜的結構中優雅的提取出一列數據](questions/iteration/如何從一個複雜的結構中優雅的提取出一列數據.md) + * [如何把 tuple 轉成 dictionary](questions/iteration/如何把tuple轉成dictionary.md) + * [Python 的 list 有沒有類似 js 的 find 方法](questions/iteration/Python的list有沒有類似js的find方法.md) + * [python 中既然生成器表達式比列表解析快, 那為什麼不全部使用生成器表達式](questions/iteration/python中既然生成器表達式比列表解析快, 那為什麼不全部使用生成器表達式.md) * functional programming style(map/filter/reduce) - * [sum 函數中可以使用條件語句嗎?](questions/fp/sum函數中可以使用條件語句嗎.md) + * [sum 函數中可以使用條件語句嗎?](questions/fp/sum函數中可以使用條件語句嗎.md) * error handling(exception) - * [Python 如何優雅的處理大量異常語句](questions/error/Python如何優雅的處理大量異常語句.md) - * [python 如何捕獲中斷](questions/error/python如何捕獲中斷.md) + * [Python 如何優雅的處理大量異常語句](questions/error/Python如何優雅的處理大量異常語句.md) + * [python 如何捕獲中斷](questions/error/python如何捕獲中斷.md) ## 物件導向程式設計 * dunder(magic function) - * [自己寫的數據類型使用print無法輸出每個元素](questions/dunder/自己寫的數據類型使用print無法輸出每個元素.md) + * [自己寫的數據類型使用print無法輸出每個元素](questions/dunder/自己寫的數據類型使用print無法輸出每個元素.md) * object(class/object) - * [Python 3.x 實例方法的`__func__`屬性](questions/object/Python 3.x 實例方法的__func__屬性.md) - * [Python 如何通過類方法創建實例方法](questions/object/Python如何通過類方法創建實例方法.md) - * [Python 的 staticmethod 在什麼情況下用](questions/object/Python的staticmethod在什麼情況下用.md) + * [Python 3.x 實例方法的`__func__`屬性](questions/object/Python 3.x 實例方法的__func__屬性.md) + * [Python 如何通過類方法創建實例方法](questions/object/Python如何通過類方法創建實例方法.md) + * [Python 的 staticmethod 在什麼情況下用](questions/object/Python的staticmethod在什麼情況下用.md) ## 檔案與資料處理 * file - * [怎樣合併文檔中有重複部分的行](questions/file/怎樣合併文檔中有重複部分的行.md) - * [Python 處理文本信息](questions/file/Python處理文本信息.md) - * [Python 如何實現並行查找關鍵字所在的行](questions/file/Python如何實現並行查找關鍵字所在的行.md) - * [文本格式轉換代碼優化](questions/file/文本格式轉換代碼優化.md) - * [使用 Python 如何按行數拆分文件](questions/file/使用Python如何按行數拆分文件.md) - * [Python 處理一個求和運算](questions/file/Python處理一個求和運算.md) - * [Python 如何向文件最開始插入一個字串](questions/file/Python如何向文件最開始插入一個字串.md)(待補充) - * [用 Python 實現類似 grep 的功能](questions/file/用Python實現類似grep的功能.md) + * [怎樣合併文檔中有重複部分的行](questions/file/怎樣合併文檔中有重複部分的行.md) + * [Python 處理文本信息](questions/file/Python處理文本信息.md) + * [Python 如何實現並行查找關鍵字所在的行](questions/file/Python如何實現並行查找關鍵字所在的行.md) + * [文本格式轉換代碼優化](questions/file/文本格式轉換代碼優化.md) + * [使用 Python 如何按行數拆分文件](questions/file/使用Python如何按行數拆分文件.md) + * [Python 處理一個求和運算](questions/file/Python處理一個求和運算.md) + * [Python 如何向文件最開始插入一個字串](questions/file/Python如何向文件最開始插入一個字串.md)(待補充) + * [用 Python 實現類似 grep 的功能](questions/file/用Python實現類似grep的功能.md) * json - * [為什麼 json 的 key 只能是 string?](questions/json/為什麼json的key只能是string.md) - * [Python 如何合併批量輸出 json](questions/json/Python如何合併批量輸出json.md) - * [Python 如何讀取 json 中的數據](questions/json/Python如何讀取json中的數據.md) - * [不定深層 Json 剖析](questions/json/不定深層Json剖析.md) + * [為什麼 json 的 key 只能是 string?](questions/json/為什麼json的key只能是string.md) + * [Python 如何合併批量輸出 json](questions/json/Python如何合併批量輸出json.md) + * [Python 如何讀取 json 中的數據](questions/json/Python如何讀取json中的數據.md) + * [不定深層 Json 剖析](questions/json/不定深層Json剖析.md) * cvs - * [csv 模塊生成 CSV 文件問題(0字頭數字缺失與漢字亂碼)](questions/csv/csv模塊生成CSV文件問題(0字頭數字缺失與漢字亂碼).md) - * [操作 csv 文件寫入順序不對](questions/csv/操作csv文件寫入順序不對.md) - * [如何用 python 刪除 csv 文件中的某一列](questions/csv/如何用python刪除csv文件中的某一列.md) + * [csv 模塊生成 CSV 文件問題(0字頭數字缺失與漢字亂碼)](questions/csv/csv模塊生成CSV文件問題(0字頭數字缺失與漢字亂碼).md) + * [操作 csv 文件寫入順序不對](questions/csv/操作csv文件寫入順序不對.md) + * [如何用 python 刪除 csv 文件中的某一列](questions/csv/如何用python刪除csv文件中的某一列.md) ## 模組與套件 * import - * [通過哪個函數能查看 Python 文件中匯入了哪些模組](questions/import/通過哪個函數能查看Python文件中匯入了哪些模組.md) - * [deepcopy 無法 import](questions/import/deepcopy無法import.md) + * [通過哪個函數能查看 Python 文件中匯入了哪些模組](questions/import/通過哪個函數能查看Python文件中匯入了哪些模組.md) + * [deepcopy 無法 import](questions/import/deepcopy無法import.md) * standard library - * [os.mkdir 和 os.makedirs 的區別](questions/standard_lib/os.mkdir和os.makedirs的區別.md) - * [tk 程序中出現問題](questions/standard_lib/tk程序中出現問題.md) - * [計算時間差](questions/standard_lib/計算時間差.md) - * [Python timeit 測量代碼運行時間問題](questions/standard_lib/Python timeit測量代碼運行時間問題.md) - * [Python 日期的遞增問題](questions/standard_lib/Python日期的遞增問題.md) - * [一個需要傳入參數的 python 程序如何封裝成可執行文件](questions/standard_lib/一個需要傳入參數的python程序如何封裝成可執行文件.md) - * [一個結構化顯示文件的腳本,迭代是否有問題](questions/standard_lib/一個結構化顯示文件的腳本,迭代是否有問題.md) - * [如何在 python raw_input 中使用 tab 鍵補全](questions/standard_lib/如何在python raw_input中使用tab鍵補全.md) - * [交換兩個 shelve objects](questions/standard_lib/交換兩個shelve objects.md) - * [Python 獲取文件路徑及文件目錄(`__file__` 的使用方法)](questions/standard_lib/Python 獲取文件路徑及文件目錄(__file__ 的使用方法).md) + * [os.mkdir 和 os.makedirs 的區別](questions/standard_lib/os.mkdir和os.makedirs的區別.md) + * [tk 程序中出現問題](questions/standard_lib/tk程序中出現問題.md) + * [計算時間差](questions/standard_lib/計算時間差.md) + * [Python timeit 測量代碼運行時間問題](questions/standard_lib/Python timeit測量代碼運行時間問題.md) + * [Python 日期的遞增問題](questions/standard_lib/Python日期的遞增問題.md) + * [一個需要傳入參數的 python 程序如何封裝成可執行文件](questions/standard_lib/一個需要傳入參數的python程序如何封裝成可執行文件.md) + * [一個結構化顯示文件的腳本,迭代是否有問題](questions/standard_lib/一個結構化顯示文件的腳本,迭代是否有問題.md) + * [如何在 python raw_input 中使用 tab 鍵補全](questions/standard_lib/如何在python raw_input中使用tab鍵補全.md) + * [交換兩個 shelve objects](questions/standard_lib/交換兩個shelve objects.md) + * [Python 獲取文件路徑及文件目錄(`__file__` 的使用方法)](questions/standard_lib/Python 獲取文件路徑及文件目錄(__file__ 的使用方法).md) * pip - * [pip 無法在安裝 pyinstaller](questions/pip/pip無法在安裝pyinstaller.md) - * [Python 代碼怎麼打包](questions/pip/python代碼怎麼打包.md) + * [pip 無法在安裝 pyinstaller](questions/pip/pip無法在安裝pyinstaller.md) + * [Python 代碼怎麼打包](questions/pip/python代碼怎麼打包.md) * others - * [中文按照拼音排序](questions/others/中文按照拼音排序.md) + * [中文按照拼音排序](questions/others/中文按照拼音排序.md) ## WEB * django - * [django 如何一個 url 綁定多個視圖](questions/django/django如何一個url綁定多個視圖.md) - * [django 模版中變量引用變量被當作字符串處理而不是變量值](questions/django/django模版中變量引用變量被當作字符串處理而不是變量值.md) - * [網頁根目錄改成子目錄後文件如何調用](questions/django/網頁根目錄改成子目錄後文件如何調用.md) - * [Django CSRF verification failed 問題](questions/django/Django CSRF verification failed 問題.md) + * [django 如何一個 url 綁定多個視圖](questions/django/django如何一個url綁定多個視圖.md) + * [django 模版中變量引用變量被當作字符串處理而不是變量值](questions/django/django模版中變量引用變量被當作字符串處理而不是變量值.md) + * [網頁根目錄改成子目錄後文件如何調用](questions/django/網頁根目錄改成子目錄後文件如何調用.md) + * [Django CSRF verification failed 問題](questions/django/Django CSRF verification failed 問題.md) * flask/jinja - * [jinja2 macro caller](questions/jinja/jinja2_macro_caller.md) + * [jinja2 macro caller](questions/jinja/jinja2_macro_caller.md) ## 爬蟲 * beautiful soup - * [刪除 xml 文件的指定標籤](questions/bs/刪除xml文件的指定標籤.md) - * [Python 爬蟲 beautifulsoup string 抓取問題](questions/bs/python爬蟲beautifulsoup string抓取問題.md) + * [刪除 xml 文件的指定標籤](questions/bs/刪除xml文件的指定標籤.md) + * [Python 爬蟲 beautifulsoup string 抓取問題](questions/bs/python爬蟲beautifulsoup string抓取問題.md) ## 演算法與科學計算 * algorithm - * [Subset-Sum Problem](questions/algorithm/subset_sum_problem.md) - * [字串 list 排序(七橋問題)](questions/algorithm/字串list排序(七橋問題).md) - * [使用字串為整數編碼](questions/algorithm/使用字串為整數編碼.md) - * [分群問題](questions/algorithm/分群問題.md) - * [找出所有組合-笛卡爾積問題](questions/algorithm/找出所有組合-笛卡爾積問題.md) - * [燈泡開關問題](questions/algorithm/燈泡開關問題.md) - * [一個數最後一位是 6,移動到首位是原來數的三倍,求這個數](questions/algorithm/一個數最後一位是6,移動到首位是原來數的三倍,求這個數.md) + * [Subset-Sum Problem](questions/algorithm/subset_sum_problem.md) + * [字串 list 排序(七橋問題)](questions/algorithm/字串list排序(七橋問題).md) + * [使用字串為整數編碼](questions/algorithm/使用字串為整數編碼.md) + * [分群問題](questions/algorithm/分群問題.md) + * [找出所有組合-笛卡爾積問題](questions/algorithm/找出所有組合-笛卡爾積問題.md) + * [燈泡開關問題](questions/algorithm/燈泡開關問題.md) + * [一個數最後一位是 6,移動到首位是原來數的三倍,求這個數](questions/algorithm/一個數最後一位是6,移動到首位是原來數的三倍,求這個數.md) * math - * [Python 怎麼通過 input 獲取矩陣](questions/math/Python怎麼通過input獲取矩陣.md) + * [Python 怎麼通過 input 獲取矩陣](questions/math/Python怎麼通過input獲取矩陣.md) ## 大數據與機器學習 * data mining - * [python3 中有聚類(主要是k-means)的函數或者模塊嗎](questions/data_mining/python3中有聚類(主要是k-means)的函數或者模塊嗎.md) + * [python3 中有聚類(主要是k-means)的函數或者模塊嗎](questions/data_mining/python3中有聚類(主要是k-means)的函數或者模塊嗎.md) ## Python 實作與開發環境 * IDE (集成開發環境) - * [Python 能否在保存程序變量情況下啟動控制台](questions/ide/Python能否在保存程序變量情況下啟動控制台.md) + * [Python 能否在保存程序變量情況下啟動控制台](questions/ide/Python能否在保存程序變量情況下啟動控制台.md) * virtualenv - * [如何在 ubuntu14.04 安裝 python3.5](questions/virtualenv/如何在ubuntu14.04安裝python3.5.md) + * [如何在 ubuntu14.04 安裝 python3.5](questions/virtualenv/如何在ubuntu14.04安裝python3.5.md) From e1bec6083c991c5cef7f57b088eafddaab6a0c63 Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Sun, 26 Mar 2017 19:19:30 +0800 Subject: [PATCH 25/37] Update contents.md --- contents.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contents.md b/contents.md index feb6c3a..a94d7c6 100644 --- a/contents.md +++ b/contents.md @@ -3,7 +3,7 @@ ## 內建型態與 collections 容器 * string - * [Python 中字串的 bitwise or 怎麼實現?](questions/string/Python中字串的bitwise or怎麼實現.md) + * [Python 中字串的 bitwise or 怎麼實現?](questions/string/Python中字串的bitwise%20or怎麼實現.md) * [給定一個字串,回傳所有的可能組合](questions/string/給定一個字串,回傳所有的可能組合.md) * [如何讓列表所有元素首字母變大寫](questions/string/如何讓列表所有元素首字母變大寫.md) * [轉換一個字串為浮點數會報錯](questions/string/轉換一個字串為浮點數會報錯.md) From 0437f99ffeecbd3cd1ee53e581c637e75d443c49 Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Sun, 26 Mar 2017 19:32:34 +0800 Subject: [PATCH 26/37] =?UTF-8?q?Create=20=E5=81=87=E5=AE=9A=E6=9C=89json?= =?UTF-8?q?=E6=95=B8=E6=93=9A=E5=A4=9A=E6=A2=9D=E8=A8=98=E9=8C=84=EF=BC=8C?= =?UTF-8?q?=E5=A6=82=E4=BD=95=E6=A0=B9=E6=93=9AKEY=E7=9A=84=E5=80=BC?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E4=B8=80=E6=A2=9D=E8=A8=98=E9=8C=84.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...00\346\242\235\350\250\230\351\214\204.md" | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 "questions/json/\345\201\207\345\256\232\346\234\211json\346\225\270\346\223\232\345\244\232\346\242\235\350\250\230\351\214\204\357\274\214\345\246\202\344\275\225\346\240\271\346\223\232KEY\347\232\204\345\200\274\350\277\224\345\233\236\344\270\200\346\242\235\350\250\230\351\214\204.md" diff --git "a/questions/json/\345\201\207\345\256\232\346\234\211json\346\225\270\346\223\232\345\244\232\346\242\235\350\250\230\351\214\204\357\274\214\345\246\202\344\275\225\346\240\271\346\223\232KEY\347\232\204\345\200\274\350\277\224\345\233\236\344\270\200\346\242\235\350\250\230\351\214\204.md" "b/questions/json/\345\201\207\345\256\232\346\234\211json\346\225\270\346\223\232\345\244\232\346\242\235\350\250\230\351\214\204\357\274\214\345\246\202\344\275\225\346\240\271\346\223\232KEY\347\232\204\345\200\274\350\277\224\345\233\236\344\270\200\346\242\235\350\250\230\351\214\204.md" new file mode 100644 index 0000000..da76948 --- /dev/null +++ "b/questions/json/\345\201\207\345\256\232\346\234\211json\346\225\270\346\223\232\345\244\232\346\242\235\350\250\230\351\214\204\357\274\214\345\246\202\344\275\225\346\240\271\346\223\232KEY\347\232\204\345\200\274\350\277\224\345\233\236\344\270\200\346\242\235\350\250\230\351\214\204.md" @@ -0,0 +1,112 @@ +# 假定有 json 數據多條記錄,如何根據 KEY 的值返回一條記錄? + +## 問題 + +比如說給一個 json 數據: + +```python +[ + { + "Name": "A1", + "No": "3111", + "createDate": "9999/12/31 00:00:00", + "lastUpdDate": "9999/12/31 00:00:00" + }, + { + "Name": "B2", + "No": "2222", + "createDate": "9999/12/31 00:00:00", + "lastUpdDate": "9999/12/31 00:00:00" + }, + { + "Name": "C3", + "No": "1444", + "createDate": "9999/12/31 00:00:00", + "lastUpdDate": "9999/12/31 00:00:00" + }, + { + "Name": "C4", + "No": "0542", + "createDate": "9999/12/31 00:00:00", + "lastUpdDate": "9999/12/31 00:00:00" + } +] +``` + +我想要 `No` 為 `"0542"` 的一條記錄: + +```python +{ + "Name": "C4", + "No": "0542", + "createDate": "9999/12/31 00:00:00", + "lastUpdDate": "9999/12/31 00:00:00" +} +``` + +如果用 python3 應該怎麼實現? + +我網上搜索了類似代碼, 比如: + +```python +data = list(filter(lambda d: d['No'] == "0542", jsondata)) +``` + +改來改去,總是報各種類型錯誤,抓狂了……所以請教下大家,應該怎麼寫,謝謝! + +問題出自 [segmentfault](https://segmentfault.com/q/1010000008793933/a-1020000008795741), by [Nix](https://segmentfault.com/u/nix) + +## 回答 + +假設有 json string 如下: + +```python +s = """ +[ + { + "Name": "A1", + "No": "3111", + "createDate": "9999/12/31 00:00:00", + "lastUpdDate": "9999/12/31 00:00:00" + }, + { + "Name": "B2", + "No": "2222", + "createDate": "9999/12/31 00:00:00", + "lastUpdDate": "9999/12/31 00:00:00" + }, + { + "Name": "C3", + "No": "1444", + "createDate": "9999/12/31 00:00:00", + "lastUpdDate": "9999/12/31 00:00:00" + }, + { + "Name": "C4", + "No": "0542", + "createDate": "9999/12/31 00:00:00", + "lastUpdDate": "9999/12/31 00:00:00" + } +] +""" +``` + +代碼: + +```python +# code for python3 + +import json + +def search(json_str, no): + return [datum for datum in json.loads(s) if datum['No']==no] + +datum = search(s, '0542') +print(datum) +``` + +結果: + +```python +[{'Name': 'C4', 'No': '0542', 'createDate': '9999/12/31 00:00:00', 'lastUpdDate': '9999/12/31 00:00:00'}] +``` From 91f64156224b71d12d82b3cf9ab2a45a29134be2 Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Sun, 26 Mar 2017 19:36:09 +0800 Subject: [PATCH 27/37] Update contents.md --- contents.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/contents.md b/contents.md index a94d7c6..2d80f53 100644 --- a/contents.md +++ b/contents.md @@ -23,7 +23,7 @@ * [關於 python * 和 ** 的問題](questions/star/關於python*和**的問題.md) * variable scope(global/local/nonlocal/closure) - * [為什麼這兩段 python lambda 出現不同的結果](questions/scope/為什麼這兩段 python lambda 出現不同的結果.md) + * [為什麼這兩段 python lambda 出現不同的結果](questions/scope/為什麼這兩段%20python%20lambda%20出現不同的結果.md) ## 內建函式 @@ -45,11 +45,11 @@ * iteration(iterable/iterater/comprehension/generator/generator expression) * [如何將列表中的元組整個迭代出](questions/iteration/如何將列表中的元組整個迭代出來.md) * [一個求質(素)數的編程題](questions/iteration/一個求質(素)數的編程題.md) - * [Python 如何合併 list of lists](questions/iteration/Python 如何合併 list of lists.md)(待補充) + * [Python 如何合併 list of lists](questions/iteration/Python 如何合併%20list%20of%20lists.md)(待補充) * [如何從一個複雜的結構中優雅的提取出一列數據](questions/iteration/如何從一個複雜的結構中優雅的提取出一列數據.md) * [如何把 tuple 轉成 dictionary](questions/iteration/如何把tuple轉成dictionary.md) * [Python 的 list 有沒有類似 js 的 find 方法](questions/iteration/Python的list有沒有類似js的find方法.md) - * [python 中既然生成器表達式比列表解析快, 那為什麼不全部使用生成器表達式](questions/iteration/python中既然生成器表達式比列表解析快, 那為什麼不全部使用生成器表達式.md) + * [python 中既然生成器表達式比列表解析快, 那為什麼不全部使用生成器表達式](questions/iteration/python中既然生成器表達式比列表解析快,%20那為什麼不全部使用生成器表達式.md) * functional programming style(map/filter/reduce) * [sum 函數中可以使用條件語句嗎?](questions/fp/sum函數中可以使用條件語句嗎.md) @@ -64,7 +64,7 @@ * [自己寫的數據類型使用print無法輸出每個元素](questions/dunder/自己寫的數據類型使用print無法輸出每個元素.md) * object(class/object) - * [Python 3.x 實例方法的`__func__`屬性](questions/object/Python 3.x 實例方法的__func__屬性.md) + * [Python 3.x 實例方法的`__func__`屬性](questions/object/Python 3.x%20實例方法的__func__屬性.md) * [Python 如何通過類方法創建實例方法](questions/object/Python如何通過類方法創建實例方法.md) * [Python 的 staticmethod 在什麼情況下用](questions/object/Python的staticmethod在什麼情況下用.md) @@ -85,6 +85,7 @@ * [Python 如何合併批量輸出 json](questions/json/Python如何合併批量輸出json.md) * [Python 如何讀取 json 中的數據](questions/json/Python如何讀取json中的數據.md) * [不定深層 Json 剖析](questions/json/不定深層Json剖析.md) + * [假定有 json 數據多條記錄,如何根據 KEY 的值返回一條記錄](questions/json/假定有json數據多條記錄,如何根據KEY的值返回一條記錄.md) * cvs * [csv 模塊生成 CSV 文件問題(0字頭數字缺失與漢字亂碼)](questions/csv/csv模塊生成CSV文件問題(0字頭數字缺失與漢字亂碼).md) @@ -101,13 +102,13 @@ * [os.mkdir 和 os.makedirs 的區別](questions/standard_lib/os.mkdir和os.makedirs的區別.md) * [tk 程序中出現問題](questions/standard_lib/tk程序中出現問題.md) * [計算時間差](questions/standard_lib/計算時間差.md) - * [Python timeit 測量代碼運行時間問題](questions/standard_lib/Python timeit測量代碼運行時間問題.md) + * [Python timeit 測量代碼運行時間問題](questions/standard_lib/Python%20timeit測量代碼運行時間問題.md) * [Python 日期的遞增問題](questions/standard_lib/Python日期的遞增問題.md) * [一個需要傳入參數的 python 程序如何封裝成可執行文件](questions/standard_lib/一個需要傳入參數的python程序如何封裝成可執行文件.md) * [一個結構化顯示文件的腳本,迭代是否有問題](questions/standard_lib/一個結構化顯示文件的腳本,迭代是否有問題.md) - * [如何在 python raw_input 中使用 tab 鍵補全](questions/standard_lib/如何在python raw_input中使用tab鍵補全.md) + * [如何在 python raw_input 中使用 tab 鍵補全](questions/standard_lib/如何在python%20raw_input中使用tab鍵補全.md) * [交換兩個 shelve objects](questions/standard_lib/交換兩個shelve objects.md) - * [Python 獲取文件路徑及文件目錄(`__file__` 的使用方法)](questions/standard_lib/Python 獲取文件路徑及文件目錄(__file__ 的使用方法).md) + * [Python 獲取文件路徑及文件目錄(`__file__` 的使用方法)](questions/standard_lib/Python%20獲取文件路徑及文件目錄(__file__ 的使用方法).md) * pip * [pip 無法在安裝 pyinstaller](questions/pip/pip無法在安裝pyinstaller.md) From fcf1b3084b405e399f2ba709e06094445254a880 Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Sun, 26 Mar 2017 19:38:27 +0800 Subject: [PATCH 28/37] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 95be61a..0cf8845 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ 這個 repository 收集了一些我自己感覺比較有趣或實用的問題,每篇都會附上原發問者的問題以及我的回答,問題可能經過潤飾,但我盡量維持原貌,回答的部分也多是個人見解,只是希望做個整理並且與有興趣的人分享. -由於問題滿雜的,我只能憑我的直覺將之分類歸檔,目前一共收錄了 78 個問題,大家有興趣的可以參閱[目錄](contents.md). +由於問題滿雜的,我只能憑我的直覺將之分類歸檔,目前一共收錄了 79 個問題,大家有興趣的可以參閱[目錄](contents.md). 如果你有任何的意見或想要討論,都歡迎你開個 issue 來討論唷! From c6e5a179a997767f3b2ce9860ce0ed3be7f691e5 Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Sun, 26 Mar 2017 19:42:02 +0800 Subject: [PATCH 29/37] Update contents.md --- contents.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/contents.md b/contents.md index 2d80f53..c49aa1a 100644 --- a/contents.md +++ b/contents.md @@ -40,12 +40,12 @@ ## 控制流程與迭代 * if(if/elif/else) - * [if 語句的 and or 運算](questions/if/if 語句的 and or 運算.md) + * [if 語句的 and or 運算](questions/if/if%20語句的%20and%20or%20運算.md) * iteration(iterable/iterater/comprehension/generator/generator expression) * [如何將列表中的元組整個迭代出](questions/iteration/如何將列表中的元組整個迭代出來.md) * [一個求質(素)數的編程題](questions/iteration/一個求質(素)數的編程題.md) - * [Python 如何合併 list of lists](questions/iteration/Python 如何合併%20list%20of%20lists.md)(待補充) + * [Python 如何合併 list of lists](questions/iteration/Python%如何合併%20list%20of%20lists.md)(待補充) * [如何從一個複雜的結構中優雅的提取出一列數據](questions/iteration/如何從一個複雜的結構中優雅的提取出一列數據.md) * [如何把 tuple 轉成 dictionary](questions/iteration/如何把tuple轉成dictionary.md) * [Python 的 list 有沒有類似 js 的 find 方法](questions/iteration/Python的list有沒有類似js的find方法.md) @@ -64,7 +64,7 @@ * [自己寫的數據類型使用print無法輸出每個元素](questions/dunder/自己寫的數據類型使用print無法輸出每個元素.md) * object(class/object) - * [Python 3.x 實例方法的`__func__`屬性](questions/object/Python 3.x%20實例方法的__func__屬性.md) + * [Python 3.x 實例方法的`__func__`屬性](questions/object/Python%203.x%20實例方法的__func__屬性.md) * [Python 如何通過類方法創建實例方法](questions/object/Python如何通過類方法創建實例方法.md) * [Python 的 staticmethod 在什麼情況下用](questions/object/Python的staticmethod在什麼情況下用.md) @@ -107,8 +107,8 @@ * [一個需要傳入參數的 python 程序如何封裝成可執行文件](questions/standard_lib/一個需要傳入參數的python程序如何封裝成可執行文件.md) * [一個結構化顯示文件的腳本,迭代是否有問題](questions/standard_lib/一個結構化顯示文件的腳本,迭代是否有問題.md) * [如何在 python raw_input 中使用 tab 鍵補全](questions/standard_lib/如何在python%20raw_input中使用tab鍵補全.md) - * [交換兩個 shelve objects](questions/standard_lib/交換兩個shelve objects.md) - * [Python 獲取文件路徑及文件目錄(`__file__` 的使用方法)](questions/standard_lib/Python%20獲取文件路徑及文件目錄(__file__ 的使用方法).md) + * [交換兩個 shelve objects](questions/standard_lib/交換兩個shelve%20objects.md) + * [Python 獲取文件路徑及文件目錄(`__file__` 的使用方法)](questions/standard_lib/Python%20獲取文件路徑及文件目錄(__file__%20的使用方法).md) * pip * [pip 無法在安裝 pyinstaller](questions/pip/pip無法在安裝pyinstaller.md) @@ -123,7 +123,7 @@ * [django 如何一個 url 綁定多個視圖](questions/django/django如何一個url綁定多個視圖.md) * [django 模版中變量引用變量被當作字符串處理而不是變量值](questions/django/django模版中變量引用變量被當作字符串處理而不是變量值.md) * [網頁根目錄改成子目錄後文件如何調用](questions/django/網頁根目錄改成子目錄後文件如何調用.md) - * [Django CSRF verification failed 問題](questions/django/Django CSRF verification failed 問題.md) + * [Django CSRF verification failed 問題](questions/django/Django%20CSRF%20verification%20failed%20問題.md) * flask/jinja * [jinja2 macro caller](questions/jinja/jinja2_macro_caller.md) @@ -132,7 +132,7 @@ * beautiful soup * [刪除 xml 文件的指定標籤](questions/bs/刪除xml文件的指定標籤.md) - * [Python 爬蟲 beautifulsoup string 抓取問題](questions/bs/python爬蟲beautifulsoup string抓取問題.md) + * [Python 爬蟲 beautifulsoup string 抓取問題](questions/bs/python爬蟲beautifulsoup%20string抓取問題.md) ## 演算法與科學計算 @@ -150,7 +150,7 @@ ## 大數據與機器學習 * data mining - * [python3 中有聚類(主要是k-means)的函數或者模塊嗎](questions/data_mining/python3中有聚類(主要是k-means)的函數或者模塊嗎.md) +  * [python3 中有聚類(主要是k-means)的函數或者模塊嗎](questions/data_mining/python3中有聚類(主要是k-means)%20的函數或者模塊嗎.md) ## Python 實作與開發環境 From 54a0bed82e53a2e9b9ca6065252c1d6222b02f28 Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Sun, 26 Mar 2017 19:45:03 +0800 Subject: [PATCH 30/37] Update contents.md --- contents.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contents.md b/contents.md index c49aa1a..002872e 100644 --- a/contents.md +++ b/contents.md @@ -149,8 +149,9 @@ * [Python 怎麼通過 input 獲取矩陣](questions/math/Python怎麼通過input獲取矩陣.md) ## 大數據與機器學習 + * data mining -  * [python3 中有聚類(主要是k-means)的函數或者模塊嗎](questions/data_mining/python3中有聚類(主要是k-means)%20的函數或者模塊嗎.md) + * [python3 中有聚類(主要是k-means)的函數或者模塊嗎](questions/data_mining/python3中有聚類(主要是k-means)%20的函數或者模塊嗎.md) ## Python 實作與開發環境 From 4ea07d0310a97490405cfdf360146190458b2b11 Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Sun, 7 May 2017 03:19:52 +0800 Subject: [PATCH 31/37] Create finput.py --- draft/finput.py | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 draft/finput.py diff --git a/draft/finput.py b/draft/finput.py new file mode 100644 index 0000000..19af047 --- /dev/null +++ b/draft/finput.py @@ -0,0 +1,76 @@ +# author: dokelung + +import re +from ast import literal_eval +from functools import partial + + +class InputDoesNotMatchFStr(Exception): pass +class TypeConvertError(Exception): pass +class InputCountNotInRange(Exception): pass + + +FORMAT_SPECIFIER = { + '%a': literal_eval, + '%d': int, + '%f': float, + '%o': partial(int, base=8), + '%s': str, + '%x': partial(int, base=16), +} + + +def finput(prompt='', fstr='%s', expand_fsp=None, + whitespace=False, + escape_parenthesis=True): + """format input + """ + fsp = FORMAT_SPECIFIER + if expand_fsp is not None: + fsp.update(expand_fsp) + if escape_parenthesis: + rstr = fstr.replace('(', '\(').replace(')', '\)') + else: + rstr = fstr + regex = '(.+)' if whitespace else '(\S+)' + for sp, typ in fsp.items(): + rstr = rstr.replace(sp, regex) + types = [] + for idx, c in enumerate(fstr): + pattern = fstr[idx:idx+2] + if pattern in fsp: + types.append(fsp[pattern]) + pure_input = input(prompt) + mobj = re.match(rstr, pure_input) + if mobj: + try: + return tuple(typ(value) for value, typ in zip(mobj.groups(), types)) + except Exception as err: + raise TypeConvertError(err) + else: + msg = 'input does not match format string "{}"' + raise InputDoesNotMatchFStr(msg.format(fstr)) + + +def minput(prompt='', typ=str, sep=None, min=1, max=100000): + """multiple input + """ + pure_input = input(prompt) + try: + if sep is None: + values = tuple(typ(item) for item in pure_input.split()) + else: + values = tuple(typ(item) for item in pure_input.split(sep)) + except Exception as err: + raise TypeConvertError(err) + if len(values) < min or len(values) > max: + msg = 'input count {} is not in range [{}, {}]' + raise InputCountNotInRange(msg.format(len(values), min, max)) + return values + + +if __name__ == '__main__': + #res = finput('>>> ', fstr='%s, *%d, *%f') + #print(res) + res = minput('>>> ', typ=int, min=1, max=3) + print(res) From e46edb540c41785a10b9e92018bd673e1f66b20e Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Sat, 18 Nov 2017 13:20:33 +0800 Subject: [PATCH 32/37] =?UTF-8?q?Create=20Python=E5=A4=9A=E9=87=8D?= =?UTF-8?q?=E7=B9=BC=E6=89=BF=E5=B1=AC=E6=80=A7=E5=95=8F=E9=A1=8C.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...54\346\200\247\345\225\217\351\241\214.md" | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 "questions/object/Python\345\244\232\351\207\215\347\271\274\346\211\277\345\261\254\346\200\247\345\225\217\351\241\214.md" diff --git "a/questions/object/Python\345\244\232\351\207\215\347\271\274\346\211\277\345\261\254\346\200\247\345\225\217\351\241\214.md" "b/questions/object/Python\345\244\232\351\207\215\347\271\274\346\211\277\345\261\254\346\200\247\345\225\217\351\241\214.md" new file mode 100644 index 0000000..68c2af2 --- /dev/null +++ "b/questions/object/Python\345\244\232\351\207\215\347\271\274\346\211\277\345\261\254\346\200\247\345\225\217\351\241\214.md" @@ -0,0 +1,109 @@ +# Python 多重繼承屬性問題 + +## 問題 + +Python 類的繼承,怎麽讓一個子類 `C`, 同時繼承父類 `A`, `B` 的屬性? + +先定義兩父類: + +```python + class A(object): + def __init__(self, a1,a2): + # super(ClassName, self).__init__() + self.a1 = a1 + self.a2 = a2 + + def funa(self): + print("I'm funa") + + class B(object): + def __init__(self, b1): + # super(ClassName, self).__init__() + self.b1 = b1 + + def funb(self): + print("I'm funb") +``` + +那麽子類 `C` 應該如何寫? 才能讓初始化後具有 `A`, `B` 中的 `a1`, `a2`, `b1` 屬性和 `funa`, `funb` 方法? + +```python + class C(A,B): + # ???????????????????? + def __init__(self): + super().__init__() + #????????????????????? + pass +``` +感覺是很基本的問題,求各位大佬解答,謝謝! + +問題出自 [segmentfault](), by [Andykim](https://segmentfault.com/u/andykim) + +## 回答 + +假設你要多重繼承的 **各個父類關係是平行的**, 多重繼承用於 **組合各父類的成員** (**Mixin** 的概念), 那你可以考慮下面這個例子, 而為了展示通用性, 下面的例子中有三個可能被用來繼承的父類 `A`, `B`, `C`, 而其子類 (例如 `X`, `Y`)可以用任意順序來組合任意數量個父類: + +```python +# base classes + +class A: + def __init__(self, a1, a2, **kwargs): + super().__init__(**kwargs) + self.a1 = a1 + self.a2 = a2 + + def funa(self): + print("I'm funa") + +class B: + def __init__(self, b1, **kwargs): + super().__init__(**kwargs) + self.b1 = b1 + + def funb(self): + print("I'm funb") + +class C: + def __init__(self, c1, c2, c3, **kwargs): + super().__init__(**kwargs) + self.c1 = c1 + self.c2 = c2 + self.c3 = c3 + + def func(self): + print("I'm func") +``` + +```python +# derived classes + +class X(B, A, C): + def __init__(self, **kwargs): + super().__init__(**kwargs) + +class Y(A, B): + def __init__(self, **kwargs): + super().__init__(**kwargs) +``` + +使用範例: + +```python +x = X(a1=1, a2=2, b1=3, c1=4, c2=5, c3=6) +y = Y(a1=1, a2=2, b1=3) +print(x.a1, x.a2, x.b1, x.c1, x.c2, x.c3) +x.funa() +y.funb() +print(dir(x)) +print(dir(y)) +``` + +結果: + +```python +1 2 3 4 5 6 +I'm funa +I'm funb +['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a1', 'a2', 'b1', 'c1', 'c2', 'c3', 'funa', 'funb', 'func'] +['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a1', 'a2', 'b1', 'funa', 'funb'] +``` From da2de0e800bc016b2eb164bf109bf8686bd1b3f4 Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Sat, 18 Nov 2017 13:21:51 +0800 Subject: [PATCH 33/37] Update contents.md --- contents.md | 1 + 1 file changed, 1 insertion(+) diff --git a/contents.md b/contents.md index 002872e..a1bf33c 100644 --- a/contents.md +++ b/contents.md @@ -67,6 +67,7 @@ * [Python 3.x 實例方法的`__func__`屬性](questions/object/Python%203.x%20實例方法的__func__屬性.md) * [Python 如何通過類方法創建實例方法](questions/object/Python如何通過類方法創建實例方法.md) * [Python 的 staticmethod 在什麼情況下用](questions/object/Python的staticmethod在什麼情況下用.md) + * [Python 多重繼承屬性問題](questions/object/Python多重繼承屬性問題.md) ## 檔案與資料處理 From 37eb56c37305190b858e95d46aee44b697a8e444 Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Sat, 18 Nov 2017 13:22:24 +0800 Subject: [PATCH 34/37] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0cf8845..68a68fc 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ 這個 repository 收集了一些我自己感覺比較有趣或實用的問題,每篇都會附上原發問者的問題以及我的回答,問題可能經過潤飾,但我盡量維持原貌,回答的部分也多是個人見解,只是希望做個整理並且與有興趣的人分享. -由於問題滿雜的,我只能憑我的直覺將之分類歸檔,目前一共收錄了 79 個問題,大家有興趣的可以參閱[目錄](contents.md). +由於問題滿雜的,我只能憑我的直覺將之分類歸檔,目前一共收錄了 80 個問題,大家有興趣的可以參閱[目錄](contents.md). 如果你有任何的意見或想要討論,都歡迎你開個 issue 來討論唷! From 0f0abf1fe5102a08a921031660823f39c9f06bcc Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Sat, 18 Nov 2017 13:27:27 +0800 Subject: [PATCH 35/37] =?UTF-8?q?Create=20python=E7=94=9F=E6=88=90?= =?UTF-8?q?=E7=89=B9=E5=AE=9A=E5=88=97=E8=A1=A8=E6=A0=BC=E5=BC=8F.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...27\350\241\250\346\240\274\345\274\217.md" | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 "questions/list/python\347\224\237\346\210\220\347\211\271\345\256\232\345\210\227\350\241\250\346\240\274\345\274\217.md" diff --git "a/questions/list/python\347\224\237\346\210\220\347\211\271\345\256\232\345\210\227\350\241\250\346\240\274\345\274\217.md" "b/questions/list/python\347\224\237\346\210\220\347\211\271\345\256\232\345\210\227\350\241\250\346\240\274\345\274\217.md" new file mode 100644 index 0000000..b0cc587 --- /dev/null +++ "b/questions/list/python\347\224\237\346\210\220\347\211\271\345\256\232\345\210\227\350\241\250\346\240\274\345\274\217.md" @@ -0,0 +1,93 @@ +# python 如何生成特定列表格式 + +## 問題 + +```python +aa = [ + {'ip': '192.168.1.1', 'projectname__pname': 'hh', 'id': 1, 'projectname_id': 1}, + {'ip': '192.168.3.2', 'projectname__pname': 'hh', 'id': 2, 'projectname_id': 1}, + {'ip': '192.168.22.3', 'projectname__pname': 'qm', 'id': 3, 'projectname_id': 2}, + {'ip': '192.168.5.3', 'projectname__pname': 'ssh', 'id':4, 'projectname_id': 3} +] +``` + +大家好,我想把 `aa` 中的列表生成以下 `bb` 的格式: + +```python +bb = [ + { + 'projectname_id': 1, + 'projectname__pname': 'hh', + 'children': [{'id': 1, 'text': '192.168.1.1'},{'id': 2, 'text': '192.168.1.2'}] + }, + { + 'projectname_id': 2, + 'projectname__pname': 'qm', + 'children': [{'id': 3, 'text':'192.168.22.3'}] + }, + { + 'projectname_id': 3, + 'projectname__pname': 'ssh', + 'children': [{'id': 4, 'text': '192.168.5.3'}] + } +] +``` + +請問代碼怎麽實現? + +問題出自 [segmentfault](), by [tempreg](https://segmentfault.com/u/tempreg) + +## 回答 + +代碼: + +```python +def aa2bb(aa): + bb = [] + proj_id_map = {} + for ad in aa: + proj_id = ad['projectname_id'] + child = {'id': ad['id'], 'text': ad['ip']} + if proj_id not in proj_id_map: + bd = { + 'projectname__pname': ad['projectname__pname'], + 'projectname_id': ad['projectname_id'], + 'children': [child] + } + bb.append(bd) + proj_id_map[proj_id] = bd + else: + bd = proj_id_map[proj_id] + bd['children'].append(child) + return bb +``` + +測試: + +```python +from pprint import pprint + +aa = [ + {'ip': '192.168.1.1', 'projectname__pname': 'hh', 'id': 1, 'projectname_id': 1}, + {'ip': '192.168.3.2', 'projectname__pname': 'hh', 'id': 2, 'projectname_id': 1}, + {'ip': '192.168.22.3', 'projectname__pname': 'qm', 'id': 3, 'projectname_id': 2}, + {'ip': '192.168.5.3', 'projectname__pname': 'ssh', 'id':4, 'projectname_id': 3} +] + +pprint(aa2bb(aa)) +``` + +結果: + +```python +[{'children': [{'id': 1, 'text': '192.168.1.1'}, + {'id': 2, 'text': '192.168.3.2'}], + 'projectname__pname': 'hh', + 'projectname_id': 1}, + {'children': [{'id': 3, 'text': '192.168.22.3'}], + 'projectname__pname': 'qm', + 'projectname_id': 2}, + {'children': [{'id': 4, 'text': '192.168.5.3'}], + 'projectname__pname': 'ssh', + 'projectname_id': 3}] +``` From 84726693900234c9b3109bb10c73f0bf4edaab43 Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Sat, 18 Nov 2017 13:28:28 +0800 Subject: [PATCH 36/37] Update contents.md --- contents.md | 1 + 1 file changed, 1 insertion(+) diff --git a/contents.md b/contents.md index a1bf33c..998df8a 100644 --- a/contents.md +++ b/contents.md @@ -12,6 +12,7 @@ * [遍歷二維串列最外圈](questions/list/遍歷二維串列最外圈.md) * [list 使用 append 最後為什麼會把前面的元素都修改掉](questions/list/list使用append最後為什麼會把前面的元素都修改掉.md) * [python 列表取交集](questions/list/python列表取交集.md) +  * [python 生成特定列表格式](questions/list/python生成特定列表格式.md) * collections * [會 php 和 Python 的大神進來幫忙轉換一段代碼](questions/collections/會php和python的大神進來幫忙轉換一段代碼.md) From bca409e34788b408b509bd1b198f5069026a8a82 Mon Sep 17 00:00:00 2001 From: Ko-Lung Yuan Date: Sat, 18 Nov 2017 13:28:50 +0800 Subject: [PATCH 37/37] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 68a68fc..3e095dd 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ 這個 repository 收集了一些我自己感覺比較有趣或實用的問題,每篇都會附上原發問者的問題以及我的回答,問題可能經過潤飾,但我盡量維持原貌,回答的部分也多是個人見解,只是希望做個整理並且與有興趣的人分享. -由於問題滿雜的,我只能憑我的直覺將之分類歸檔,目前一共收錄了 80 個問題,大家有興趣的可以參閱[目錄](contents.md). +由於問題滿雜的,我只能憑我的直覺將之分類歸檔,目前一共收錄了 81 個問題,大家有興趣的可以參閱[目錄](contents.md). 如果你有任何的意見或想要討論,都歡迎你開個 issue 來討論唷!