├── .ipynb_checkpoints ├── CHAPTER 2 Numbers, Strings,and Variables-checkpoint.ipynb ├── CHAPTER 3 Py Filling Lists, Tuples, Dictionaries and Sets-checkpoint.ipynb ├── CHAPTER 4 Py Crust- Code Structures-checkpoint.ipynb ├── CHAPTER 5 Py Boxes- Modules, Packages, and Programs-checkpoint.ipynb ├── CHAPTER 6 Oh Oh- Objects and Classes-checkpoint.ipynb ├── CHAPTER 7 Mangle Data Like a Pro-checkpoint.ipynb ├── CHAPTER 8 Data Has to Go Somewhere-checkpoint.ipynb └── CHAPTER 9 The Web, Untangled-checkpoint.ipynb ├── CHAPTER 10 Systems.ipynb ├── CHAPTER 11 Concurrency and Networks.ipynb ├── CHAPTER 2 Numbers, Strings,and Variables.ipynb ├── CHAPTER 3 Py Filling Lists, Tuples, Dictionaries and Sets.ipynb ├── CHAPTER 4 Py Crust- Code Structures.ipynb ├── CHAPTER 5 Py Boxes- Modules, Packages, and Programs.ipynb ├── CHAPTER 6 Oh Oh- Objects and Classes.ipynb ├── CHAPTER 7 Mangle Data Like a Pro.ipynb ├── CHAPTER 8 Data Has to Go Somewhere.ipynb ├── CHAPTER 9 The Web, Untangled.ipynb ├── Data ├── bfile ├── dishes.py ├── dishes_process.py ├── dishes_threads.py ├── menu.xml ├── mp.py ├── mp2.py ├── mp_threads.py ├── relativity └── villains ├── LICENSE └── README.md /.ipynb_checkpoints/CHAPTER 2 Numbers, Strings,and Variables-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "\n", 8 | "# CHAPTER 2 Numbers, Strings,and Variables\n", 9 | "## Python的基本元素:數字,字串和變量\n", 10 | "\n", 11 | "* [2.1 變數 名稱 物件](#Variables_Names_Objects)\n", 12 | "* [2.2 數字](#Numbers)\n", 13 | "* [2.3 字串](#Strings)\n", 14 | "\n", 15 | "\n", 16 | "Python內建的型態有\n", 17 | "* 布林值 Boolean (True 、 False)\n", 18 | "* 整數 Integer\n", 19 | "* 浮點數 Float (可用科學記號表示法 ex. 1.0e3 = 1000.0)\n", 20 | "* 字串 String (字元組成的陣列)" 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "metadata": {}, 26 | "source": [ 27 | "------\n", 28 | "\n", 29 | "## 2.1 變數 名稱 物件\n", 30 | "[回目錄](#HOME)\n" 31 | ] 32 | }, 33 | { 34 | "cell_type": "markdown", 35 | "metadata": {}, 36 | "source": [ 37 | "Python為物件導向作為設計,所有的數據皆為Objcet,詳細的物件導向觀念可參考wiki中的介紹或是書中的介紹。 \n", 38 | "其中要特別注意所謂的針對某個特定物件型別內建method上的使用, \n", 39 | "例如string型別內建upper函數,可以把文字轉成大寫,則要使用上的方法為__string.upper()__, \n", 40 | "若是一個一般的內建method或是使用者自行建立的function, \n", 41 | "例如__len()__,則使用上的方法為 __len('abc')__, \n", 42 | "所以在學習Python時,需要清楚了解此function是針對某個型別的內建還是一般狀況。 \n", 43 | "\n", 44 | "其中要注意的是Python為強型別(Strongly typed),也就是說在執行 '1' + 2,會出現TypeError,並不會出現3或是'12'的結果,所以進行不同型別之間的處理可以使用 int('1') + 2 = 3或是 '1' + str(2) = '12'來作為處理。\n", 45 | "\n", 46 | "跟大多數語言一樣,再給定變數數值是使用 '=' 來賦予值,在Python中變數不用宣告,並且還有一個特性為,變數在記憶體位置中僅僅像是標籤一般,對某個記憶體位置做貼標籤功能,在變數改變內容時,記憶體內的值不會改變,而是變數標籤貼到其他記憶體位置上。因此Python不用宣告變數型別,故可以改變變數內的型別,所以可以使用_type(變數)_做為檢測變數現在的型別。\n", 47 | "\n", 48 | "變數的命名不外乎就是只能大小寫英文字母、 數字與底線(_),且不能以數字開頭,相關保留關鍵字如下,請勿作為變數名稱使用。\n", 49 | "\n", 50 | "\n", 51 | "![Alt text](http://i.imgur.com/vS3VxFe.png \"保留關鍵字\")" 52 | ] 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "metadata": {}, 57 | "source": [ 58 | "------\n", 59 | "\n", 60 | "## 2.2 數字\n", 61 | "[回目錄](#HOME)\n", 62 | "\n", 63 | "基本運算符號如下\n", 64 | "\n", 65 | "|符號|解釋|用法|\n", 66 | "|--|--|--|\n", 67 | "|+|加法|2 + 3 = 5|\n", 68 | "|-|減法|2 - 3 = -1|\n", 69 | "|\\*|乘法|2 * 3 = 6|\n", 70 | "|/|浮點數除法|3 / 2 = 1.5|\n", 71 | "|//|整數除法 (商數)|3 // 2 = 1|\n", 72 | "|%|餘數|3 % 2 = 1|\n", 73 | "|\\*\\*|次方|2 \\*\\* 3 = 8|\n", 74 | "\n", 75 | "\n", 76 | "對於正整數的操作,比較要注意的為0不可以放置在數字前端,如 a = 05 會出現SyntaxError。 \n", 77 | "於整數使用'/'除法上也會得到浮點數結果,並不需要特別轉換成浮點數再做除法運算。\n", 78 | "\n", 79 | "其餘運算規則與用法詳細請看書本介紹(ex. a = a + 1可以寫成 a += 1 等等) \n", 80 | "數字型別轉換可以用__int()__,裡面不允許有非數字出現,浮點數會無條件捨去,其中python允許使用__int(98.7) = 98__,但__int('98.7')__則會出現錯誤,這點要多加小心。\n", 81 | "\n", 82 | "最為重要的一點為Python3之後沒有溢位問題,意旨儲存整數大小無上限,取決於自身記憶體限制。\n", 83 | "\n", 84 | "轉換成浮點數可以使用__float()__。" 85 | ] 86 | }, 87 | { 88 | "cell_type": "markdown", 89 | "metadata": {}, 90 | "source": [ 91 | "------\n", 92 | "\n", 93 | "## 2.3 字串\n", 94 | "[回目錄](#HOME)\n", 95 | "\n", 96 | "Python3支援Unicode!!!! 表示可以顯示中文等等,檔案編碼方式記得選擇Unicode \n", 97 | "使用單或雙引號皆可以創建字串,若要在字串中包含單雙引號只要 \n", 98 | "用相反的作為外框 \n", 99 | "使用跳脫字元\\' \\\" \n", 100 | "連續使用三次即可(單,雙引號都可以)\n", 101 | "\n", 102 | "三個單引號'''還可以用再多行字串的建立,一般常用於多行註解上使用。 \n", 103 | "在使用print()指令時,會自動將跳脫字元轉換成正確的顯示方式(ex. \\n轉換成跳行等等) \n", 104 | "並且會在變數之間插入一空白\n", 105 | "\n", 106 | "```Python\n", 107 | "print('a','b','c') # 'a' 'b' 'c'\n", 108 | "```\n", 109 | "\n", 110 | "可以使用__str()__將其餘類別轉換成字串型態。\n", 111 | "\n", 112 | "字串相連接時可以使用 + 號或是直接把兩字串擺在前後即可。( print('a'+'b') print('a''b') 都可以得到 'ab'的結果 ) \n", 113 | "使用\\*可以快速建立重複字串。\n", 114 | "\n", 115 | "```Python\n", 116 | "print('a' * 5) # 'aaaaa'\n", 117 | "```" 118 | ] 119 | }, 120 | { 121 | "cell_type": "code", 122 | "execution_count": 1, 123 | "metadata": { 124 | "collapsed": false 125 | }, 126 | "outputs": [ 127 | { 128 | "name": "stdout", 129 | "output_type": "stream", 130 | "text": [ 131 | "b\n", 132 | "d\n" 133 | ] 134 | } 135 | ], 136 | "source": [ 137 | "#前述提到字串為字元的陣列,故可以使用[ ]來提取特定位置之字元,(相關的容器介紹在CH3)\n", 138 | "\n", 139 | "a = 'bcd' \n", 140 | "print(a[0]) #'b' \n", 141 | "print(a[-1]) #'d'\n", 142 | "\n", 143 | "#index從0開始,-1為最後一個字元" 144 | ] 145 | }, 146 | { 147 | "cell_type": "markdown", 148 | "metadata": {}, 149 | "source": [ 150 | "更多的提取方法如下\n", 151 | "\n", 152 | "|用法|說明|\n", 153 | "|--|--|\n", 154 | "|[ : ]|提取全部|\n", 155 | "|[start : ]|提取 start 至結束|\n", 156 | "|[ : end]|提取開頭到 end - 1|\n", 157 | "|[start : end]|提取 start 至 end - 1|\n", 158 | "|[start : end : step]|提取 start 至 end - 1,間隔為 step (step為負的時則從右邊開始,start與end需反過來擺放)|\n" 159 | ] 160 | }, 161 | { 162 | "cell_type": "code", 163 | "execution_count": 2, 164 | "metadata": { 165 | "collapsed": false 166 | }, 167 | "outputs": [ 168 | { 169 | "name": "stdout", 170 | "output_type": "stream", 171 | "text": [ 172 | "edcba\n", 173 | "dcb\n" 174 | ] 175 | } 176 | ], 177 | "source": [ 178 | "a = 'abcde'\n", 179 | "print(a[::-1]) #'edcba' 可以變成反序排列\n", 180 | "print(a[-2:0:-1]) #'dcb'" 181 | ] 182 | }, 183 | { 184 | "cell_type": "markdown", 185 | "metadata": {}, 186 | "source": [ 187 | "其中變數內的字串是不能替換內容(因為容器為類似TUPLES的型態,CH3會說明),\n", 188 | "若要替換內容,則可以使用重組或是 __string.replace()__" 189 | ] 190 | }, 191 | { 192 | "cell_type": "code", 193 | "execution_count": 3, 194 | "metadata": { 195 | "collapsed": false 196 | }, 197 | "outputs": [ 198 | { 199 | "name": "stdout", 200 | "output_type": "stream", 201 | "text": [ 202 | "Penny\n", 203 | "Penny\n" 204 | ] 205 | } 206 | ], 207 | "source": [ 208 | "name = 'Henny'\n", 209 | "#name[0] = 'P' #錯誤!!!!!!\n", 210 | "a = name.replace('H', 'P') #'Penny'\n", 211 | "print(a)\n", 212 | "print('P' + name[1:]) #'Penny'" 213 | ] 214 | }, 215 | { 216 | "cell_type": "markdown", 217 | "metadata": {}, 218 | "source": [ 219 | "__len()__ 可以獲得長度" 220 | ] 221 | }, 222 | { 223 | "cell_type": "code", 224 | "execution_count": 4, 225 | "metadata": { 226 | "collapsed": false 227 | }, 228 | "outputs": [ 229 | { 230 | "data": { 231 | "text/plain": [ 232 | "3" 233 | ] 234 | }, 235 | "execution_count": 4, 236 | "metadata": {}, 237 | "output_type": "execute_result" 238 | } 239 | ], 240 | "source": [ 241 | "a = 'abc'\n", 242 | "len(a)" 243 | ] 244 | }, 245 | { 246 | "cell_type": "markdown", 247 | "metadata": {}, 248 | "source": [ 249 | "__string.split()__可以分割字串成list,( )內可以指定符號,預設會切割\\n(換行) 、 \\t(tab)與空格三種" 250 | ] 251 | }, 252 | { 253 | "cell_type": "code", 254 | "execution_count": 5, 255 | "metadata": { 256 | "collapsed": false 257 | }, 258 | "outputs": [ 259 | { 260 | "name": "stdout", 261 | "output_type": "stream", 262 | "text": [ 263 | "['get gloves', 'get mask', 'give cat vitamins', 'call ambulance']\n", 264 | "['get', 'gloves,get', 'mask,give', 'cat', 'vitamins,call', 'ambulance']\n" 265 | ] 266 | } 267 | ], 268 | "source": [ 269 | "todos = 'get gloves,get mask,give cat vitamins,call ambulance'\n", 270 | "print(todos.split(','))\n", 271 | "print(todos.split())" 272 | ] 273 | }, 274 | { 275 | "cell_type": "markdown", 276 | "metadata": {}, 277 | "source": [ 278 | "__'符號'.join()__可以合併list成字串" 279 | ] 280 | }, 281 | { 282 | "cell_type": "code", 283 | "execution_count": 6, 284 | "metadata": { 285 | "collapsed": false 286 | }, 287 | "outputs": [ 288 | { 289 | "data": { 290 | "text/plain": [ 291 | "'Yeti, Bigfoot, Loch Ness Monster'" 292 | ] 293 | }, 294 | "execution_count": 6, 295 | "metadata": {}, 296 | "output_type": "execute_result" 297 | } 298 | ], 299 | "source": [ 300 | "crypto_list = ['Yeti', 'Bigfoot', 'Loch Ness Monster']\n", 301 | "', '.join(crypto_list)" 302 | ] 303 | }, 304 | { 305 | "cell_type": "markdown", 306 | "metadata": {}, 307 | "source": [ 308 | "__string.startswith()__ 與 __string.endswith()__ 分別可以檢查開頭與結束字串是否為特定字串,回傳__True__或__False__" 309 | ] 310 | }, 311 | { 312 | "cell_type": "code", 313 | "execution_count": 7, 314 | "metadata": { 315 | "collapsed": false 316 | }, 317 | "outputs": [ 318 | { 319 | "name": "stdout", 320 | "output_type": "stream", 321 | "text": [ 322 | "True\n", 323 | "False\n" 324 | ] 325 | } 326 | ], 327 | "source": [ 328 | "poem = 'abcdef'\n", 329 | "print(poem.startswith('ab'))\n", 330 | "print(poem.endswith('eef'))" 331 | ] 332 | }, 333 | { 334 | "cell_type": "markdown", 335 | "metadata": {}, 336 | "source": [ 337 | "__string.find()__ 與 __string.rfind()__ 可以查詢第一次與最後一次出現搜尋字串的index,__string.count()__可以查詢字串出現次數" 338 | ] 339 | }, 340 | { 341 | "cell_type": "code", 342 | "execution_count": 8, 343 | "metadata": { 344 | "collapsed": false 345 | }, 346 | "outputs": [ 347 | { 348 | "name": "stdout", 349 | "output_type": "stream", 350 | "text": [ 351 | "1\n", 352 | "6\n", 353 | "2\n" 354 | ] 355 | } 356 | ], 357 | "source": [ 358 | "poem = 'abcdefbcd'\n", 359 | "print(poem.find('bc'))\n", 360 | "print(poem.rfind('bc'))\n", 361 | "print(poem.count('bc'))" 362 | ] 363 | }, 364 | { 365 | "cell_type": "markdown", 366 | "metadata": {}, 367 | "source": [ 368 | "__string.isalnum()__可以查詢字串中是否都是字母或數字,回傳__True__或__False__" 369 | ] 370 | }, 371 | { 372 | "cell_type": "code", 373 | "execution_count": 9, 374 | "metadata": { 375 | "collapsed": false 376 | }, 377 | "outputs": [ 378 | { 379 | "data": { 380 | "text/plain": [ 381 | "False" 382 | ] 383 | }, 384 | "execution_count": 9, 385 | "metadata": {}, 386 | "output_type": "execute_result" 387 | } 388 | ], 389 | "source": [ 390 | "poem = 'abc@def'\n", 391 | "poem.isalnum()" 392 | ] 393 | }, 394 | { 395 | "cell_type": "code", 396 | "execution_count": 10, 397 | "metadata": { 398 | "collapsed": false 399 | }, 400 | "outputs": [ 401 | { 402 | "name": "stdout", 403 | "output_type": "stream", 404 | "text": [ 405 | "a duck goes into a bar\n", 406 | "A duck goes into a bar...\n", 407 | "A Duck Goes Into A Bar...\n", 408 | "A DUCK GOES INTO A BAR...\n", 409 | "a duck goes into a bar...\n", 410 | "A DUCK GOES INTO A BAR...\n", 411 | " a duck goes into a bar... \n", 412 | "a duck goes into a bar... \n", 413 | " a duck goes into a bar...\n", 414 | "a marmoset goes into a bar...\n", 415 | "a famous duck goes into a famous bar...\n" 416 | ] 417 | } 418 | ], 419 | "source": [ 420 | "#其餘還有一些方便的string內建function可以使用\n", 421 | "\n", 422 | "setup = 'a duck goes into a bar...'\n", 423 | "print(setup.strip('.')) #刪除結尾特定符號 'a duck goes into a bar'\n", 424 | "print(setup.capitalize()) #字串第一個字元大寫 'A duck goes into a bar...'\n", 425 | "print(setup.title()) #每個單字開頭大寫 'A Duck Goes Into A Bar...'\n", 426 | "print(setup.upper()) #全部大寫 'A DUCK GOES INTO A BAR...'\n", 427 | "print(setup.lower()) #全部小寫 'a duck goes into a bar...'\n", 428 | "print(setup.swapcase()) #大小寫交換 'a DUCK GOES INTO A BAR...'\n", 429 | "print(setup.center(30)) #將字串中心移動至30個字元的中間 ' a duck goes into a bar... '\n", 430 | "print(setup.ljust(30)) #左對齊 'a duck goes into a bar... '\n", 431 | "print(setup.rjust(30)) #右對齊 ' a duck goes into a bar...'\n", 432 | "print(setup.replace('duck', 'marmoset')) #'a marmoset goes into a bar...'\n", 433 | "print(setup.replace('a ', 'a famous ', 100)) #只替換前100個'a '" 434 | ] 435 | } 436 | ], 437 | "metadata": { 438 | "anaconda-cloud": {}, 439 | "kernelspec": { 440 | "display_name": "Python [Root]", 441 | "language": "python", 442 | "name": "Python [Root]" 443 | }, 444 | "language_info": { 445 | "codemirror_mode": { 446 | "name": "ipython", 447 | "version": 3 448 | }, 449 | "file_extension": ".py", 450 | "mimetype": "text/x-python", 451 | "name": "python", 452 | "nbconvert_exporter": "python", 453 | "pygments_lexer": "ipython3", 454 | "version": "3.5.2" 455 | } 456 | }, 457 | "nbformat": 4, 458 | "nbformat_minor": 0 459 | } 460 | -------------------------------------------------------------------------------- /.ipynb_checkpoints/CHAPTER 3 Py Filling Lists, Tuples, Dictionaries and Sets-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "\n", 8 | "# CHAPTER 3 Py Filling: Lists, Tuples, Dictionaries, and Sets\n", 9 | "## Python容器:串列、Tuples、字典與集合\n", 10 | "\n", 11 | "* [3.1 串列(list)與Tuples](#Lists_Tuples)\n", 12 | "* [3.2 串列(list)型態](#Lists)\n", 13 | "* [3.3 Tuples型態](#Tuples)\n", 14 | "* [3.4 字典(Dictionarie)型態](#Dictionaries)\n", 15 | "* [3.5 集合(set)型態](#Sets)\n", 16 | "* [3.6 比較型態差別](#CompareDataStructures)\n", 17 | "* [3.7 建立大型結構](#MakeBiggerDataStructures)" 18 | ] 19 | }, 20 | { 21 | "cell_type": "markdown", 22 | "metadata": {}, 23 | "source": [ 24 | "------\n", 25 | "\n", 26 | "## 3.1 串列(list)與Tuples\n", 27 | "[回目錄](#HOME)\n", 28 | "\n", 29 | "兩者差異在於,List可以改變其內容,增減長度 or 替換等等皆可以 \n", 30 | "Tuples一旦賦予值之後,就不能再修改。 \n", 31 | "以效能和記憶體使用量來說,Tuples皆較佳" 32 | ] 33 | }, 34 | { 35 | "cell_type": "markdown", 36 | "metadata": {}, 37 | "source": [ 38 | "------\n", 39 | "\n", 40 | "## 3.2 串列(list)型態\n", 41 | "[回目錄](#HOME)\n", 42 | "\n", 43 | "List可以使用 **[]** 或是 **list()** 來創建空的,或是直接加入值進去,使用逗號區分即可。內容可以重複出現,且具有順序性。" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 1, 49 | "metadata": { 50 | "collapsed": false 51 | }, 52 | "outputs": [ 53 | { 54 | "name": "stdout", 55 | "output_type": "stream", 56 | "text": [ 57 | "[]\n", 58 | "['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']\n", 59 | "['emu', 'ostrich', 'cassowary']\n", 60 | "['Graham', 'John', 'Terry', 'Terry', 'Michael']\n" 61 | ] 62 | } 63 | ], 64 | "source": [ 65 | "empty_list = []\n", 66 | "weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']\n", 67 | "big_birds = ['emu', 'ostrich', 'cassowary']\n", 68 | "first_names = ['Graham', 'John', 'Terry', 'Terry', 'Michael']\n", 69 | "\n", 70 | "print(empty_list)\n", 71 | "print(weekdays)\n", 72 | "print(big_birds)\n", 73 | "print(first_names)" 74 | ] 75 | }, 76 | { 77 | "cell_type": "markdown", 78 | "metadata": {}, 79 | "source": [ 80 | "可以使用 **list()** 來作為轉換其他型別至List,或是前面2.3小節提到的字串__split()__函數" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": 2, 86 | "metadata": { 87 | "collapsed": false 88 | }, 89 | "outputs": [ 90 | { 91 | "name": "stdout", 92 | "output_type": "stream", 93 | "text": [ 94 | "['c', 'a', 't']\n", 95 | "['ready', 'fire', 'aim']\n", 96 | "['1', '6', '1952']\n" 97 | ] 98 | } 99 | ], 100 | "source": [ 101 | "print(list('cat'))\n", 102 | "\n", 103 | "a_tuple = ('ready', 'fire', 'aim')\n", 104 | "print(list(a_tuple))\n", 105 | "\n", 106 | "birthday = '1/6/1952'\n", 107 | "print((birthday.split('/')))" 108 | ] 109 | }, 110 | { 111 | "cell_type": "markdown", 112 | "metadata": {}, 113 | "source": [ 114 | "提取內容時跟字串一樣使用[], \n", 115 | "**index** 從0開始,-1為最後一個, \n", 116 | "**index** 數值的範圍請務必在總長度內,不然會出現IndexError。也可以將其修改替換內容。 \n", 117 | "提取多個以上也如同字串中的用法 __[start : end : step]__,注意這邊只會提取到index為end - 1" 118 | ] 119 | }, 120 | { 121 | "cell_type": "code", 122 | "execution_count": 3, 123 | "metadata": { 124 | "collapsed": false 125 | }, 126 | "outputs": [ 127 | { 128 | "name": "stdout", 129 | "output_type": "stream", 130 | "text": [ 131 | "a\n", 132 | "b\n", 133 | "d\n", 134 | "c\n", 135 | "['QQ', 'b']\n", 136 | "[]\n", 137 | "['QQ', 'c']\n" 138 | ] 139 | } 140 | ], 141 | "source": [ 142 | "XD = ['a', 'b', 'c', 'd']\n", 143 | "print(XD[0])\n", 144 | "print(XD[1])\n", 145 | "print(XD[-1])\n", 146 | "print(XD[-2])\n", 147 | "\n", 148 | "XD[0] = 'QQ'\n", 149 | "\n", 150 | "print(XD[0:2])\n", 151 | "print(XD[2:-2])\n", 152 | "print(XD[::2])" 153 | ] 154 | }, 155 | { 156 | "cell_type": "markdown", 157 | "metadata": {}, 158 | "source": [ 159 | "List裡面可以包含不同類型的物件,當然也包括List" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": 4, 165 | "metadata": { 166 | "collapsed": false 167 | }, 168 | "outputs": [ 169 | { 170 | "name": "stdout", 171 | "output_type": "stream", 172 | "text": [ 173 | "['a', 'b', 'c']\n", 174 | "b\n" 175 | ] 176 | } 177 | ], 178 | "source": [ 179 | "XD = [['a', 'b', 'c'],['d', 'e', 'f'],['g', 'h', 'i']]\n", 180 | "print(XD[0])\n", 181 | "print(XD[0][1])" 182 | ] 183 | }, 184 | { 185 | "cell_type": "markdown", 186 | "metadata": {}, 187 | "source": [ 188 | "可以使用List的內建函數append()來向後面添加元素\n", 189 | "\n", 190 | "|語法|效果|\n", 191 | "|--|--|\n", 192 | "|**list.extend()**或 **+=** |合併list|\n", 193 | "|**list.insert()**|在指定位置插入元素,如果位置超過最大長度則放在最後面,故不會飛到很遠去或出錯。|\n", 194 | "|**del Object** |用來刪除某個位置的元素,剩餘元素會自動往前補填補|\n", 195 | "|**list.remove()**|用來移除指定元素|\n", 196 | "|**list.pop()**|為類似剪出的效果,可以將指定位置的元素剪出來,預設index為 -1|\n", 197 | "|**list.index()**|找查指定元素第一次出現的index|\n", 198 | "|**in Object** |判斷指定元素是否存在|\n", 199 | "|**list.count()**|計算指定元素出現次數|\n" 200 | ] 201 | }, 202 | { 203 | "cell_type": "code", 204 | "execution_count": 5, 205 | "metadata": { 206 | "collapsed": false 207 | }, 208 | "outputs": [ 209 | { 210 | "name": "stdout", 211 | "output_type": "stream", 212 | "text": [ 213 | "['a', 'b'] ['e', 'f']\n", 214 | "['a', 'b', 'QQ~']\n", 215 | "['a', 'b', 'QQ~', 'e', 'f']\n", 216 | "['a', 'b', 'QQ~', 'e', 'f', 'e', 'f']\n", 217 | "['a', 'b', 'QQ~', 'e', 'f', 'e', 'f', ['e', 'f']]\n", 218 | "['a', 'b', 'c', 'QQ~', 'e', 'f', 'e', 'f', ['e', 'f']]\n", 219 | "['a', 'b', 'c', 'QQ~', 'e', 'f', 'e', 'f', ['e', 'f'], 'ker']\n", 220 | "['a', 'b', 'c', 'QQ~', 'e', 'f', 'e', 'f', 'ker']\n", 221 | "['a', 'b', 'c', 'QQ~', 'f', 'e', 'f', 'ker']\n", 222 | "['a', 'b', 'c', 'f', 'e', 'f', 'ker'] QQ~\n", 223 | "3\n", 224 | "True\n", 225 | "2\n" 226 | ] 227 | } 228 | ], 229 | "source": [ 230 | "XD = ['a', 'b']\n", 231 | "XD2 = ['e', 'f']\n", 232 | "print(XD, XD2)\n", 233 | "\n", 234 | "XD.append('QQ~')\n", 235 | "print(XD)\n", 236 | "\n", 237 | "XD.extend(XD2)\n", 238 | "print(XD)\n", 239 | "\n", 240 | "XD += XD2\n", 241 | "print(XD)\n", 242 | "\n", 243 | "XD.append(XD2)\n", 244 | "print(XD)\n", 245 | "\n", 246 | "XD.insert(2, 'c')\n", 247 | "print(XD)\n", 248 | "\n", 249 | "XD.insert(500, 'ker')\n", 250 | "print(XD)\n", 251 | "\n", 252 | "del XD[8]\n", 253 | "print(XD)\n", 254 | "\n", 255 | "XD.remove('e')\n", 256 | "print(XD)\n", 257 | "\n", 258 | "QQ = XD.pop(3)\n", 259 | "print(XD, QQ)\n", 260 | "\n", 261 | "print(XD.index('f'))\n", 262 | "print('ker' in XD)\n", 263 | "print(XD.count('f'))" 264 | ] 265 | }, 266 | { 267 | "cell_type": "markdown", 268 | "metadata": {}, 269 | "source": [ 270 | "前面2.3節提到的__string.join()__,可以用來組裝List成為字串, \n", 271 | "書中提到這邊的用法看起來有點彆扭,如果改成__List.join(', ')__會更直覺, \n", 272 | "但是當初設計的理念就是join的方法是在字串的型態中, \n", 273 | "這樣後面我想要針對List、Tuples或是字串使用字串做組裝,就只要一種方法就好, \n", 274 | "不用針對每種型態都去設計一個相同的方法來做使用,如下面範例所示範。 \n", 275 | "__string.join()__ 與 __string.split()__兩個為相對應的用法!!!" 276 | ] 277 | }, 278 | { 279 | "cell_type": "code", 280 | "execution_count": 6, 281 | "metadata": { 282 | "collapsed": false 283 | }, 284 | "outputs": [ 285 | { 286 | "name": "stdout", 287 | "output_type": "stream", 288 | "text": [ 289 | "a, b, c\n", 290 | "a, b, c\n", 291 | "a, b, c\n", 292 | "['a', 'b', 'c']\n" 293 | ] 294 | } 295 | ], 296 | "source": [ 297 | "print(', '.join(['a', 'b', 'c']))\n", 298 | "print(', '.join('abc'))\n", 299 | "print(', '.join(('a', 'b', 'c')))\n", 300 | "print('a, b, c'.split(', '))" 301 | ] 302 | }, 303 | { 304 | "cell_type": "markdown", 305 | "metadata": {}, 306 | "source": [ 307 | "* **list.sort()**為list排序方法,\n", 308 | "* **sorted()**為通用的排序函數\n", 309 | "其中的差異在於__sort()__會直接改變輸入的list,__sorted()__則會另外回傳一個排序好的物件,\n", 310 | "\n", 311 | "**len()**可以獲得list的長度。" 312 | ] 313 | }, 314 | { 315 | "cell_type": "code", 316 | "execution_count": 7, 317 | "metadata": { 318 | "collapsed": false 319 | }, 320 | "outputs": [ 321 | { 322 | "name": "stdout", 323 | "output_type": "stream", 324 | "text": [ 325 | "['a', 'b', 'c']\n", 326 | "['a', 'b', 'c']\n", 327 | "3\n" 328 | ] 329 | } 330 | ], 331 | "source": [ 332 | "L = ['b', 'c', 'a']\n", 333 | "L.sort()\n", 334 | "print(L)\n", 335 | "\n", 336 | "t = ['b', 'c', 'a']\n", 337 | "a = sorted(t)\n", 338 | "print(a)\n", 339 | "\n", 340 | "print(len(a))" 341 | ] 342 | }, 343 | { 344 | "cell_type": "markdown", 345 | "metadata": {}, 346 | "source": [ 347 | "使用 '=' 設定變數則會是傳址,等同於前面說的標籤概念,把兩張標籤貼在同一個物件上(number or srting 除外) \n", 348 | "這樣當我改變了物件後,則物件上所有的標籤所指到的值都會跟著改變, \n", 349 | "若要改成傳值的話可以使用**copy()** 、 **list.list()** 與 **list[:]** 來達到目的" 350 | ] 351 | }, 352 | { 353 | "cell_type": "code", 354 | "execution_count": 8, 355 | "metadata": { 356 | "collapsed": false 357 | }, 358 | "outputs": [ 359 | { 360 | "name": "stdout", 361 | "output_type": "stream", 362 | "text": [ 363 | "[4, 2, 3] [4, 2, 3]\n", 364 | "['surprises', 2, 3] ['surprises', 2, 3] [4, 2, 3] [4, 2, 3] [4, 2, 3]\n" 365 | ] 366 | } 367 | ], 368 | "source": [ 369 | "a = [1, 2, 3]\n", 370 | "b = a\n", 371 | "\n", 372 | "a[0] = 4\n", 373 | "print(a, b)\n", 374 | "\n", 375 | "c = a.copy()\n", 376 | "d = list(a)\n", 377 | "e = a[:]\n", 378 | "a[0] = 'surprises'\n", 379 | "print(a, b, c, d, e)" 380 | ] 381 | }, 382 | { 383 | "cell_type": "markdown", 384 | "metadata": {}, 385 | "source": [ 386 | "------\n", 387 | "\n", 388 | "## 3.3 Tuples型態\n", 389 | "[回目錄](#HOME)\n", 390 | "\n", 391 | "也是一個List差別只在不能做修改,一旦给定後,無法再進行增加 刪除 修改等操作,所以可以當作一個常數的List\n", 392 | "\n", 393 | "創建時空的時使用(),一個以上時可以省略,但是一個時最後一個逗號不可以省略。" 394 | ] 395 | }, 396 | { 397 | "cell_type": "code", 398 | "execution_count": 9, 399 | "metadata": { 400 | "collapsed": false 401 | }, 402 | "outputs": [ 403 | { 404 | "name": "stdout", 405 | "output_type": "stream", 406 | "text": [ 407 | "()\n", 408 | "('tem',)\n", 409 | "('tem1', 'tem2', 'tem3')\n", 410 | "tem1 tem2 tem3\n" 411 | ] 412 | } 413 | ], 414 | "source": [ 415 | "a = () #空Tuples\n", 416 | "b = 'tem', #b:(tem,) 括弧可以省略,但是一個的時候逗號不能省略\n", 417 | "c = 'tem1', 'tem2', 'tem3' #('tem1', 'tem2', 'tem3')\n", 418 | "d, e, f = c #d:'tem1', e:'tem2', f:'tem3'\n", 419 | "\n", 420 | "print(a)\n", 421 | "print(b)\n", 422 | "print(c)\n", 423 | "print(d, e, f)" 424 | ] 425 | }, 426 | { 427 | "cell_type": "markdown", 428 | "metadata": {}, 429 | "source": [ 430 | "結合以上的用法可以有一個超級方便直覺的用法,任意交換變數間的值。 \n", 431 | "(在等號右邊的東西會先形成一個Tuples,再分配給前面的變數。)" 432 | ] 433 | }, 434 | { 435 | "cell_type": "code", 436 | "execution_count": 10, 437 | "metadata": { 438 | "collapsed": false 439 | }, 440 | "outputs": [ 441 | { 442 | "name": "stdout", 443 | "output_type": "stream", 444 | "text": [ 445 | "3 1 2\n" 446 | ] 447 | } 448 | ], 449 | "source": [ 450 | "a = '1'\n", 451 | "b = '2'\n", 452 | "c = '3'\n", 453 | "b, c, a = a, b, c\n", 454 | "\n", 455 | "print(a, b, c)" 456 | ] 457 | }, 458 | { 459 | "cell_type": "markdown", 460 | "metadata": {}, 461 | "source": [ 462 | "既然他不能修改等等的那相對於List一定也有其他好處\n", 463 | "\n", 464 | "* 空間較小\n", 465 | "* 不會不小心修改到值\n", 466 | "* 可以當作dictionary的key值 (後一小節有說明)\n", 467 | "* 命名Tuples,可以做為物件的替代 (第六章會說明)\n", 468 | "* 函數的傳遞是以Tuples形式傳遞\n" 469 | ] 470 | }, 471 | { 472 | "cell_type": "markdown", 473 | "metadata": {}, 474 | "source": [ 475 | "------\n", 476 | "\n", 477 | "## 3.4 字典型態\n", 478 | "[回目錄](#HOME)\n", 479 | "\n", 480 | "為一種沒有順序的容器,其使用的是大括弧{},裏頭包含鍵值與值(**key : value**) \n", 481 | "可以使用**dict()**來轉換期他型態至dictionary\n", 482 | "\n", 483 | "|語法|效果|\n", 484 | "|--|--|\n", 485 | "|**D.update()** | 合併不同dictionary|\n", 486 | "|**del Object** | 刪除某項|\n", 487 | "|**in Object** | 是否存在裡面(key)|\n", 488 | "|**D.keys() ** | 獲得所有key值|\n", 489 | "|**D.values()** | 獲得所有value值|\n", 490 | "|**D.items() ** | 獲得全部的key: value( Tuples型態 )|\n", 491 | "|**D.copy() ** | 複製一個dictionary|\n", 492 | "|**D.clear() ** | 清除所有內容|" 493 | ] 494 | }, 495 | { 496 | "cell_type": "code", 497 | "execution_count": 11, 498 | "metadata": { 499 | "collapsed": false 500 | }, 501 | "outputs": [ 502 | { 503 | "name": "stdout", 504 | "output_type": "stream", 505 | "text": [ 506 | "{'a': 'v', 'b': 'w'} {'d': 'y', 'c': 'x'}\n", 507 | "{'e': 'f', 'a': 'b', 'c': 'd'} {'e': 'f', 'a': 'b', 'c': 'd'} {'e': 'f', 'a': 'b', 'c': 'd'}\n", 508 | "{'e': 'f', 'a': 'b', 'c': 'd'} {'e': 'f', 'a': 'b', 'c': 'd'}\n", 509 | "============分隔線============\n", 510 | "x\n", 511 | "z\n", 512 | "{'d': 'y', 'a': 'v', 'c': 'z', 'b': 'w'}\n", 513 | "{'a': 'v', 'c': 'z', 'b': 'w'}\n", 514 | "True\n", 515 | "============分隔線============\n", 516 | "dict_keys(['a', 'c', 'b'])\n", 517 | "dict_values(['v', 'z', 'w'])\n", 518 | "[('a', 'v'), ('c', 'z'), ('b', 'w')]\n", 519 | "============分隔線============\n", 520 | "{'a': 'n', 'c': 'z', 'b': 'w'} {'a': 'n', 'c': 'z', 'b': 'w'}\n", 521 | "{'a': 'n', 'c': 'z', 'b': 'w'} {'a': 'm', 'c': 'z', 'b': 'w'}\n", 522 | "{}\n" 523 | ] 524 | } 525 | ], 526 | "source": [ 527 | "dic = { 'a':'v','b':'w', } #最後一個逗號可以省略\n", 528 | "dic_ = { 'd':'y','c':'x' } #最後一個逗號可以省略\n", 529 | "print(dic, dic_)\n", 530 | "\n", 531 | "\n", 532 | "lol1 = [ ['a', 'b'], ['c', 'd'], ['e', 'f'] ]\n", 533 | "lol2 = [ ('a', 'b'), ('c', 'd'), ('e', 'f') ]\n", 534 | "lol3 = ( ['a', 'b'], ['c', 'd'], ['e', 'f'] )\n", 535 | "print(dict(lol1), dict(lol2), dict(lol3))\n", 536 | "\n", 537 | "\n", 538 | "tos1 = [ 'ab', 'cd', 'ef' ]\n", 539 | "tos2 = ( 'ab', 'cd', 'ef' )\n", 540 | "print(dict(tos1), dict(tos2))\n", 541 | "\n", 542 | "print('============分隔線============')\n", 543 | "print(dic_['c'])\n", 544 | "dic_['c'] = 'z'\n", 545 | "print(dic_['c'])\n", 546 | "\n", 547 | "dic.update(dic_)\n", 548 | "print(dic)\n", 549 | "\n", 550 | "\n", 551 | "del dic['d']\n", 552 | "print(dic)\n", 553 | "\n", 554 | "print('a' in dic)\n", 555 | "\n", 556 | "print('============分隔線============')\n", 557 | "print(dic.keys()) # dict_keys(['a', 'b', 'c'])\n", 558 | "print(dic.values()) # ['v', 'w', 'x']\n", 559 | "print(list(dic.items())) # [('a', 'v'), ('b', 'w'), ('c', 'x')]\n", 560 | "\n", 561 | "print('============分隔線============')\n", 562 | "dic_new = dic\n", 563 | "dic_new['a'] = 'n'\n", 564 | "print(dic, dic_new)\n", 565 | "\n", 566 | "dic_cp = dic.copy()\n", 567 | "dic_cp['a'] = 'm'\n", 568 | "print(dic, dic_cp)\n", 569 | "\n", 570 | "dic.clear() \n", 571 | "print(dic)" 572 | ] 573 | }, 574 | { 575 | "cell_type": "markdown", 576 | "metadata": {}, 577 | "source": [ 578 | "------\n", 579 | "\n", 580 | "## 3.5 集合型態\n", 581 | "[回目錄](#HOME)\n", 582 | "\n", 583 | "集合就好比沒有value的dictionary,一樣沒有順序,使用大括弧**{}**。 \n", 584 | "空白集合為**set()**,也合相當於False。 \n", 585 | "使用**set()**可以轉換其他型態至集合,dictionary轉換至set只會保留key值。 \n", 586 | "**in**也可以檢查特定元素是否存在其中。\n", 587 | "\n", 588 | "![Alt text](http://i.imgur.com/gXChbwA.png \"集合示意圖\")" 589 | ] 590 | }, 591 | { 592 | "cell_type": "code", 593 | "execution_count": 12, 594 | "metadata": { 595 | "collapsed": false 596 | }, 597 | "outputs": [ 598 | { 599 | "name": "stdout", 600 | "output_type": "stream", 601 | "text": [ 602 | "set() {8, 0, 2, 4, 6}\n", 603 | "{'r', 'e', 'l', 't', 's'}\n", 604 | "{'D', 'M', 'P', 'A'}\n", 605 | "{'U', 'Echoes', 'Atom'}\n", 606 | "{'orange', 'apple'}\n" 607 | ] 608 | } 609 | ], 610 | "source": [ 611 | "empty_set = set()\n", 612 | "even_numbers = {0, 2, 4, 6, 8}\n", 613 | "print(empty_set, even_numbers)\n", 614 | "\n", 615 | "\n", 616 | "print(set( 'letters' ))\n", 617 | "print(set( ['D', 'A', 'P', 'M'] ))\n", 618 | "print(set( ('U', 'Echoes', 'Atom') ))\n", 619 | "print(set( {'apple': 'red', 'orange': 'orange'} ))" 620 | ] 621 | }, 622 | { 623 | "cell_type": "markdown", 624 | "metadata": {}, 625 | "source": [ 626 | "------\n", 627 | "\n", 628 | "## 3.6 比較型態差別\n", 629 | "[回目錄](#HOME)\n", 630 | "\n", 631 | "比較不同容器之間的使用差別,請自己在看過一次書中介紹。" 632 | ] 633 | }, 634 | { 635 | "cell_type": "markdown", 636 | "metadata": {}, 637 | "source": [ 638 | "------\n", 639 | "\n", 640 | "## 3.7 建立大型結構\n", 641 | "[回目錄](#HOME)\n", 642 | "\n", 643 | "容器中可以包含不同型態的元素,也可以包含其他的容器物件。" 644 | ] 645 | }, 646 | { 647 | "cell_type": "code", 648 | "execution_count": 13, 649 | "metadata": { 650 | "collapsed": false 651 | }, 652 | "outputs": [ 653 | { 654 | "name": "stdout", 655 | "output_type": "stream", 656 | "text": [ 657 | "{'Pythons': ['Chapman', 'Cleese', 'Gilliam', 'Jones', 'Palin'], 'Marxes': ['Groucho', 'Chico', 'Harpo'], 'Stooges': ['Moe', 'Curly', 'Larry']}\n", 658 | "['Groucho', 'Chico', 'Harpo']\n", 659 | "Chico\n" 660 | ] 661 | } 662 | ], 663 | "source": [ 664 | "dict_of_lists = {'Stooges': ['Moe', 'Curly', 'Larry'],\n", 665 | " 'Marxes': ['Groucho', 'Chico', 'Harpo'],\n", 666 | " 'Pythons': ['Chapman', 'Cleese', 'Gilliam', 'Jones', 'Palin']}\n", 667 | "\n", 668 | "print(dict_of_lists)\n", 669 | "print(dict_of_lists['Marxes'])\n", 670 | "print(dict_of_lists['Marxes'][1])" 671 | ] 672 | } 673 | ], 674 | "metadata": { 675 | "kernelspec": { 676 | "display_name": "Python [Root]", 677 | "language": "python", 678 | "name": "Python [Root]" 679 | }, 680 | "language_info": { 681 | "codemirror_mode": { 682 | "name": "ipython", 683 | "version": 3 684 | }, 685 | "file_extension": ".py", 686 | "mimetype": "text/x-python", 687 | "name": "python", 688 | "nbconvert_exporter": "python", 689 | "pygments_lexer": "ipython3", 690 | "version": "3.5.2" 691 | } 692 | }, 693 | "nbformat": 4, 694 | "nbformat_minor": 0 695 | } 696 | -------------------------------------------------------------------------------- /.ipynb_checkpoints/CHAPTER 5 Py Boxes- Modules, Packages, and Programs-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": false 7 | }, 8 | "source": [ 9 | "\n", 10 | "# CHAPTER 5 Py Boxes: Modules, Packages, and Programs\n", 11 | "## Python模組、包和程序\n", 12 | "\n", 13 | "* [5.1 獨立程式 Standalone Programs](#Standalone)\n", 14 | "* [5.2 命令列參數 Command-Line Arguments](#Command-Line)\n", 15 | "* [5.3 模組與匯入 Modules and the import Statement](#Modules_import)\n", 16 | "* [5.4 打包 Packages](#Packages)\n", 17 | "* [5.5 標準函數庫 The Python Standard Library](#Standard_Library)\n", 18 | "* [5.6 獲取其他程式 More Batteries: Get Other Python Code](#Get_Other)\n", 19 | "\n", 20 | "\n", 21 | "程式若要寫得漂亮,乾淨,清楚,則模組化是很重要的一個技術基礎\n", 22 | "方可把大型的程式拆解能若干小程式,方便管理,維護,重複使用" 23 | ] 24 | }, 25 | { 26 | "cell_type": "markdown", 27 | "metadata": {}, 28 | "source": [ 29 | "---\n", 30 | "\n", 31 | "## 5.1 Standalone Programs 獨立程式\n", 32 | "[回目錄](#HOME)\n", 33 | "\n", 34 | "可以把編寫完的py檔於命令提示字元執行\n", 35 | "\n", 36 | "```\n", 37 | ">>> python test1.py\n", 38 | "```" 39 | ] 40 | }, 41 | { 42 | "cell_type": "markdown", 43 | "metadata": {}, 44 | "source": [ 45 | "---\n", 46 | "\n", 47 | "## 5.2 Command-Line Arguments 命令列參數\n", 48 | "[回目錄](#HOME)\n", 49 | "\n", 50 | "\n", 51 | "sys為命令列函數,import後即可在命令列直接輸入參數。\n", 52 | "\n", 53 | "```python\n", 54 | "import sys\n", 55 | "print('Program arguments:',sys.argv[1])\n", 56 | "```\n", 57 | "test2.py tra la \n", 58 | "```\n", 59 | ">>> python test2.py\n", 60 | "Program arguments: ['test2.py']\n", 61 | ">>> python la\n", 62 | "Program arguments: ['test2.py', 'tra', 'la', 'la']\n", 63 | "```" 64 | ] 65 | }, 66 | { 67 | "cell_type": "markdown", 68 | "metadata": {}, 69 | "source": [ 70 | "---\n", 71 | "\n", 72 | "## 5.3 Modules and the import Statement 模組與匯入\n", 73 | "[回目錄](#HOME)\n", 74 | "\n", 75 | "將程式拆成若干模組(Modules)後,即可使用import匯入,並且可以用as重新取自己想要的名稱\n", 76 | "\n", 77 | "程式預設會先搜尋主程式相同路徑的資料夾,若無則搜尋安裝目錄的\\Lib資料夾\n", 78 | "\n", 79 | "### import 函式庫( as 別名)\n", 80 | "為匯入全部的function\n", 81 | "\n", 82 | "### from 函式庫 import function( as 別名)\n", 83 | "為匯入函式庫中的某隻特定function" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": null, 89 | "metadata": { 90 | "collapsed": false 91 | }, 92 | "outputs": [], 93 | "source": [ 94 | "# weatherman.py\n", 95 | "# 主程式\n", 96 | "# P.S.這裡抓不到,因為沒有準備實體函式在資料中\n", 97 | "\n", 98 | "import report #把 report.py 在相同目錄資料夾中,即可對其呼叫匯入\n", 99 | "description = report.get_description() #使用report中的get_description函數\n", 100 | "\n", 101 | "from get_description import report as get\n", 102 | "\n", 103 | "print(\"Today's weather:\", description)" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": null, 109 | "metadata": { 110 | "collapsed": true 111 | }, 112 | "outputs": [], 113 | "source": [ 114 | "# report.py\n", 115 | "# 函式庫\n", 116 | "\n", 117 | "def get_description():\n", 118 | " \"\"\"Return random weather, just like the pros\"\"\"\n", 119 | " from random import choice #匯入標準函式庫 random 中的 choice函數\n", 120 | " possibilities = ['rain', 'snow', 'sleet', 'fog', 'sun', 'who knows']\n", 121 | " return choice(possibilities)" 122 | ] 123 | }, 124 | { 125 | "cell_type": "markdown", 126 | "metadata": {}, 127 | "source": [ 128 | "---\n", 129 | "\n", 130 | "## 5.4 Packages 打包\n", 131 | "[回目錄](#HOME)\n", 132 | "\n", 133 | "__非常非常非常好用的功能!!!!__\n", 134 | "\n", 135 | "前述用法是把function拆開再同一層目錄,但是如果函式庫相當的多,在管理上會變得複雜 \n", 136 | "所以可以將函式庫利用資料夾作為管理,簡易示意圖如下\n", 137 | "\n", 138 | "![Alt text](http://i.imgur.com/pCwG1Ze.png)\n", 139 | "\n", 140 | "主程式為 __weather.py__ \n", 141 | "modules為__daily.py__ 與 __weekly.py__ \n", 142 | "__init.py__檔則為一個空的檔案,目的為使python將sources視為一個函式庫用\n", 143 | "\n", 144 | "\n", 145 | "主程式[__weather.py__]即可使用import匯入sources資料夾中的函示\n", 146 | "```python\n", 147 | "#----------------------------------------------------weather.py\n", 148 | "from sources import daily, weekly\n", 149 | "\n", 150 | "print(\"Daily forecast:\", daily.forecast())\n", 151 | "print(\"Weekly forecast:\")\n", 152 | "for number, outlook in enumerate(weekly.forecast(), 1):\n", 153 | " print(number, outlook)\n", 154 | "\n", 155 | "#----------------------------------------------------daily.py:\n", 156 | "def forecast():\n", 157 | " 'fake daily forecast'\n", 158 | " return 'like yesterday'\n", 159 | "\n", 160 | "#----------------------------------------------------weekly.py\n", 161 | "def forecast():\n", 162 | " \"\"\"Fake weekly forecast\"\"\"\n", 163 | " return ['snow', 'more snow', 'sleet','freezing rain', 'rain', 'fog', 'hail']\n", 164 | "```" 165 | ] 166 | }, 167 | { 168 | "cell_type": "markdown", 169 | "metadata": {}, 170 | "source": [ 171 | "---\n", 172 | "\n", 173 | "## 5.5 The Python Standard Library 標準函數庫\n", 174 | "[回目錄](#HOME)\n", 175 | "\n", 176 | "介紹一些Python內建的標準函式庫, \n", 177 | "PYTHON把一些較不常用的function拆解為標準函式庫,使得python更輕巧\n", 178 | "\n", 179 | "詳細介紹請看書本,這邊不多說" 180 | ] 181 | }, 182 | { 183 | "cell_type": "markdown", 184 | "metadata": {}, 185 | "source": [ 186 | "---\n", 187 | "\n", 188 | "## 5.6 More Batteries: Get Other Python Code 獲取其他程式\n", 189 | "[回目錄](#HOME)\n", 190 | "\n", 191 | "如果表準函式庫中沒有想到的,可以上到其他網站去尋找,書中介紹了這三個網站\n", 192 | "\n", 193 | "* PyPi( http://pypi.python.org )\n", 194 | "* github( http://github.com/Python )\n", 195 | "* readthedocs( https://readthedocs.org/ )\n", 196 | "* Python Extension Packages,windows環境超級大補帖 ( http://www.lfd.uci.edu/~gohlke/pythonlibs/ )\n" 197 | ] 198 | } 199 | ], 200 | "metadata": { 201 | "anaconda-cloud": {}, 202 | "kernelspec": { 203 | "display_name": "Python [Root]", 204 | "language": "python", 205 | "name": "Python [Root]" 206 | }, 207 | "language_info": { 208 | "codemirror_mode": { 209 | "name": "ipython", 210 | "version": 3 211 | }, 212 | "file_extension": ".py", 213 | "mimetype": "text/x-python", 214 | "name": "python", 215 | "nbconvert_exporter": "python", 216 | "pygments_lexer": "ipython3", 217 | "version": "3.5.2" 218 | } 219 | }, 220 | "nbformat": 4, 221 | "nbformat_minor": 0 222 | } 223 | -------------------------------------------------------------------------------- /.ipynb_checkpoints/CHAPTER 6 Oh Oh- Objects and Classes-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": false 7 | }, 8 | "source": [ 9 | "\n", 10 | "# CHAPTER 6 Oh Oh: Objects and Classes\n", 11 | "## 物件與類別\n", 12 | "\n", 13 | "* [6.1 什麼是物件](#Objects)\n", 14 | "* [6.2 使用class定義類別](#Class)\n", 15 | "* [6.3 繼承](#Inheritance)\n", 16 | "* [6.4 覆蓋方法](#Override)\n", 17 | "* [6.5 添加新方法](#Add)\n", 18 | "* [6.6 使用super得到父類別支援](#super)\n", 19 | "* [6.7 self](#self)\n", 20 | "* [6.8 設置與呼叫特性的屬性](#Attribute)\n", 21 | "* [6.9 使用名稱重整保持私有性](#Privacy)\n", 22 | "* [6.10 方法的類別](#Types)\n", 23 | "* [6.11 鴨子類別](#Duck)\n", 24 | "* [6.12 特殊方法](#Special)\n", 25 | "* [6.13 組合](#Composition)\n", 26 | "* [6.14 類別與對象v.s.模組](#ClassesModules)\n", 27 | "\n", 28 | "\n", 29 | "\n", 30 | "除了python內建的對象,我們也可以通過class來建立屬於自己的類別供使用" 31 | ] 32 | }, 33 | { 34 | "cell_type": "markdown", 35 | "metadata": {}, 36 | "source": [ 37 | "---\n", 38 | "\n", 39 | "## 6.1 什麼是物件\n", 40 | "[回目錄](#HOME)\t\t\t\t\t \n", 41 | "\n", 42 | "\n", 43 | "第二章節提到,python裡面所有的東西都是物件(_objects_),連同一個整數也是一種物件,python的語法設計可以巧妙的隱藏諸多細節\n", 44 | "\n", 45 | "本章節將會介紹到自訂新的物件以及修改現有的物件。\n", 46 | "\n", 47 | "物件包含屬性(__attribute__)與方法(__methods__), \n", 48 | "例如整數5和7都是整數物件,都包含了基本的+-\\*/方法, \n", 49 | "'cat' 和 'duck'都是字串物件,都包含了 __capitalize()__ 和 __replace()__ 兩種方法\n", 50 | "\n", 51 | "所以當你要創造一個新的物件時,就必須先定義一個類別,用它來清楚規範其類別可以創造出來的物件有什麼樣的屬性(__attribute__)與方法(__methods__)\n", 52 | "\n", 53 | "物件像名詞,方法就像個動詞。對象代表一個獨立的事物,方法用來定義她如何與其他事物相互作用 \n", 54 | "與模組不同的是,你可以同時創建多個同類別的物件,他們之間的屬性值可能各有不同,對象像是個結構,包含著數據。\n" 55 | ] 56 | }, 57 | { 58 | "cell_type": "markdown", 59 | "metadata": {}, 60 | "source": [ 61 | "---\n", 62 | "\n", 63 | "## 6.2 使用class定義類別\n", 64 | "[回目錄](#HOME)\t\t\t \n", 65 | "\t \n", 66 | "我們可以通過class來定義自己的類別,就可以創造出新的物件\n" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": 1, 72 | "metadata": { 73 | "collapsed": false 74 | }, 75 | "outputs": [ 76 | { 77 | "name": "stdout", 78 | "output_type": "stream", 79 | "text": [ 80 | "Elmer Fudd\n", 81 | "QQ@WW.tw\n", 82 | "I am Elmer Fudd!!!\n", 83 | "Hsuky\n", 84 | "XDD@WW.tw\n" 85 | ] 86 | } 87 | ], 88 | "source": [ 89 | "# 自定義一個Person()\n", 90 | "# __init__為定義屬性部分\n", 91 | "# self為物件自己\n", 92 | "\n", 93 | "class Person():\n", 94 | " def __init__(self, name, email):\n", 95 | " self.name = name\n", 96 | " self.email = email\n", 97 | " \n", 98 | " def XDD(self, tem):\n", 99 | " return 'I am ' + self.name + tem\n", 100 | "\n", 101 | "hunter = Person('Elmer Fudd', \"QQ@WW.tw\")\n", 102 | "\n", 103 | "Husky = Person('Hsuky', \"XDD@WW.tw\")\n", 104 | "\n", 105 | "print(hunter.name)\n", 106 | "print(hunter.email)\n", 107 | "\n", 108 | "print(hunter.XDD('!!!'))\n", 109 | "\n", 110 | "print(Husky.name)\n", 111 | "print(Husky.email)" 112 | ] 113 | }, 114 | { 115 | "cell_type": "markdown", 116 | "metadata": {}, 117 | "source": [ 118 | "---\n", 119 | "\n", 120 | "## 6.3 繼承\n", 121 | "[回目錄](#HOME)\t\t\t\t\t\t\t \n", 122 | "\n", 123 | "在編寫類別時,如果發現已經有前人開發過,那就可以不用整段複製,可以採用繼承的方法取得他的屬性與方法 \n", 124 | "並且補充自己會用到的功能,一方面可以減少去改既有的類別辛苦,也可省去複製貼上的功" 125 | ] 126 | }, 127 | { 128 | "cell_type": "code", 129 | "execution_count": 2, 130 | "metadata": { 131 | "collapsed": false 132 | }, 133 | "outputs": [ 134 | { 135 | "name": "stdout", 136 | "output_type": "stream", 137 | "text": [ 138 | "add: 4\n", 139 | "add: 6\n" 140 | ] 141 | } 142 | ], 143 | "source": [ 144 | "class math():\n", 145 | " def add(self, a, b):\n", 146 | " print(\"add:\", a + b)\n", 147 | "\n", 148 | "class mean(math):\n", 149 | " pass\n", 150 | " \n", 151 | "ab = mean()\n", 152 | "ab.add(1, 3)\n", 153 | "\n", 154 | "ac = math()\n", 155 | "ac.add(1,5)" 156 | ] 157 | }, 158 | { 159 | "cell_type": "markdown", 160 | "metadata": {}, 161 | "source": [ 162 | "---\n", 163 | "\n", 164 | "## 6.4 覆蓋方法\n", 165 | "[回目錄](#HOME) \n", 166 | "\n", 167 | "當然我們也可以覆蓋掉原有的方法" 168 | ] 169 | }, 170 | { 171 | "cell_type": "code", 172 | "execution_count": 3, 173 | "metadata": { 174 | "collapsed": false 175 | }, 176 | "outputs": [ 177 | { 178 | "name": "stdout", 179 | "output_type": "stream", 180 | "text": [ 181 | "add: 7\n" 182 | ] 183 | } 184 | ], 185 | "source": [ 186 | "class math():\n", 187 | " def add(self, a, b):\n", 188 | " print(\"add:\", a + b)\n", 189 | "\n", 190 | "class mean(math):\n", 191 | " def add(self, a, b):\n", 192 | " print(\"add:\", a + b + b)\n", 193 | " \n", 194 | "ab = mean()\n", 195 | "ab.add(1, 3)" 196 | ] 197 | }, 198 | { 199 | "cell_type": "markdown", 200 | "metadata": {}, 201 | "source": [ 202 | "---\n", 203 | "\n", 204 | "## 6.5 添加新方法\n", 205 | "[回目錄](#HOME) \n", 206 | "\n", 207 | "前面的都是複製與修改接著我們也可以在新的類別中加入新的方法" 208 | ] 209 | }, 210 | { 211 | "cell_type": "code", 212 | "execution_count": 4, 213 | "metadata": { 214 | "collapsed": false 215 | }, 216 | "outputs": [ 217 | { 218 | "name": "stdout", 219 | "output_type": "stream", 220 | "text": [ 221 | "add: 4\n", 222 | "add: -2\n", 223 | "add: 6\n" 224 | ] 225 | } 226 | ], 227 | "source": [ 228 | "class math():\n", 229 | " def add(self, a, b):\n", 230 | " print(\"add:\", a + b)\n", 231 | "\n", 232 | "class mean(math):\n", 233 | " def less(self, a, b):\n", 234 | " print(\"add:\", a - b)\n", 235 | " \n", 236 | "ab = mean()\n", 237 | "ab.add(1, 3)\n", 238 | "ab.less(1, 3)\n", 239 | "\n", 240 | "ac = math()\n", 241 | "ac.add(1, 5)\n" 242 | ] 243 | }, 244 | { 245 | "cell_type": "markdown", 246 | "metadata": {}, 247 | "source": [ 248 | "---\n", 249 | "\n", 250 | "## 6.6 使用super得到父類別支援\n", 251 | "[回目錄](#HOME) \n", 252 | "\n", 253 | "那如果們我要修改屬性部分( *\\_\\_int\\_\\_* ),除了直接重寫一個蓋掉以外還有__super()__方法可以用來擴充既有的屬性,這樣才有達到既成的目的" 254 | ] 255 | }, 256 | { 257 | "cell_type": "code", 258 | "execution_count": 5, 259 | "metadata": { 260 | "collapsed": false 261 | }, 262 | "outputs": [ 263 | { 264 | "name": "stdout", 265 | "output_type": "stream", 266 | "text": [ 267 | "Elmer Fudd\n", 268 | "QQ@CC.tw\n", 269 | "=============\n", 270 | "Elmer Fudd\n", 271 | "QQ@CC.tw\n", 272 | "2016/05/07\n" 273 | ] 274 | } 275 | ], 276 | "source": [ 277 | "class Person():\n", 278 | " def __init__(self, name, email):\n", 279 | " self.name = name\n", 280 | " self.email = email\n", 281 | " \n", 282 | "class Person_day(Person):\n", 283 | " def __init__(self, name, email, birthday):\n", 284 | " super().__init__(name, email)\n", 285 | " self.birthday = birthday\n", 286 | " \n", 287 | " \n", 288 | "hunter = Person('Elmer Fudd', 'QQ@CC.tw')\n", 289 | "husky = Person_day('Elmer Fudd', 'QQ@CC.tw', '2016/05/07')\n", 290 | "\n", 291 | "print(hunter.name)\n", 292 | "print(hunter.email)\n", 293 | "print('=============')\n", 294 | "print(husky.name)\n", 295 | "print(husky.email)\n", 296 | "print(husky.birthday)\n" 297 | ] 298 | }, 299 | { 300 | "cell_type": "markdown", 301 | "metadata": {}, 302 | "source": [ 303 | "---\n", 304 | "\n", 305 | "## 6.7 self\n", 306 | "[回目錄](#HOME) \n", 307 | "\n", 308 | "在定義屬性時常常會看到__self__,__self__指的就是被創造出來的物件它自身。 \n", 309 | "所以在__\\_\\_int\\_\\_(self, name)__的參數部分,實際在__self__並不用傳入參數。\n", 310 | "\n", 311 | "```python\n", 312 | "class Person():\n", 313 | " def __init__(self, name, email):\n", 314 | " self.name = name\n", 315 | " self.email = email\n", 316 | "\n", 317 | "XDD = Person('QQ', 'QQ@gmail.com') #不須傳入self參數\n", 318 | "```" 319 | ] 320 | }, 321 | { 322 | "cell_type": "markdown", 323 | "metadata": {}, 324 | "source": [ 325 | "---\n", 326 | "\n", 327 | "## 6.8 設置與呼叫特性的屬性\n", 328 | "[回目錄](#HOME) \n", 329 | "\n", 330 | "在其他語言中,可以設置__getter__ 和 __setter__來確保私有屬性的讀寫,但是在python一切都是公開的, \n", 331 | "可以透過__property()__來達到python風格的寫法,即可將屬性值藏起來,不用透過呼叫每個__getter()__和__setter()__來達到改變斯有變數 \n", 332 | "\n", 333 | "若沒有給定setter函數,則無法透過__property()__來改變屬性質,當然前提是在別人不知道實在儲存變數的屬性名稱是什麼" 334 | ] 335 | }, 336 | { 337 | "cell_type": "code", 338 | "execution_count": 6, 339 | "metadata": { 340 | "collapsed": false 341 | }, 342 | "outputs": [ 343 | { 344 | "name": "stdout", 345 | "output_type": "stream", 346 | "text": [ 347 | "提取名稱時,則呼叫get函數\n", 348 | "---使用get函數---\n", 349 | "Howard!!\n", 350 | "\n", 351 | "設定名稱時,則呼叫set函數\n", 352 | "---使用set函數---\n", 353 | "nname被改成Daffy\n", 354 | "---使用get函數---\n", 355 | "Daffy??!!\n", 356 | "\n", 357 | "當然也可以透過原始的set_name()與get_name()進行修改私有屬性\n", 358 | "---使用get函數---\n", 359 | "Daffy??!!\n", 360 | "---使用set函數---\n", 361 | "---使用get函數---\n", 362 | "Daffyyyy??!!\n" 363 | ] 364 | } 365 | ], 366 | "source": [ 367 | "class Duck():\n", 368 | " def __init__(self, input_name):\n", 369 | " self.hidden_name = input_name\n", 370 | " \n", 371 | " #取的 name 的函數\n", 372 | " def get_name(self):\n", 373 | " print('---使用get函數---')\n", 374 | " return self.hidden_name + '!!'\n", 375 | " \n", 376 | " #設定 name 的函數\n", 377 | " def set_name(self, input_name):\n", 378 | " print('---使用set函數---')\n", 379 | " self.hidden_name = input_name + '??'\n", 380 | " \n", 381 | " #使用property(get,set)來包裝,讓使用上更方便\n", 382 | " name = property(get_name, set_name)\n", 383 | "\n", 384 | "#宣告物件為Duck類別,並給定name,從頭到尾都沒有直接抄作hidden_name來改變屬性值\n", 385 | "fowl = Duck('Howard')\n", 386 | "print('提取名稱時,則呼叫get函數')\n", 387 | "print(fowl.name)\n", 388 | "\n", 389 | "print('\\n設定名稱時,則呼叫set函數')\n", 390 | "fowl.name = 'Daffy'\n", 391 | "print('nname被改成Daffy')\n", 392 | "print(fowl.name)\n", 393 | "\n", 394 | "print('\\n當然也可以透過原始的set_name()與get_name()進行修改私有屬性')\n", 395 | "print(fowl.get_name())\n", 396 | "fowl.set_name('Daffyyyy')\n", 397 | "print(fowl.get_name())" 398 | ] 399 | }, 400 | { 401 | "cell_type": "code", 402 | "execution_count": 7, 403 | "metadata": { 404 | "collapsed": false 405 | }, 406 | "outputs": [ 407 | { 408 | "name": "stdout", 409 | "output_type": "stream", 410 | "text": [ 411 | "提取名稱時,則呼叫get函數\n", 412 | "---使用get函數---\n", 413 | "Howard\n", 414 | "\n", 415 | "設定名稱時,則呼叫set函數\n", 416 | "---使用set函數---\n", 417 | "nname被改成Daffy\n", 418 | "---使用get函數---\n", 419 | "Daffy\n" 420 | ] 421 | } 422 | ], 423 | "source": [ 424 | "#當然可以透過裝飾器,來寫得更漂亮!!!\n", 425 | "\n", 426 | "class Duck():\n", 427 | " def __init__(self, input_name):\n", 428 | " self.hidden_name = input_name\n", 429 | " \n", 430 | " @property\n", 431 | " def name(self):\n", 432 | " print('---使用get函數---')\n", 433 | " return self.hidden_name\n", 434 | "\n", 435 | " @name.setter\n", 436 | " def name(self, input_name):\n", 437 | " print('---使用set函數---')\n", 438 | " self.hidden_name = input_name\n", 439 | " \n", 440 | "#宣告物件為Duck類別,並給定name\n", 441 | "fowl = Duck('Howard')\n", 442 | "\n", 443 | "print('提取名稱時,則呼叫get函數')\n", 444 | "print(fowl.name)\n", 445 | "\n", 446 | "print('\\n設定名稱時,則呼叫set函數')\n", 447 | "fowl.name = 'Daffy'\n", 448 | "print('nname被改成Daffy')\n", 449 | "print(fowl.name)" 450 | ] 451 | }, 452 | { 453 | "cell_type": "markdown", 454 | "metadata": {}, 455 | "source": [ 456 | "---\n", 457 | "\n", 458 | "## 6.9 使用名稱重整保持私有性\n", 459 | "[回目錄](#HOME) \n", 460 | "\n", 461 | "前面的用法如果被知道實際儲存屬性的名稱為什麼,也是可以對其修改\n", 462 | "所以可以透過名稱重整來把實際儲存屬性的名稱改寫\n", 463 | "\n", 464 | "在屬性名稱前面加上( \\_\\_ )來重整名稱,雖然不能完全的防止修改私有屬性,但可以透過有效的方法降低有意或無意的修改" 465 | ] 466 | }, 467 | { 468 | "cell_type": "code", 469 | "execution_count": 8, 470 | "metadata": { 471 | "collapsed": false 472 | }, 473 | "outputs": [ 474 | { 475 | "name": "stdout", 476 | "output_type": "stream", 477 | "text": [ 478 | "---使用get函數---\n", 479 | "Howard\n", 480 | "---使用set函數---\n", 481 | "---使用get函數---\n", 482 | "Donald\n" 483 | ] 484 | } 485 | ], 486 | "source": [ 487 | "class Duck():\n", 488 | " def __init__(self, input_name):\n", 489 | " self.__name = input_name\n", 490 | " \n", 491 | " @property\n", 492 | " def name(self):\n", 493 | " print('---使用get函數---')\n", 494 | " return self.__name\n", 495 | " \n", 496 | " @name.setter\n", 497 | " def name(self, input_name):\n", 498 | " print('---使用set函數---')\n", 499 | " self.__name = input_name\n", 500 | "\n", 501 | " \n", 502 | " \n", 503 | "fowl = Duck('Howard')\n", 504 | "print(fowl.name)\n", 505 | "fowl.name = 'Donald'\n", 506 | "print(fowl.name)\n", 507 | "\n", 508 | "#fowl.__name #直接修改會錯誤\n", 509 | "#fowl._Duck__name #重整完的名稱" 510 | ] 511 | }, 512 | { 513 | "cell_type": "markdown", 514 | "metadata": {}, 515 | "source": [ 516 | "---\n", 517 | "\n", 518 | "## 6.10 方法的類別\n", 519 | "[回目錄](#HOME) \n", 520 | "\n", 521 | "前述交的都是物件的方法,對於類別本身也是可以設定屬性以及方法 \n", 522 | "分別使用 __類別.屬性__ 以及 __@classmethod__\n", 523 | "\n", 524 | "在類別的方法中,呼叫自己使用 __cls__ 或是 **類別名稱** 皆可以\n", 525 | "\n", 526 | "還有一種 __@staticmethod__ 可以設定類別的函數,差異在於 \n", 527 | "* @staticmethod不需使用cls參數\n", 528 | "* @classmethod第一個參數需為cls參數\n", 529 | "\n", 530 | "在使用上來說,若__@staticmethod__要調用到這個類別的屬性只能直接用名稱來取得,而__@classmethod__因為有cls參數傳入,所以可以透過cls來調用類別函數\n" 531 | ] 532 | }, 533 | { 534 | "cell_type": "code", 535 | "execution_count": 9, 536 | "metadata": { 537 | "collapsed": false 538 | }, 539 | "outputs": [ 540 | { 541 | "name": "stdout", 542 | "output_type": "stream", 543 | "text": [ 544 | "A has 3 little objects.\n", 545 | "A has 3 little objects.\n", 546 | "This CoyoteWeapon has been brought to you by Acme\n" 547 | ] 548 | } 549 | ], 550 | "source": [ 551 | "class A():\n", 552 | " count = 0 #類別的屬性\n", 553 | " def __init__(self):\n", 554 | " A.count += 1 #修改類別的屬性\n", 555 | " \n", 556 | " def exclaim(self):\n", 557 | " print(\"I'm an A!\")\n", 558 | " \n", 559 | " @classmethod #類別的方法(methond)\n", 560 | " def kids(cls):\n", 561 | " print(\"A has\", cls.count, \"little objects.\")\n", 562 | " \n", 563 | " @classmethod #類別的方法(methond)\n", 564 | " def kids2(A):\n", 565 | " print(\"A has\", A.count, \"little objects.\")\n", 566 | "\n", 567 | "easy_a = A()\n", 568 | "breezy_a = A()\n", 569 | "wheezy_a = A()\n", 570 | "A.kids()\n", 571 | "A.kids2()\n", 572 | "\n", 573 | "\n", 574 | "class CoyoteWeapon():\n", 575 | " @staticmethod\n", 576 | " def commercial():\n", 577 | " print('This CoyoteWeapon has been brought to you by Acme')\n", 578 | " \n", 579 | "CoyoteWeapon.commercial()" 580 | ] 581 | }, 582 | { 583 | "cell_type": "markdown", 584 | "metadata": {}, 585 | "source": [ 586 | "---\n", 587 | "\n", 588 | "## 6.11 鴨子類別\n", 589 | "[回目錄](#HOME) \n", 590 | "\n", 591 | "在物件導向的語言中多態(polymorphism)的使用,可以讓我們更方便的調用物件的函數\n", 592 | "\n", 593 | "不用管物件本身的類別是什麼,只要擁有相同的方法就可以呼叫到\n", 594 | "\n", 595 | "\n", 596 | "鴨子一詞的由來為,如果能像鴨子一樣叫,像鴨子一樣走路,那他就是一隻鴨子。 \n", 597 | "所以我們不用太在意是什麼物件,只要他能夠有一樣的方法可以使用,那我們就可以安心的使用了" 598 | ] 599 | }, 600 | { 601 | "cell_type": "code", 602 | "execution_count": 10, 603 | "metadata": { 604 | "collapsed": false, 605 | "scrolled": true 606 | }, 607 | "outputs": [ 608 | { 609 | "name": "stdout", 610 | "output_type": "stream", 611 | "text": [ 612 | "Elmer Fudd says I'm hunting wabbits.\n", 613 | "Brook says Babble\n" 614 | ] 615 | } 616 | ], 617 | "source": [ 618 | "class Quote():\n", 619 | " def __init__(self, person, words):\n", 620 | " self.person = person\n", 621 | " self.words = words\n", 622 | " \n", 623 | " def who(self):\n", 624 | " return self.person\n", 625 | "\n", 626 | " def says(self):\n", 627 | " return self.words + '.'\n", 628 | " \n", 629 | "class BabblingBrook():\n", 630 | " def who(self):\n", 631 | " return 'Brook'\n", 632 | " \n", 633 | " def says(self):\n", 634 | " return 'Babble'\n", 635 | " \n", 636 | "hunter = Quote('Elmer Fudd', \"I'm hunting wabbits\")\n", 637 | "brook = BabblingBrook()\n", 638 | "\n", 639 | "#儘管兩者完全獨立沒有關係,但只要有相同名稱的函數就可以呼叫到\n", 640 | "def who_says(obj):\n", 641 | " print(obj.who(), 'says', obj.says())\n", 642 | " \n", 643 | "who_says(hunter)\n", 644 | "who_says(brook)" 645 | ] 646 | }, 647 | { 648 | "cell_type": "markdown", 649 | "metadata": {}, 650 | "source": [ 651 | "---\n", 652 | "\n", 653 | "## 6.12 特殊方法\n", 654 | "[回目錄](#HOME) \n", 655 | "\n", 656 | "在python中,存在一些特殊方法( special method )或者稱回( magic method ), \n", 657 | "這些方法為雙底線( **\\_\\_** )開頭與結束用法,前面介紹過的( **\\_\\_init\\_\\_** )就是一個特殊方法,他是用來對新物件初始化用\n", 658 | "\n", 659 | "假設我有一隻class裡面有個method可以用來判斷兩個字串的小寫是否相同\n", 660 | "\n", 661 | "```python\n", 662 | "#---------------採用一般方法寫法\n", 663 | "class Word():\n", 664 | " def __init__(self, text):\n", 665 | " self.text = text\n", 666 | " \n", 667 | " def equals(self, word2):\n", 668 | " return self.text.lower() == word2.text.lower()\n", 669 | "\n", 670 | "#創建三個單字物件\n", 671 | "first = Word('ha')\n", 672 | "second = Word('HA')\n", 673 | "third = Word('eh')\n", 674 | "\n", 675 | "#進行比較\n", 676 | "first.equals(second) #True\n", 677 | "first.equals(third) #False\n", 678 | "\n", 679 | "#---------------採用特殊方法寫法\n", 680 | "class Word():\n", 681 | " def __init__(self, text):\n", 682 | " self.text = text\n", 683 | " \n", 684 | " def __eq__(self, word2):\n", 685 | " return self.text.lower() == word2.text.lower()\n", 686 | "\n", 687 | "#創建三個單字物件\n", 688 | "first = Word('ha')\n", 689 | "second = Word('HA')\n", 690 | "third = Word('eh')\n", 691 | "\n", 692 | "#進行比較\n", 693 | "first == second #True\n", 694 | "first == third #False\n", 695 | "```\n", 696 | "\n", 697 | "是~不~是~漂亮許多啦!!!!\n", 698 | "\n", 699 | "一些常用的特殊用法整理如下\n", 700 | "\n", 701 | "\n", 702 | "### 比較用\n", 703 | "|方法名稱 | 使用 |\n", 704 | "|:------------------:|:---------------------:|\n", 705 | "|\\_\\_eq\\_\\_(self, other) | self == other |\n", 706 | "|\\_\\_ne\\_\\_(self, other) | self != other |\n", 707 | "|\\_\\_lt\\_\\_(self, other) | self < other |\n", 708 | "|\\_\\_gt\\_\\_(self, other) | self > other |\n", 709 | "|\\_\\_le\\_\\_(self, other) | self <= other |\n", 710 | "|\\_\\_ge\\_\\_(self, other) | self >= other |\n", 711 | "\n", 712 | "\n", 713 | "### 數學用\n", 714 | "|方法名 | 使用 |\n", 715 | "|:------------------:|:---------------------:|\n", 716 | "|\\_\\_add\\_\\_(self, other)|self + other |\n", 717 | "|\\_\\_sub\\_\\_(self, other)|self - other |\n", 718 | "|\\_\\_mul\\_\\_(self, other)|self * other |\n", 719 | "|\\_\\_floordiv\\_\\_(self, other)|self // other |\n", 720 | "|\\_\\_truediv\\_\\_(self, other)|self / other |\n", 721 | "|\\_\\_mod\\_\\_(self, other)|self % other |\n", 722 | "|\\_\\_pow\\_\\_(self, other)|self ** other |\n", 723 | "\n", 724 | "### 其他常用\n", 725 | "|方法名 | 使用 |\n", 726 | "|:------------------:|:---------------------:|\n", 727 | "|\\_\\_str\\_\\_(self)|str(self) |\n", 728 | "|\\_\\_repr\\_\\_(self)|repr(self) |\n", 729 | "|\\_\\_len\\_\\_(self)|len(self) |\n", 730 | "\n", 731 | "\n", 732 | "完整清單請看官方文件。\n", 733 | "https://docs.python.org/3/reference/datamodel.html#special-method-names" 734 | ] 735 | }, 736 | { 737 | "cell_type": "code", 738 | "execution_count": 11, 739 | "metadata": { 740 | "collapsed": false 741 | }, 742 | "outputs": [ 743 | { 744 | "name": "stdout", 745 | "output_type": "stream", 746 | "text": [ 747 | "hahaha!!\n", 748 | "20\n", 749 | "min:3,max:10\n", 750 | "min:3,max:10\n" 751 | ] 752 | } 753 | ], 754 | "source": [ 755 | "class Word():\n", 756 | " def __init__(self, text):\n", 757 | " self.text = text\n", 758 | " \n", 759 | " def __str__(self):\n", 760 | " return self.text + 'haha!!'\n", 761 | "\n", 762 | "class sqrtt():\n", 763 | " def __init__(self, num):\n", 764 | " self.num = num\n", 765 | " \n", 766 | " def __mul__(self, number):\n", 767 | " return self.num * number.num\n", 768 | " \n", 769 | "class minmax():\n", 770 | " def __init__(self, minn, maxx):\n", 771 | " self.minn = minn\n", 772 | " self.maxx = maxx\n", 773 | " \n", 774 | " def __str__(self):\n", 775 | " return 'min:' + str(self.minn) + ',max:'+ str(self.maxx)\n", 776 | " \n", 777 | "\n", 778 | "#創建三個單字物件\n", 779 | "first = Word('ha')\n", 780 | "\n", 781 | "print(first) #print必須為字串,所以程式自行使用str()轉換成字串\n", 782 | "\n", 783 | "XD = sqrtt(4)\n", 784 | "XDD = sqrtt(5)\n", 785 | "print( XD * XDD )\n", 786 | "\n", 787 | "AM = minmax(3, 10)\n", 788 | "print(AM)\n", 789 | "print('min:' + str(AM.minn) + ',max:'+ str(AM.maxx))" 790 | ] 791 | }, 792 | { 793 | "cell_type": "markdown", 794 | "metadata": {}, 795 | "source": [ 796 | "---\n", 797 | "\n", 798 | "## 6.13 組合\n", 799 | "[回目錄](#HOME) \n", 800 | "\n", 801 | "\n", 802 | "如果要新建的類別有相似的類別可以繼承的話就可以採用繼承來取得父類別的所有, \n", 803 | "但若兩個類別差異太大,或是沒有關係,我們就可以採用組合來合併這些類別\n", 804 | "\n", 805 | "例如,鴨子是鳥的一種,所以可以繼承鳥的類別, \n", 806 | "但是嘴巴和尾巴不是鴨子的一種,而是鴨子的組成。\n" 807 | ] 808 | }, 809 | { 810 | "cell_type": "code", 811 | "execution_count": 12, 812 | "metadata": { 813 | "collapsed": false 814 | }, 815 | "outputs": [ 816 | { 817 | "name": "stdout", 818 | "output_type": "stream", 819 | "text": [ 820 | "這隻鴨子有一個 紅色的 嘴巴,然後有 白色,15cm 長的尾巴\n" 821 | ] 822 | } 823 | ], 824 | "source": [ 825 | "\n", 826 | "class Bill():\n", 827 | " def __init__(self, description):\n", 828 | " self.description = description\n", 829 | " \n", 830 | "class Tail():\n", 831 | " def __init__(self, length):\n", 832 | " self.length = length\n", 833 | " \n", 834 | "\n", 835 | "class Duck():\n", 836 | " def __init__(self, bill, tail):\n", 837 | " self.bill = bill\n", 838 | " self.tail = tail\n", 839 | " def about(self):\n", 840 | " print('這隻鴨子有一個', bill.description, '嘴巴,然後有', tail.length, '長的尾巴')\n", 841 | "\n", 842 | " \n", 843 | "bill = Bill('紅色的')\n", 844 | "tail = Tail('白色,15cm')\n", 845 | "\n", 846 | "duck = Duck(bill, tail)\n", 847 | "duck.about()" 848 | ] 849 | }, 850 | { 851 | "cell_type": "markdown", 852 | "metadata": {}, 853 | "source": [ 854 | "---\n", 855 | "\n", 856 | "## 6.14 類別與對象v.s.模組\n", 857 | "[回目錄](#HOME)\n", 858 | "\n", 859 | "有一些方法可以幫助你決定是把你的代碼封裝到類裡還是模塊裡。\n", 860 | "* 當你需要許多具有相似行為(方法),但不同狀態(特性)的實例時,使用對象是最好的選擇。\n", 861 | "* 類支持繼承,但模塊不支持。\n", 862 | "* 如果你想要保證實例的唯一性,使用模塊是最好的選擇。不管模塊在程序中被引用多少次,始終只有一個實例被加載。 \n", 863 | "* 如果你有一系列包含多個值的變量,並且它們能作為參數傳入不同的函數,那麼最好將它們封裝到類裡面。舉個例子,你可能會使用以大小和顏色為鍵的字典代表一張\n", 864 | "彩色图片。你可以在程序中为每张图片创建不同的字典,并把它们作为参数传递给像規模()或者變換()之類的函數。但這麼做的話,一旦你想要添加其他的鍵或者函數會變得非常麻煩。為了保證統一性,應該定義一個圖片類,把大小和顏色作為特性,把規模()和變換()定義為方法。這麼一來,關於一張圖片的所有數據和可執行的操作都存儲在了統一的位置。\n", 865 | "* 用最簡單的方式解決問題。使用字典,列表和元組往往要比使用模塊更加簡單,簡潔且快速。而使用類則更為複雜。\n", 866 | "\n", 867 | "\n", 868 | "---\n", 869 | "### 命名Tuple(named tuple)\n", 870 | "\n", 871 | "可以用來創造可以用名稱訪問的Tuple子類\n", 872 | "\n", 873 | "跟Tuple一樣,不可被改變,但是可以透過替換來產生新的命名Tuple" 874 | ] 875 | }, 876 | { 877 | "cell_type": "code", 878 | "execution_count": 13, 879 | "metadata": { 880 | "collapsed": false 881 | }, 882 | "outputs": [ 883 | { 884 | "name": "stdout", 885 | "output_type": "stream", 886 | "text": [ 887 | "Duck(bill='wide orange', tail='long')\n", 888 | "wide orange\n", 889 | "long\n", 890 | "Duck(bill='wide orange', tail='long')\n", 891 | "Duck(bill='crushing', tail='magnificent')\n" 892 | ] 893 | } 894 | ], 895 | "source": [ 896 | "from collections import namedtuple #引入函式庫\n", 897 | "\n", 898 | "Duck = namedtuple('Duck', 'bill tail') #宣告為命名Tuple,並且有bill和tail兩種名稱\n", 899 | "duck = Duck('wide orange', 'long') #給值\n", 900 | "\n", 901 | "print(duck)\n", 902 | "print(duck.bill)\n", 903 | "print(duck.tail)\n", 904 | "\n", 905 | "parts = {'bill': 'wide orange', 'tail': 'long'} #使用dictionary給值\n", 906 | "duck2 = Duck(**parts)\n", 907 | "print(duck2)\n", 908 | "\n", 909 | "duck3 = duck2._replace(tail='magnificent', bill='crushing') #替換內容\n", 910 | "print(duck3)" 911 | ] 912 | } 913 | ], 914 | "metadata": { 915 | "kernelspec": { 916 | "display_name": "Python [Root]", 917 | "language": "python", 918 | "name": "Python [Root]" 919 | }, 920 | "language_info": { 921 | "codemirror_mode": { 922 | "name": "ipython", 923 | "version": 3 924 | }, 925 | "file_extension": ".py", 926 | "mimetype": "text/x-python", 927 | "name": "python", 928 | "nbconvert_exporter": "python", 929 | "pygments_lexer": "ipython3", 930 | "version": "3.5.2" 931 | } 932 | }, 933 | "nbformat": 4, 934 | "nbformat_minor": 0 935 | } 936 | -------------------------------------------------------------------------------- /.ipynb_checkpoints/CHAPTER 8 Data Has to Go Somewhere-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": false 7 | }, 8 | "source": [ 9 | "\n", 10 | "# CHAPTER 8 Data Has to Go Somewhere\n", 11 | "## 資料的歸宿\n", 12 | "\n", 13 | "* [8.1 資料的輸出與輸入](#IO)\n", 14 | "* [8.2 結構化資料檔案](#StructuredText)\n", 15 | "* [8.3 結構化二進位檔案](#StructuredBinary)\n", 16 | "* [8.4 關聯式資料庫](#RelationalDatabases)\n", 17 | "* [8.5 NoSQL資料庫](#NoSQL)\n", 18 | "* [8.6 全文檢索資料庫](#Full-TextDatabases)\n", 19 | "\n" 20 | ] 21 | }, 22 | { 23 | "cell_type": "markdown", 24 | "metadata": {}, 25 | "source": [ 26 | "---\n", 27 | "\n", 28 | "## 8.1 資料的輸出與輸入\n", 29 | "[回目錄](#HOME)\n", 30 | "\n", 31 | "```python\n", 32 | "fileobj = open(filename, mode)\n", 33 | "```\n", 34 | "\n", 35 | "|mode 第一個字母|解釋|\n", 36 | "|:---:|----|\n", 37 | "|r |表示讀模式|\n", 38 | "|w |表示寫模式。如果文件不存在則新創建,如果存在則重寫新內容|\n", 39 | "|x |表示在文件不存在的情況下新創建並寫文件|\n", 40 | "|a |表示如果文件存在,在文件末尾追加寫內容|\n", 41 | "\n", 42 | "\n", 43 | "|mode 第二個字母|解釋|\n", 44 | "|:---:|----|\n", 45 | "|t|(或者省略)代表文本類型|\n", 46 | "|b| 代表二進位文件|\n" 47 | ] 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "metadata": {}, 52 | "source": [ 53 | "### 8.1.1 使用write()與print()寫入檔案\n", 54 | "\n", 55 | "\n", 56 | "使用print寫入時可以使用sep與end參數指定分隔符號與結束符號\n", 57 | "* sep,預設為' '\n", 58 | "* end,預設為'\\n'" 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": 1, 64 | "metadata": { 65 | "collapsed": false 66 | }, 67 | "outputs": [], 68 | "source": [ 69 | "abc = 'abc'\n", 70 | "defg = 'defg'\n", 71 | "\n", 72 | "#wirte寫入\n", 73 | "fout = open('Data/relativity', 'wt')\n", 74 | "fout.write('{0}-{1}。'.format(abc, 'XD'))\n", 75 | "fout.write(defg)\n", 76 | "fout.close()\n", 77 | "\n", 78 | "#print寫入(預設)\n", 79 | "fout = open('Data/relativity', 'wt')\n", 80 | "print(abc, defg, file=fout)\n", 81 | "fout.close()\n", 82 | "\n", 83 | "##print寫入(更換分隔與結束符號)\n", 84 | "fout = open('Data/relativity', 'wt')\n", 85 | "print(abc, defg, sep='-', end='。', file=fout)\n", 86 | "fout.close()" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": 2, 92 | "metadata": { 93 | "collapsed": false 94 | }, 95 | "outputs": [ 96 | { 97 | "name": "stdout", 98 | "output_type": "stream", 99 | "text": [ 100 | "文件已存在。\n" 101 | ] 102 | } 103 | ], 104 | "source": [ 105 | "#分段寫入\n", 106 | "poem = '''There was a young lady named Bright,\n", 107 | "Whose speed was far faster than light;\n", 108 | "She started one day\n", 109 | "In a relative way,\n", 110 | "And returned on the previous night.'''\n", 111 | "size = len(poem)\n", 112 | "\n", 113 | "fout = open('Data/relativity', 'wt')\n", 114 | "\n", 115 | "offset = 0\n", 116 | "chunk = 100\n", 117 | "while True:\n", 118 | " if offset > size:\n", 119 | " fout.close()\n", 120 | " break\n", 121 | " fout.write(poem[offset:offset+chunk])\n", 122 | " offset += chunk\n", 123 | " \n", 124 | "\n", 125 | "#open模式改為x可以防止覆蓋已存在之文件\n", 126 | "try:\n", 127 | " fout = open('Data/relativity', 'xt')\n", 128 | " fout.write('stomp stomp stomp')\n", 129 | "except FileExistsError:\n", 130 | " print('文件已存在。')" 131 | ] 132 | }, 133 | { 134 | "cell_type": "markdown", 135 | "metadata": {}, 136 | "source": [ 137 | "### 8.1.2使用read(),readline()或者readlines()讀取檔案\n", 138 | "\n", 139 | "* __fin.read()__,一次讀入全部,或是指定讀入字節數,注意記憶體占用情況\n", 140 | "* __fin.readline()__,一次讀入一行\n", 141 | "* __fin.readlines()__,疊代器用法,寫法更好看" 142 | ] 143 | }, 144 | { 145 | "cell_type": "code", 146 | "execution_count": 3, 147 | "metadata": { 148 | "collapsed": false 149 | }, 150 | "outputs": [ 151 | { 152 | "name": "stdout", 153 | "output_type": "stream", 154 | "text": [ 155 | "There was a young lady named Bright,\n", 156 | "Whose speed was far faster than light;\n", 157 | "She started one day\n", 158 | "In a relative way,\n", 159 | "And returned on the previous night.\n", 160 | "\n", 161 | "================\n", 162 | "There was a young lady named Bright,\n", 163 | "Whose speed was far faster than light;\n", 164 | "She started one day\n", 165 | "In a relative way,\n", 166 | "And returned on the previous night.\n", 167 | "\n", 168 | "================\n", 169 | "There was a young lady named Bright,\n", 170 | "Whose speed was far faster than light;\n", 171 | "She started one day\n", 172 | "In a relative way,\n", 173 | "And returned on the previous night.\n", 174 | "\n", 175 | "================\n", 176 | "共 5 行\n", 177 | "There was a young lady named Bright,\n", 178 | "。Whose speed was far faster than light;\n", 179 | "。She started one day\n", 180 | "。In a relative way,\n", 181 | "。And returned on the previous night.。" 182 | ] 183 | } 184 | ], 185 | "source": [ 186 | "#一次讀入\n", 187 | "fin = open('Data/relativity', 'rt' )\n", 188 | "poem = fin.read()\n", 189 | "fin.close()\n", 190 | "print(poem)\n", 191 | "\n", 192 | "\n", 193 | "#指定一次100字節\n", 194 | "print('\\n================')\n", 195 | "poem = ''\n", 196 | "fin = open('Data/relativity', 'rt' )\n", 197 | "chunk = 100\n", 198 | "while True:\n", 199 | " fragment = fin.read(chunk)\n", 200 | " if not fragment:\n", 201 | " fin.close()\n", 202 | " break\n", 203 | " poem += fragment\n", 204 | "\n", 205 | "print(poem)\n", 206 | "\n", 207 | "#使用readline一次讀入一行\n", 208 | "print('\\n================')\n", 209 | "poem = ''\n", 210 | "fin = open('Data/relativity', 'rt' )\n", 211 | "while True:\n", 212 | " line = fin.readline()\n", 213 | " if not line:\n", 214 | " fin.close()\n", 215 | " break\n", 216 | " poem += line\n", 217 | "\n", 218 | "print(poem)\n", 219 | "\n", 220 | "#使用readlines疊代器\n", 221 | "print('\\n================')\n", 222 | "fin = open('Data/relativity', 'rt' )\n", 223 | "lines = fin.readlines()\n", 224 | "fin.close()\n", 225 | "print('共', len(lines), '行')\n", 226 | "\n", 227 | "for line in lines:\n", 228 | " print(line, end='。')" 229 | ] 230 | }, 231 | { 232 | "cell_type": "markdown", 233 | "metadata": {}, 234 | "source": [ 235 | "### 8.1.3 寫入二進位檔案" 236 | ] 237 | }, 238 | { 239 | "cell_type": "code", 240 | "execution_count": 4, 241 | "metadata": { 242 | "collapsed": false 243 | }, 244 | "outputs": [], 245 | "source": [ 246 | "bdata = bytes(range(0, 256))\n", 247 | "#print(bdata)\n", 248 | "\n", 249 | "#一次寫入\n", 250 | "fout = open('Data/bfile', 'wb')\n", 251 | "fout.write(bdata)\n", 252 | "fout.close()\n", 253 | "\n", 254 | "#批次寫入\n", 255 | "fout = open('Data/bfile', 'wb')\n", 256 | "size = len(bdata)\n", 257 | "offset = 0\n", 258 | "chunk = 100\n", 259 | "while True:\n", 260 | " if offset > size:\n", 261 | " fout.close()\n", 262 | " break\n", 263 | " fout.write(bdata[offset:offset+chunk])\n", 264 | " offset += chunk\n" 265 | ] 266 | }, 267 | { 268 | "cell_type": "markdown", 269 | "metadata": {}, 270 | "source": [ 271 | "### 8.1.4 讀取二進位檔案" 272 | ] 273 | }, 274 | { 275 | "cell_type": "code", 276 | "execution_count": 5, 277 | "metadata": { 278 | "collapsed": false 279 | }, 280 | "outputs": [ 281 | { 282 | "name": "stdout", 283 | "output_type": "stream", 284 | "text": [ 285 | "b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\\x7f\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x8b\\x8c\\x8d\\x8e\\x8f\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b\\x9c\\x9d\\x9e\\x9f\\xa0\\xa1\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\\xa8\\xa9\\xaa\\xab\\xac\\xad\\xae\\xaf\\xb0\\xb1\\xb2\\xb3\\xb4\\xb5\\xb6\\xb7\\xb8\\xb9\\xba\\xbb\\xbc\\xbd\\xbe\\xbf\\xc0\\xc1\\xc2\\xc3\\xc4\\xc5\\xc6\\xc7\\xc8\\xc9\\xca\\xcb\\xcc\\xcd\\xce\\xcf\\xd0\\xd1\\xd2\\xd3\\xd4\\xd5\\xd6\\xd7\\xd8\\xd9\\xda\\xdb\\xdc\\xdd\\xde\\xdf\\xe0\\xe1\\xe2\\xe3\\xe4\\xe5\\xe6\\xe7\\xe8\\xe9\\xea\\xeb\\xec\\xed\\xee\\xef\\xf0\\xf1\\xf2\\xf3\\xf4\\xf5\\xf6\\xf7\\xf8\\xf9\\xfa\\xfb\\xfc\\xfd\\xfe\\xff'\n" 286 | ] 287 | } 288 | ], 289 | "source": [ 290 | "fin = open('Data/bfile', 'rb')\n", 291 | "bdata = fin.read()\n", 292 | "fin.close()\n", 293 | "\n", 294 | "print(bdata)" 295 | ] 296 | }, 297 | { 298 | "cell_type": "markdown", 299 | "metadata": {}, 300 | "source": [ 301 | "### 8.1.5使用with自動關閉檔案\n", 302 | "\n", 303 | "python若後續沒有再繼續使用檔案則會自動關閉,所以在一個function中開啟檔案就算沒有關閉最後也會自動關閉。 \n", 304 | "但是在一個主程式中開啟則不會自動關閉,所以可以使用with as來做為自動關閉檔案用" 305 | ] 306 | }, 307 | { 308 | "cell_type": "code", 309 | "execution_count": 6, 310 | "metadata": { 311 | "collapsed": true 312 | }, 313 | "outputs": [], 314 | "source": [ 315 | "with open('Data/relativity', 'wt') as fout:\n", 316 | " fout.write(poem)" 317 | ] 318 | }, 319 | { 320 | "cell_type": "markdown", 321 | "metadata": {}, 322 | "source": [ 323 | "### 使用seek()改變位置\n", 324 | "\n", 325 | "__file.tell()__可以查詢讀取位置\n", 326 | "seek(offset,origin)\n", 327 | "\n", 328 | "origin = 0,預設,從頭開始位移。 \n", 329 | "origin = 1,從目前位置開始位移。 \n", 330 | "origin = 2,從最後往前為位移。" 331 | ] 332 | }, 333 | { 334 | "cell_type": "code", 335 | "execution_count": 7, 336 | "metadata": { 337 | "collapsed": false 338 | }, 339 | "outputs": [ 340 | { 341 | "name": "stdout", 342 | "output_type": "stream", 343 | "text": [ 344 | "1\n", 345 | "255\n", 346 | "1\n", 347 | "255\n", 348 | "255\n" 349 | ] 350 | } 351 | ], 352 | "source": [ 353 | "fin = open('Data/bfile', 'rb')\n", 354 | "fin.seek(255)\n", 355 | "\n", 356 | "bdata = fin.read()\n", 357 | "print(len(bdata))\n", 358 | "print(bdata[0])\n", 359 | "fin.close()\n", 360 | "\n", 361 | "#使用不同方法讀取最後一個字節\n", 362 | "fin = open('Data/bfile', 'rb')\n", 363 | "\n", 364 | "fin.seek(-1, 2)\n", 365 | "bdata = fin.read()\n", 366 | "print(len(bdata))\n", 367 | "print(bdata[0])\n", 368 | "fin.close()\n", 369 | "\n", 370 | "#\n", 371 | "fin = open('Data/bfile', 'rb')\n", 372 | "fin.seek(254, 0)\n", 373 | "fin.tell()\n", 374 | "fin.seek(1, 1)\n", 375 | "fin.tell()\n", 376 | "\n", 377 | "bdata = fin.read()\n", 378 | "print(bdata[0])" 379 | ] 380 | }, 381 | { 382 | "cell_type": "markdown", 383 | "metadata": {}, 384 | "source": [ 385 | "---\n", 386 | "\n", 387 | "## 8.2 結構化資料檔案\n", 388 | "[回目錄](#HOME)\n", 389 | "\n", 390 | "* CSV\n", 391 | "* XML\n", 392 | "* HTML\n", 393 | "* JSON" 394 | ] 395 | }, 396 | { 397 | "cell_type": "code", 398 | "execution_count": 8, 399 | "metadata": { 400 | "collapsed": false 401 | }, 402 | "outputs": [ 403 | { 404 | "name": "stdout", 405 | "output_type": "stream", 406 | "text": [ 407 | "[['Doctor', 'No'], [], ['Rosa', 'Klebb'], [], ['Mister', 'Big'], [], ['Auric', 'Goldfinger'], [], ['Ernst', 'Blofeld'], []]\n", 408 | "[{'first': 'Doctor', 'last': 'No'}, {'first': 'Rosa', 'last': 'Klebb'}, {'first': 'Mister', 'last': 'Big'}, {'first': 'Auric', 'last': 'Goldfinger'}, {'first': 'Ernst', 'last': 'Blofeld'}]\n", 409 | "[{'first': 'Doctor', 'last33': 'Blofeld', 'last': 'No'}, {'first': 'Rosa', 'last33': 'Blofeld', 'last': 'Klebb'}, {'first': 'Mister', 'last33': 'Blofeld', 'last': 'Big'}, {'first': 'Auric', 'last33': 'Blofeld', 'last': 'Goldfinger'}, {'first': 'Ernst', 'last33': 'Blofeld', 'last': 'Blofeld'}]\n" 410 | ] 411 | } 412 | ], 413 | "source": [ 414 | "import csv\n", 415 | "villains = [\n", 416 | " ['Doctor', 'No'],\n", 417 | " ['Rosa', 'Klebb'],\n", 418 | " ['Mister', 'Big'],\n", 419 | " ['Auric', 'Goldfinger'],\n", 420 | " ['Ernst', 'Blofeld']]\n", 421 | "\n", 422 | "# 寫入\n", 423 | "with open('Data/villains', 'wt') as fout:\n", 424 | " csvout = csv.writer(fout)\n", 425 | " csvout.writerows(villains)\n", 426 | "\n", 427 | "# 讀取\n", 428 | "with open('Data/villains', 'rt') as fin:\n", 429 | " cin = csv.reader(fin)\n", 430 | " villains = [row for row in cin]\n", 431 | "print(villains)\n", 432 | "\n", 433 | "# 讀成字典\n", 434 | "with open('Data/villains', 'rt') as fin:\n", 435 | " cin = csv.DictReader(fin, fieldnames=['first', 'last'])\n", 436 | " villains = [row for row in cin]\n", 437 | "print(villains)\n", 438 | "\n", 439 | "# 用字典格式寫入\n", 440 | "villains = [{'first': 'Doctor', 'last': 'No', 'last33': 'Blofeld'},\n", 441 | " {'first': 'Rosa', 'last': 'Klebb', 'last33': 'Blofeld'},\n", 442 | " {'first': 'Mister', 'last': 'Big', 'last33': 'Blofeld'},\n", 443 | " {'first': 'Auric', 'last': 'Goldfinger', 'last33': 'Blofeld'},\n", 444 | " {'first': 'Ernst', 'last': 'Blofeld', 'last33': 'Blofeld'}]\n", 445 | "\n", 446 | "with open('Data/villains', 'wt') as fout:\n", 447 | "# cout = csv.DictWriter(fout, ['first', 'last'])\n", 448 | " cout = csv.DictWriter(fout, ['first', 'last','last33'])\n", 449 | " cout.writeheader() #寫檔頭\n", 450 | " cout.writerows(villains)\n", 451 | " \n", 452 | "with open('Data/villains', 'rt') as fin:\n", 453 | " cin = csv.DictReader(fin)\n", 454 | " villains = [row for row in cin]\n", 455 | "print(villains)" 456 | ] 457 | }, 458 | { 459 | "cell_type": "code", 460 | "execution_count": 9, 461 | "metadata": { 462 | "collapsed": false 463 | }, 464 | "outputs": [ 465 | { 466 | "name": "stdout", 467 | "output_type": "stream", 468 | "text": [ 469 | "menu\n", 470 | "\ttag: item attributes: breakfast burritos\n", 471 | "\ttag: item attributes: {'price': '$6.00'}\n", 472 | "\ttag: item attributes: pancakes\n", 473 | "\ttag: item attributes: {'price': '$4.00', 'XDD': 'QQ'}\n", 474 | "\ttag: item attributes: hamburger\n", 475 | "\ttag: item attributes: {'price': '$5.00'}\n", 476 | "\ttag: item attributes: spaghetti\n", 477 | "\ttag: item attributes: {'price': '8.00'}\n", 478 | "3\n", 479 | "2\n" 480 | ] 481 | } 482 | ], 483 | "source": [ 484 | "import xml.etree.ElementTree as et\n", 485 | "tree = et.ElementTree(file='Data/menu.xml')\n", 486 | "root = tree.getroot()\n", 487 | "print(root.tag)\n", 488 | "\n", 489 | "for child in root:\n", 490 | " #print('tag:', child.tag, 'attributes:', child.attrib)\n", 491 | " for grandchild in child:\n", 492 | " print('\\ttag:', grandchild.tag, 'attributes:', grandchild.text)\n", 493 | " print('\\ttag:', grandchild.tag, 'attributes:', grandchild.attrib)\n", 494 | " \n", 495 | " \n", 496 | "print(len(root))\n", 497 | "print(len(root[0]))" 498 | ] 499 | }, 500 | { 501 | "cell_type": "code", 502 | "execution_count": 10, 503 | "metadata": { 504 | "collapsed": false 505 | }, 506 | "outputs": [ 507 | { 508 | "name": "stdout", 509 | "output_type": "stream", 510 | "text": [ 511 | "\n", 512 | "{'lunch': {'items': {'hamburger': '$5.00'}, 'hours': '11-3'}, 'breakfast': {'items': {'breakfast burritos': '$6.00', 'pancakes': '$4.00'}, 'hours': '7-11'}, 'dinner': {'items': {'spaghetti': '$8.00'}, 'hours': '3-10'}}\n", 513 | "{'items': {'breakfast burritos': '$6.00', 'pancakes': '$4.00'}, 'hours': '7-11'}\n" 514 | ] 515 | } 516 | ], 517 | "source": [ 518 | "menu = \\\n", 519 | "{\n", 520 | " \"breakfast\": {\n", 521 | " \"hours\": \"7-11\",\n", 522 | " \"items\": {\n", 523 | " \"breakfast burritos\": \"$6.00\",\n", 524 | " \"pancakes\": \"$4.00\"\n", 525 | " }\n", 526 | " },\n", 527 | " \"lunch\" : {\n", 528 | " \"hours\": \"11-3\",\n", 529 | " \"items\": {\n", 530 | " \"hamburger\": \"$5.00\"\n", 531 | " }\n", 532 | " },\n", 533 | " \"dinner\": {\n", 534 | " \"hours\": \"3-10\",\n", 535 | " \"items\": {\n", 536 | " \"spaghetti\": \"$8.00\"\n", 537 | " }\n", 538 | " }\n", 539 | "}\n", 540 | "\n", 541 | "import json\n", 542 | "menu_json = json.dumps(menu)\n", 543 | "print(type(menu_json))\n", 544 | "# print(menu_json['breakfast'])\n", 545 | "\n", 546 | "menu2 = json.loads(menu_json)\n", 547 | "print(menu2)\n", 548 | "print(menu2['breakfast'])" 549 | ] 550 | }, 551 | { 552 | "cell_type": "markdown", 553 | "metadata": {}, 554 | "source": [ 555 | "---\n", 556 | "\n", 557 | "## 8.3 結構化二進位檔案\n", 558 | "[回目錄](#HOME)" 559 | ] 560 | }, 561 | { 562 | "cell_type": "markdown", 563 | "metadata": {}, 564 | "source": [ 565 | "---\n", 566 | "\n", 567 | "## 8.4 關聯式資料庫 SQL\n", 568 | "[回目錄](#HOME)\n" 569 | ] 570 | }, 571 | { 572 | "cell_type": "markdown", 573 | "metadata": {}, 574 | "source": [ 575 | "---\n", 576 | "\n", 577 | "## 8.5 NoSQL資料庫\n", 578 | "[回目錄](#HOME)\n", 579 | "\n", 580 | "\n" 581 | ] 582 | }, 583 | { 584 | "cell_type": "markdown", 585 | "metadata": {}, 586 | "source": [ 587 | "---\n", 588 | "\n", 589 | "## 8.6 全文檢索資料庫\n", 590 | "[回目錄](#HOME)\n", 591 | "\n" 592 | ] 593 | } 594 | ], 595 | "metadata": { 596 | "anaconda-cloud": {}, 597 | "kernelspec": { 598 | "display_name": "Python [Root]", 599 | "language": "python", 600 | "name": "Python [Root]" 601 | }, 602 | "language_info": { 603 | "codemirror_mode": { 604 | "name": "ipython", 605 | "version": 3 606 | }, 607 | "file_extension": ".py", 608 | "mimetype": "text/x-python", 609 | "name": "python", 610 | "nbconvert_exporter": "python", 611 | "pygments_lexer": "ipython3", 612 | "version": "3.5.2" 613 | } 614 | }, 615 | "nbformat": 4, 616 | "nbformat_minor": 0 617 | } 618 | -------------------------------------------------------------------------------- /CHAPTER 11 Concurrency and Networks.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "\n", 8 | "# CHAPTER 11 Concurrency and Networks\n", 9 | "## 開發與網路\n", 10 | "\n", 11 | "* [11.1 開發](#Concurrency)\n", 12 | "* [11.2 網路](#Networks)\n", 13 | "\n", 14 | "Time is nature’s way of keeping everything from happening at once. \n", 15 | "Space is what preventseverything from happening to me. \n", 16 | "— Quotes about Time\n", 17 | "\n", 18 | "先前的範例都是在一台電腦一次運行一次,但是可以利用技術做到分散式計算等更強大的功能。\n", 19 | "\n", 20 | "好處有\n", 21 | "* 提升性能,可以不用因為某部分運行較慢而塞住後面的程序\n", 22 | "* 提升安全性,同時運作多個相同任務防止意外\n", 23 | "* 把程式拆解得更細小更好維護與理解\n", 24 | "* 網路傳送與接收數據" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": {}, 30 | "source": [ 31 | "---\n", 32 | "\n", 33 | "## 11.1 開發\n", 34 | "[回目錄](#HOME)\n", 35 | "\n", 36 | "一般而言在計算時速度變慢時多半是因為__I/O___的限制以及__CPU限制__ \n", 37 | "I/O的速度比起CPU計算上慢上許多, \n", 38 | "CPU算得較慢時可能是遇到科學相關需要大量計算或是圖形相關的計算導致變慢\n", 39 | "\n", 40 | "程式在開發時一般會有兩種技術,__同步(synchronous)__與__非同步(asynchronous)__\n", 41 | "\n", 42 | "* 同步是指說程式在執行時是一個接著一個,A指令做完才做B指令,最後在C指令\n", 43 | "* 非同步是可以讓A B C三種指令同時在一個程式裡執行" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": {}, 49 | "source": [ 50 | "__佇列(Queue)__中文也翻作隊列,顧名思義是一種像排隊一樣的概念, \n", 51 | "以生活中的情況為人們一個接一個的從隊伍後面加入排隊,而窗口的服務人員則從最前面的民眾一個接一個處理事務。(http://emn178.pixnet.net/blog/post/93475832-%E4%BD%87%E5%88%97(queue))\n", 52 | "\n", 53 | "本書作者以洗碗流程作為範例,分成兩段工作過程,清洗與烘乾。 \n", 54 | "假設一個人做事,可以有兩種做法,\n", 55 | "1. 洗完一個盤子就拿去烘乾\n", 56 | "2. 先洗完全部的盤子,在統一把盤子烘乾\n", 57 | "\n", 58 | "若要改善效率最快的方法就是找幫手,一人負責洗碗一人負責烘乾,但是這樣會遇到一個問題,如果洗盤子的速度大於烘乾盤子時,是要等待烘乾的人員閒置後在遞交盤子給他,還是先行放置在桌上,在繼續洗下一個盤子,等他有空時再自行拿取,前者就是同步的概念,後者則為非同步的概念。\n", 59 | "\n", 60 | "假設水槽中的盤子們是佇列(Queue)中的工作項目,可以進行同步與分同步的工作流程。 \n", 61 | "* 同步:把水槽中的髒盤子給第一個閒置的洗碗人員洗,洗完後等烘乾人員閒置後再把盤子給他\n", 62 | "* 非同步:洗盤子的人員洗好就將盤子放置在桌上後繼續清洗下一個,烘乾人員閒置時就去看桌上有無盤子可以清洗。\n", 63 | "\n", 64 | "![Alt text](http://i.imgur.com/mtFun5p.png \"時間花費表\")" 65 | ] 66 | }, 67 | { 68 | "cell_type": "markdown", 69 | "metadata": {}, 70 | "source": [ 71 | "#### 原始洗碗流程\n", 72 | "\n", 73 | "```python\n", 74 | "import os\n", 75 | "import time\n", 76 | "from datetime import datetime\n", 77 | "\n", 78 | "def washer(dishes, now_):\n", 79 | "\tfor dish in dishes:\n", 80 | "\t\tnow = datetime.now()\n", 81 | "\t\tprint('Washing', dish, ', time:', now - now_, ', pid', os.getpid())\n", 82 | "\t\ttime.sleep(1)\n", 83 | "\t\tdryer(dish, now_)\n", 84 | "\n", 85 | "def dryer(dish, now_):\n", 86 | "\tnow = datetime.now()\n", 87 | "\tprint('Drying ', dish, ', time:', now - now_, ', pid', os.getpid())\n", 88 | "\ttime.sleep(2)\n", 89 | "\n", 90 | "if __name__ == \"__main__\":\n", 91 | "\tnow_ = datetime.now()\n", 92 | "\tdishes = ['dish-1', 'dish-2', 'dish-3', 'dish-4']\n", 93 | "\twasher(dishes, now_)\n", 94 | "```" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": 1, 100 | "metadata": { 101 | "collapsed": false 102 | }, 103 | "outputs": [ 104 | { 105 | "name": "stdout", 106 | "output_type": "stream", 107 | "text": [ 108 | "Washing dish-1 , time: 0:00:00 , pid 13204\n", 109 | "Drying dish-1 , time: 0:00:01.010387 , pid 13204\n", 110 | "Washing dish-2 , time: 0:00:03.023734 , pid 13204\n", 111 | "Drying dish-2 , time: 0:00:04.027234 , pid 13204\n", 112 | "Washing dish-3 , time: 0:00:06.027493 , pid 13204\n", 113 | "Drying dish-3 , time: 0:00:07.039876 , pid 13204\n", 114 | "Washing dish-4 , time: 0:00:09.052473 , pid 13204\n", 115 | "Drying dish-4 , time: 0:00:10.060635 , pid 13204\n" 116 | ] 117 | } 118 | ], 119 | "source": [ 120 | "import subprocess\n", 121 | "ret = subprocess.getoutput('python Data/dishes.py')\n", 122 | "print(ret) #執行需時間,請等候" 123 | ] 124 | }, 125 | { 126 | "cell_type": "markdown", 127 | "metadata": {}, 128 | "source": [ 129 | "### 行程or處理程序(Processes)\n", 130 | "\n", 131 | "[wiki 行程](https://zh.wikipedia.org/wiki/%E8%A1%8C%E7%A8%8B)\n", 132 | "\n", 133 | "下列範例可以模擬兩個人員在進行分工合作,洗碗為主行程,烘乾則為另開的行程,所以洗碗者不必等到烘乾完畢就可以洗下一個盤子\n", 134 | "\n", 135 | "```python\n", 136 | "import multiprocessing as mp\n", 137 | "import os\n", 138 | "import time\n", 139 | "from datetime import datetime\n", 140 | "\n", 141 | "def washer(dishes, output, now_):\n", 142 | "\tfor dish in dishes:\n", 143 | "\t\tnow = datetime.now()\n", 144 | "\t\tprint('Washing', dish, ', time:', now - now_, ', pid', os.getpid())\n", 145 | "\t\ttime.sleep(1)\n", 146 | "\t\t#把東西丟給其他行程後繼續執行下一個\n", 147 | "\t\toutput.put(dish)\n", 148 | "\n", 149 | "def dryer(input, now_):\n", 150 | "\twhile True:\n", 151 | "\t\tdish = input.get()\n", 152 | "\t\tnow = datetime.now()\n", 153 | "\t\tprint('Drying ', dish, ', time:', now - now_, ', pid', os.getpid())\n", 154 | "\t\ttime.sleep(2)\n", 155 | "\t\tinput.task_done()\n", 156 | "\n", 157 | "if __name__ == \"__main__\":\n", 158 | "\tnow_ = datetime.now()\n", 159 | "\t#建立佇列\n", 160 | "\tdish_queue = mp.JoinableQueue()\n", 161 | "\t#創建行程(烘乾人員)\n", 162 | "\tdryer_proc = mp.Process(target=dryer, args=(dish_queue, now_,))\n", 163 | "\tdryer_proc.daemon = True\n", 164 | "\t#啟動行程(上班囉)\n", 165 | "\tdryer_proc.start()\n", 166 | "\t#time.sleep(1)\n", 167 | "\t\n", 168 | "\tdishes = ['dish-1', 'dish-2', 'dish-3', 'dish-4']\n", 169 | "\twasher(dishes, dish_queue, now_)\n", 170 | "\tdish_queue.join()\n", 171 | "```\n", 172 | "p.s. 在ipython中非主程式的行程print不出來,請自行在本機端cmd跑,或是把print改成寫成實體檔案方可看見結果, \n", 173 | "Data資料夾中有dishes_process.py檔案可供使用 \n", 174 | "\n", 175 | "結果: \n", 176 | "Washing dish-1 , time: 0:00:00.037144 , pid 10480 \n", 177 | "Washing dish-2 , time: 0:00:01.047415 , pid 10480 \n", 178 | "Drying dish-1 , time: 0:00:01.047415 , pid 7280 \n", 179 | "Washing dish-3 , time: 0:00:02.060229 , pid 10480 \n", 180 | "Drying dish-2 , time: 0:00:03.047613 , pid 7280 \n", 181 | "Washing dish-4 , time: 0:00:03.063241 , pid 10480 \n", 182 | "Drying dish-3 , time: 0:00:05.047959 , pid 7280 \n", 183 | "Drying dish-4 , time: 0:00:07.053659 , pid 7280" 184 | ] 185 | }, 186 | { 187 | "cell_type": "markdown", 188 | "metadata": {}, 189 | "source": [ 190 | "### 執行緒(Threads)\n", 191 | "\n", 192 | "[wiki 執行緒](https://zh.wikipedia.org/wiki/%E7%BA%BF%E7%A8%8B)\n", 193 | "\n", 194 | "下列範例可以模擬一個人員洗,兩個人烘的分工合作,全部都為同一個主行程,但是另開兩個線程來處理烘乾工作\n", 195 | "\n", 196 | "```python\n", 197 | "\n", 198 | "import threading, queue\n", 199 | "import os\n", 200 | "import time\n", 201 | "from datetime import datetime\n", 202 | "\n", 203 | "def washer(dishes, dish_queue, now_):\n", 204 | "\tfor dish in dishes:\n", 205 | "\t\tnow = datetime.now()\n", 206 | "\t\tprint (\"Washing\", dish, now - now_, ', pid', os.getpid(), threading.current_thread())\n", 207 | "\t\ttime.sleep(1)\n", 208 | "\t\tdish_queue.put(dish)\n", 209 | "\n", 210 | "def dryer(dish_queue, now_):\n", 211 | "\twhile True:\n", 212 | "\t\tdish = dish_queue.get()\n", 213 | "\t\tnow = datetime.now()\n", 214 | "\t\tprint (\"Drying \", dish, now - now_, ', pid', os.getpid(), threading.current_thread())\n", 215 | "\t\ttime.sleep(2)\n", 216 | "\t\tdish_queue.task_done()\n", 217 | "\n", 218 | "if __name__ == \"__main__\":\n", 219 | "\tdish_queue = queue.Queue()\n", 220 | "\tnow_ = datetime.now()\n", 221 | " #控制要開幾條執行緒\n", 222 | "\tfor n in range(2):\n", 223 | "\t\tdryer_thread = threading.Thread(target=dryer, args=(dish_queue, now_))\n", 224 | "\t\tdryer_thread.daemon = True\n", 225 | "\t\tdryer_thread.start()\n", 226 | "\t\t\n", 227 | "\tdishes = ['dishe-1', 'dishe-2', 'dishe-3', 'dishe-4']\n", 228 | "\twasher(dishes, dish_queue, now_)\n", 229 | "\tdish_queue.join()\n", 230 | "\n", 231 | "```" 232 | ] 233 | }, 234 | { 235 | "cell_type": "code", 236 | "execution_count": 7, 237 | "metadata": { 238 | "collapsed": false 239 | }, 240 | "outputs": [ 241 | { 242 | "name": "stdout", 243 | "output_type": "stream", 244 | "text": [ 245 | "Washing dishe-1 0:00:00.000505 , pid 5376 <_MainThread(MainThread, started 18348)>\n", 246 | "Washing dishe-2 0:00:01.012149 , pid 5376 <_MainThread(MainThread, started 18348)>\n", 247 | "Drying dishe-1 0:00:01.012149 , pid 5376 \n", 248 | "Washing dishe-3 0:00:02.012222 , pid 5376 <_MainThread(MainThread, started 18348)>\n", 249 | "Drying dishe-2 0:00:02.012222 , pid 5376 \n", 250 | "Washing dishe-4 0:00:03.022536 , pid 5376 <_MainThread(MainThread, started 18348)>\n", 251 | "Drying dishe-3 0:00:03.022536 , pid 5376 \n", 252 | "Drying dishe-4 0:00:04.032120 , pid 5376 \n" 253 | ] 254 | } 255 | ], 256 | "source": [ 257 | "import subprocess\n", 258 | "ret = subprocess.getoutput('python Data/dishes_threads.py')\n", 259 | "print(ret) #執行需時間,請等候" 260 | ] 261 | }, 262 | { 263 | "cell_type": "markdown", 264 | "metadata": {}, 265 | "source": [ 266 | "總而言之,對於 Python,建議如下:\n", 267 | "* 使用執行緒來解決 I/O 限制問題;\n", 268 | "* 使用行程、網絡或者事件(下一節會介紹)來處理 CPU 限制問題。" 269 | ] 270 | }, 271 | { 272 | "cell_type": "markdown", 273 | "metadata": {}, 274 | "source": [ 275 | "書中還介紹許多函示庫可以辦到各種不同的佇列(Queue)功能\n", 276 | "* gevent\n", 277 | "* twisted\n", 278 | "* asyncio\n", 279 | "* Redis" 280 | ] 281 | }, 282 | { 283 | "cell_type": "markdown", 284 | "metadata": {}, 285 | "source": [ 286 | "---\n", 287 | "\n", 288 | "## 11.2 網路\n", 289 | "[回目錄](#HOME)" 290 | ] 291 | } 292 | ], 293 | "metadata": { 294 | "kernelspec": { 295 | "display_name": "Python [Root]", 296 | "language": "python", 297 | "name": "Python [Root]" 298 | }, 299 | "language_info": { 300 | "codemirror_mode": { 301 | "name": "ipython", 302 | "version": 3 303 | }, 304 | "file_extension": ".py", 305 | "mimetype": "text/x-python", 306 | "name": "python", 307 | "nbconvert_exporter": "python", 308 | "pygments_lexer": "ipython3", 309 | "version": "3.5.2" 310 | } 311 | }, 312 | "nbformat": 4, 313 | "nbformat_minor": 0 314 | } 315 | -------------------------------------------------------------------------------- /CHAPTER 2 Numbers, Strings,and Variables.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "\n", 8 | "# CHAPTER 2 Numbers, Strings,and Variables\n", 9 | "## Python的基本元素:數字,字串和變量\n", 10 | "\n", 11 | "* [2.1 變數 名稱 物件](#Variables_Names_Objects)\n", 12 | "* [2.2 數字](#Numbers)\n", 13 | "* [2.3 字串](#Strings)\n", 14 | "\n", 15 | "\n", 16 | "Python內建的型態有\n", 17 | "* 布林值 Boolean (True 、 False)\n", 18 | "* 整數 Integer\n", 19 | "* 浮點數 Float (可用科學記號表示法 ex. 1.0e3 = 1000.0)\n", 20 | "* 字串 String (字元組成的陣列)" 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "metadata": {}, 26 | "source": [ 27 | "------\n", 28 | "\n", 29 | "## 2.1 變數 名稱 物件\n", 30 | "[回目錄](#HOME)\n" 31 | ] 32 | }, 33 | { 34 | "cell_type": "markdown", 35 | "metadata": {}, 36 | "source": [ 37 | "Python為物件導向作為設計,所有的數據皆為Objcet,詳細的物件導向觀念可參考wiki中的介紹或是書中的介紹。 \n", 38 | "其中要特別注意所謂的針對某個特定物件型別內建method上的使用, \n", 39 | "例如string型別內建upper函數,可以把文字轉成大寫,則要使用上的方法為__string.upper()__, \n", 40 | "若是一個一般的內建method或是使用者自行建立的function, \n", 41 | "例如__len()__,則使用上的方法為 __len('abc')__, \n", 42 | "所以在學習Python時,需要清楚了解此function是針對某個型別的內建還是一般狀況。 \n", 43 | "\n", 44 | "其中要注意的是Python為強型別(Strongly typed),也就是說在執行 '1' + 2,會出現TypeError,並不會出現3或是'12'的結果,所以進行不同型別之間的處理可以使用 int('1') + 2 = 3或是 '1' + str(2) = '12'來作為處理。\n", 45 | "\n", 46 | "跟大多數語言一樣,再給定變數數值是使用 '=' 來賦予值,在Python中變數不用宣告,並且還有一個特性為,變數在記憶體位置中僅僅像是標籤一般,對某個記憶體位置做貼標籤功能,在變數改變內容時,記憶體內的值不會改變,而是變數標籤貼到其他記憶體位置上。因此Python不用宣告變數型別,故可以改變變數內的型別,所以可以使用_type(變數)_做為檢測變數現在的型別。\n", 47 | "\n", 48 | "變數的命名不外乎就是只能大小寫英文字母、 數字與底線(_),且不能以數字開頭,相關保留關鍵字如下,請勿作為變數名稱使用。\n", 49 | "\n", 50 | "\n", 51 | "![Alt text](http://i.imgur.com/vS3VxFe.png \"保留關鍵字\")" 52 | ] 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "metadata": {}, 57 | "source": [ 58 | "------\n", 59 | "\n", 60 | "## 2.2 數字\n", 61 | "[回目錄](#HOME)\n", 62 | "\n", 63 | "基本運算符號如下\n", 64 | "\n", 65 | "|符號|解釋|用法|\n", 66 | "|--|--|--|\n", 67 | "|+|加法|2 + 3 = 5|\n", 68 | "|-|減法|2 - 3 = -1|\n", 69 | "|\\*|乘法|2 * 3 = 6|\n", 70 | "|/|浮點數除法|3 / 2 = 1.5|\n", 71 | "|//|整數除法 (商數)|3 // 2 = 1|\n", 72 | "|%|餘數|3 % 2 = 1|\n", 73 | "|\\*\\*|次方|2 \\*\\* 3 = 8|\n", 74 | "\n", 75 | "\n", 76 | "對於正整數的操作,比較要注意的為0不可以放置在數字前端,如 a = 05 會出現SyntaxError。 \n", 77 | "於整數使用'/'除法上也會得到浮點數結果,並不需要特別轉換成浮點數再做除法運算。\n", 78 | "\n", 79 | "其餘運算規則與用法詳細請看書本介紹(ex. a = a + 1可以寫成 a += 1 等等) \n", 80 | "數字型別轉換可以用__int()__,裡面不允許有非數字出現,浮點數會無條件捨去,其中python允許使用__int(98.7) = 98__,但__int('98.7')__則會出現錯誤,這點要多加小心。\n", 81 | "\n", 82 | "最為重要的一點為Python3之後沒有溢位問題,意旨儲存整數大小無上限,取決於自身記憶體限制。\n", 83 | "\n", 84 | "轉換成浮點數可以使用__float()__。" 85 | ] 86 | }, 87 | { 88 | "cell_type": "markdown", 89 | "metadata": {}, 90 | "source": [ 91 | "------\n", 92 | "\n", 93 | "## 2.3 字串\n", 94 | "[回目錄](#HOME)\n", 95 | "\n", 96 | "Python3支援Unicode!!!! 表示可以顯示中文等等,檔案編碼方式記得選擇Unicode \n", 97 | "使用單或雙引號皆可以創建字串,若要在字串中包含單雙引號只要 \n", 98 | "用相反的作為外框 \n", 99 | "使用跳脫字元\\' \\\" \n", 100 | "連續使用三次即可(單,雙引號都可以)\n", 101 | "\n", 102 | "三個單引號'''還可以用再多行字串的建立,一般常用於多行註解上使用。 \n", 103 | "在使用print()指令時,會自動將跳脫字元轉換成正確的顯示方式(ex. \\n轉換成跳行等等) \n", 104 | "並且會在變數之間插入一空白\n", 105 | "\n", 106 | "```Python\n", 107 | "print('a','b','c') # 'a' 'b' 'c'\n", 108 | "```\n", 109 | "\n", 110 | "可以使用__str()__將其餘類別轉換成字串型態。\n", 111 | "\n", 112 | "字串相連接時可以使用 + 號或是直接把兩字串擺在前後即可。( print('a'+'b') print('a''b') 都可以得到 'ab'的結果 ) \n", 113 | "使用\\*可以快速建立重複字串。\n", 114 | "\n", 115 | "```Python\n", 116 | "print('a' * 5) # 'aaaaa'\n", 117 | "```" 118 | ] 119 | }, 120 | { 121 | "cell_type": "code", 122 | "execution_count": 1, 123 | "metadata": { 124 | "collapsed": false 125 | }, 126 | "outputs": [ 127 | { 128 | "name": "stdout", 129 | "output_type": "stream", 130 | "text": [ 131 | "b\n", 132 | "d\n" 133 | ] 134 | } 135 | ], 136 | "source": [ 137 | "#前述提到字串為字元的陣列,故可以使用[ ]來提取特定位置之字元,(相關的容器介紹在CH3)\n", 138 | "\n", 139 | "a = 'bcd' \n", 140 | "print(a[0]) #'b' \n", 141 | "print(a[-1]) #'d'\n", 142 | "\n", 143 | "#index從0開始,-1為最後一個字元" 144 | ] 145 | }, 146 | { 147 | "cell_type": "markdown", 148 | "metadata": {}, 149 | "source": [ 150 | "更多的提取方法如下\n", 151 | "\n", 152 | "|用法|說明|\n", 153 | "|--|--|\n", 154 | "|[ : ]|提取全部|\n", 155 | "|[start : ]|提取 start 至結束|\n", 156 | "|[ : end]|提取開頭到 end - 1|\n", 157 | "|[start : end]|提取 start 至 end - 1|\n", 158 | "|[start : end : step]|提取 start 至 end - 1,間隔為 step (step為負的時則從右邊開始,start與end需反過來擺放)|\n" 159 | ] 160 | }, 161 | { 162 | "cell_type": "code", 163 | "execution_count": 2, 164 | "metadata": { 165 | "collapsed": false 166 | }, 167 | "outputs": [ 168 | { 169 | "name": "stdout", 170 | "output_type": "stream", 171 | "text": [ 172 | "edcba\n", 173 | "dcb\n" 174 | ] 175 | } 176 | ], 177 | "source": [ 178 | "a = 'abcde'\n", 179 | "print(a[::-1]) #'edcba' 可以變成反序排列\n", 180 | "print(a[-2:0:-1]) #'dcb'" 181 | ] 182 | }, 183 | { 184 | "cell_type": "markdown", 185 | "metadata": {}, 186 | "source": [ 187 | "其中變數內的字串是不能替換內容(因為容器為類似TUPLES的型態,CH3會說明),\n", 188 | "若要替換內容,則可以使用重組或是 __string.replace()__" 189 | ] 190 | }, 191 | { 192 | "cell_type": "code", 193 | "execution_count": 3, 194 | "metadata": { 195 | "collapsed": false 196 | }, 197 | "outputs": [ 198 | { 199 | "name": "stdout", 200 | "output_type": "stream", 201 | "text": [ 202 | "Penny\n", 203 | "Penny\n" 204 | ] 205 | } 206 | ], 207 | "source": [ 208 | "name = 'Henny'\n", 209 | "#name[0] = 'P' #錯誤!!!!!!\n", 210 | "a = name.replace('H', 'P') #'Penny'\n", 211 | "print(a)\n", 212 | "print('P' + name[1:]) #'Penny'" 213 | ] 214 | }, 215 | { 216 | "cell_type": "markdown", 217 | "metadata": {}, 218 | "source": [ 219 | "__len()__ 可以獲得長度" 220 | ] 221 | }, 222 | { 223 | "cell_type": "code", 224 | "execution_count": 4, 225 | "metadata": { 226 | "collapsed": false 227 | }, 228 | "outputs": [ 229 | { 230 | "data": { 231 | "text/plain": [ 232 | "3" 233 | ] 234 | }, 235 | "execution_count": 4, 236 | "metadata": {}, 237 | "output_type": "execute_result" 238 | } 239 | ], 240 | "source": [ 241 | "a = 'abc'\n", 242 | "len(a)" 243 | ] 244 | }, 245 | { 246 | "cell_type": "markdown", 247 | "metadata": {}, 248 | "source": [ 249 | "__string.split()__可以分割字串成list,( )內可以指定符號,預設會切割\\n(換行) 、 \\t(tab)與空格三種" 250 | ] 251 | }, 252 | { 253 | "cell_type": "code", 254 | "execution_count": 5, 255 | "metadata": { 256 | "collapsed": false 257 | }, 258 | "outputs": [ 259 | { 260 | "name": "stdout", 261 | "output_type": "stream", 262 | "text": [ 263 | "['get gloves', 'get mask', 'give cat vitamins', 'call ambulance']\n", 264 | "['get', 'gloves,get', 'mask,give', 'cat', 'vitamins,call', 'ambulance']\n" 265 | ] 266 | } 267 | ], 268 | "source": [ 269 | "todos = 'get gloves,get mask,give cat vitamins,call ambulance'\n", 270 | "print(todos.split(','))\n", 271 | "print(todos.split())" 272 | ] 273 | }, 274 | { 275 | "cell_type": "markdown", 276 | "metadata": {}, 277 | "source": [ 278 | "__'符號'.join()__可以合併list成字串" 279 | ] 280 | }, 281 | { 282 | "cell_type": "code", 283 | "execution_count": 6, 284 | "metadata": { 285 | "collapsed": false 286 | }, 287 | "outputs": [ 288 | { 289 | "data": { 290 | "text/plain": [ 291 | "'Yeti, Bigfoot, Loch Ness Monster'" 292 | ] 293 | }, 294 | "execution_count": 6, 295 | "metadata": {}, 296 | "output_type": "execute_result" 297 | } 298 | ], 299 | "source": [ 300 | "crypto_list = ['Yeti', 'Bigfoot', 'Loch Ness Monster']\n", 301 | "', '.join(crypto_list)" 302 | ] 303 | }, 304 | { 305 | "cell_type": "markdown", 306 | "metadata": {}, 307 | "source": [ 308 | "__string.startswith()__ 與 __string.endswith()__ 分別可以檢查開頭與結束字串是否為特定字串,回傳__True__或__False__" 309 | ] 310 | }, 311 | { 312 | "cell_type": "code", 313 | "execution_count": 7, 314 | "metadata": { 315 | "collapsed": false 316 | }, 317 | "outputs": [ 318 | { 319 | "name": "stdout", 320 | "output_type": "stream", 321 | "text": [ 322 | "True\n", 323 | "False\n" 324 | ] 325 | } 326 | ], 327 | "source": [ 328 | "poem = 'abcdef'\n", 329 | "print(poem.startswith('ab'))\n", 330 | "print(poem.endswith('eef'))" 331 | ] 332 | }, 333 | { 334 | "cell_type": "markdown", 335 | "metadata": {}, 336 | "source": [ 337 | "__string.find()__ 與 __string.rfind()__ 可以查詢第一次與最後一次出現搜尋字串的index,__string.count()__可以查詢字串出現次數" 338 | ] 339 | }, 340 | { 341 | "cell_type": "code", 342 | "execution_count": 8, 343 | "metadata": { 344 | "collapsed": false 345 | }, 346 | "outputs": [ 347 | { 348 | "name": "stdout", 349 | "output_type": "stream", 350 | "text": [ 351 | "1\n", 352 | "6\n", 353 | "2\n" 354 | ] 355 | } 356 | ], 357 | "source": [ 358 | "poem = 'abcdefbcd'\n", 359 | "print(poem.find('bc'))\n", 360 | "print(poem.rfind('bc'))\n", 361 | "print(poem.count('bc'))" 362 | ] 363 | }, 364 | { 365 | "cell_type": "markdown", 366 | "metadata": {}, 367 | "source": [ 368 | "__string.isalnum()__可以查詢字串中是否都是字母或數字,回傳__True__或__False__" 369 | ] 370 | }, 371 | { 372 | "cell_type": "code", 373 | "execution_count": 9, 374 | "metadata": { 375 | "collapsed": false 376 | }, 377 | "outputs": [ 378 | { 379 | "data": { 380 | "text/plain": [ 381 | "False" 382 | ] 383 | }, 384 | "execution_count": 9, 385 | "metadata": {}, 386 | "output_type": "execute_result" 387 | } 388 | ], 389 | "source": [ 390 | "poem = 'abc@def'\n", 391 | "poem.isalnum()" 392 | ] 393 | }, 394 | { 395 | "cell_type": "code", 396 | "execution_count": 10, 397 | "metadata": { 398 | "collapsed": false 399 | }, 400 | "outputs": [ 401 | { 402 | "name": "stdout", 403 | "output_type": "stream", 404 | "text": [ 405 | "a duck goes into a bar\n", 406 | "A duck goes into a bar...\n", 407 | "A Duck Goes Into A Bar...\n", 408 | "A DUCK GOES INTO A BAR...\n", 409 | "a duck goes into a bar...\n", 410 | "A DUCK GOES INTO A BAR...\n", 411 | " a duck goes into a bar... \n", 412 | "a duck goes into a bar... \n", 413 | " a duck goes into a bar...\n", 414 | "a marmoset goes into a bar...\n", 415 | "a famous duck goes into a famous bar...\n" 416 | ] 417 | } 418 | ], 419 | "source": [ 420 | "#其餘還有一些方便的string內建function可以使用\n", 421 | "\n", 422 | "setup = 'a duck goes into a bar...'\n", 423 | "print(setup.strip('.')) #刪除結尾特定符號 'a duck goes into a bar'\n", 424 | "print(setup.capitalize()) #字串第一個字元大寫 'A duck goes into a bar...'\n", 425 | "print(setup.title()) #每個單字開頭大寫 'A Duck Goes Into A Bar...'\n", 426 | "print(setup.upper()) #全部大寫 'A DUCK GOES INTO A BAR...'\n", 427 | "print(setup.lower()) #全部小寫 'a duck goes into a bar...'\n", 428 | "print(setup.swapcase()) #大小寫交換 'a DUCK GOES INTO A BAR...'\n", 429 | "print(setup.center(30)) #將字串中心移動至30個字元的中間 ' a duck goes into a bar... '\n", 430 | "print(setup.ljust(30)) #左對齊 'a duck goes into a bar... '\n", 431 | "print(setup.rjust(30)) #右對齊 ' a duck goes into a bar...'\n", 432 | "print(setup.replace('duck', 'marmoset')) #'a marmoset goes into a bar...'\n", 433 | "print(setup.replace('a ', 'a famous ', 100)) #只替換前100個'a '" 434 | ] 435 | } 436 | ], 437 | "metadata": { 438 | "anaconda-cloud": {}, 439 | "kernelspec": { 440 | "display_name": "Python [Root]", 441 | "language": "python", 442 | "name": "Python [Root]" 443 | }, 444 | "language_info": { 445 | "codemirror_mode": { 446 | "name": "ipython", 447 | "version": 3 448 | }, 449 | "file_extension": ".py", 450 | "mimetype": "text/x-python", 451 | "name": "python", 452 | "nbconvert_exporter": "python", 453 | "pygments_lexer": "ipython3", 454 | "version": "3.5.2" 455 | } 456 | }, 457 | "nbformat": 4, 458 | "nbformat_minor": 0 459 | } 460 | -------------------------------------------------------------------------------- /CHAPTER 3 Py Filling Lists, Tuples, Dictionaries and Sets.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "\n", 8 | "# CHAPTER 3 Py Filling: Lists, Tuples, Dictionaries, and Sets\n", 9 | "## Python容器:串列、Tuples、字典與集合\n", 10 | "\n", 11 | "* [3.1 串列(list)與Tuples](#Lists_Tuples)\n", 12 | "* [3.2 串列(list)型態](#Lists)\n", 13 | "* [3.3 Tuples型態](#Tuples)\n", 14 | "* [3.4 字典(Dictionarie)型態](#Dictionaries)\n", 15 | "* [3.5 集合(set)型態](#Sets)\n", 16 | "* [3.6 比較型態差別](#CompareDataStructures)\n", 17 | "* [3.7 建立大型結構](#MakeBiggerDataStructures)" 18 | ] 19 | }, 20 | { 21 | "cell_type": "markdown", 22 | "metadata": {}, 23 | "source": [ 24 | "------\n", 25 | "\n", 26 | "## 3.1 串列(list)與Tuples\n", 27 | "[回目錄](#HOME)\n", 28 | "\n", 29 | "兩者差異在於,List可以改變其內容,增減長度 or 替換等等皆可以 \n", 30 | "Tuples一旦賦予值之後,就不能再修改。 \n", 31 | "以效能和記憶體使用量來說,Tuples皆較佳" 32 | ] 33 | }, 34 | { 35 | "cell_type": "markdown", 36 | "metadata": {}, 37 | "source": [ 38 | "------\n", 39 | "\n", 40 | "## 3.2 串列(list)型態\n", 41 | "[回目錄](#HOME)\n", 42 | "\n", 43 | "List可以使用 **[]** 或是 **list()** 來創建空的,或是直接加入值進去,使用逗號區分即可。內容可以重複出現,且具有順序性。" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 1, 49 | "metadata": { 50 | "collapsed": false 51 | }, 52 | "outputs": [ 53 | { 54 | "name": "stdout", 55 | "output_type": "stream", 56 | "text": [ 57 | "[]\n", 58 | "['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']\n", 59 | "['emu', 'ostrich', 'cassowary']\n", 60 | "['Graham', 'John', 'Terry', 'Terry', 'Michael']\n" 61 | ] 62 | } 63 | ], 64 | "source": [ 65 | "empty_list = []\n", 66 | "weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']\n", 67 | "big_birds = ['emu', 'ostrich', 'cassowary']\n", 68 | "first_names = ['Graham', 'John', 'Terry', 'Terry', 'Michael']\n", 69 | "\n", 70 | "print(empty_list)\n", 71 | "print(weekdays)\n", 72 | "print(big_birds)\n", 73 | "print(first_names)" 74 | ] 75 | }, 76 | { 77 | "cell_type": "markdown", 78 | "metadata": {}, 79 | "source": [ 80 | "可以使用 **list()** 來作為轉換其他型別至List,或是前面2.3小節提到的字串__split()__函數" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": 2, 86 | "metadata": { 87 | "collapsed": false 88 | }, 89 | "outputs": [ 90 | { 91 | "name": "stdout", 92 | "output_type": "stream", 93 | "text": [ 94 | "['c', 'a', 't']\n", 95 | "['ready', 'fire', 'aim']\n", 96 | "['1', '6', '1952']\n" 97 | ] 98 | } 99 | ], 100 | "source": [ 101 | "print(list('cat'))\n", 102 | "\n", 103 | "a_tuple = ('ready', 'fire', 'aim')\n", 104 | "print(list(a_tuple))\n", 105 | "\n", 106 | "birthday = '1/6/1952'\n", 107 | "print((birthday.split('/')))" 108 | ] 109 | }, 110 | { 111 | "cell_type": "markdown", 112 | "metadata": {}, 113 | "source": [ 114 | "提取內容時跟字串一樣使用[], \n", 115 | "**index** 從0開始,-1為最後一個, \n", 116 | "**index** 數值的範圍請務必在總長度內,不然會出現IndexError。也可以將其修改替換內容。 \n", 117 | "提取多個以上也如同字串中的用法 __[start : end : step]__,注意這邊只會提取到index為end - 1" 118 | ] 119 | }, 120 | { 121 | "cell_type": "code", 122 | "execution_count": 3, 123 | "metadata": { 124 | "collapsed": false 125 | }, 126 | "outputs": [ 127 | { 128 | "name": "stdout", 129 | "output_type": "stream", 130 | "text": [ 131 | "a\n", 132 | "b\n", 133 | "d\n", 134 | "c\n", 135 | "['QQ', 'b']\n", 136 | "[]\n", 137 | "['QQ', 'c']\n" 138 | ] 139 | } 140 | ], 141 | "source": [ 142 | "XD = ['a', 'b', 'c', 'd']\n", 143 | "print(XD[0])\n", 144 | "print(XD[1])\n", 145 | "print(XD[-1])\n", 146 | "print(XD[-2])\n", 147 | "\n", 148 | "XD[0] = 'QQ'\n", 149 | "\n", 150 | "print(XD[0:2])\n", 151 | "print(XD[2:-2])\n", 152 | "print(XD[::2])" 153 | ] 154 | }, 155 | { 156 | "cell_type": "markdown", 157 | "metadata": {}, 158 | "source": [ 159 | "List裡面可以包含不同類型的物件,當然也包括List" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": 4, 165 | "metadata": { 166 | "collapsed": false 167 | }, 168 | "outputs": [ 169 | { 170 | "name": "stdout", 171 | "output_type": "stream", 172 | "text": [ 173 | "['a', 'b', 'c']\n", 174 | "b\n" 175 | ] 176 | } 177 | ], 178 | "source": [ 179 | "XD = [['a', 'b', 'c'],['d', 'e', 'f'],['g', 'h', 'i']]\n", 180 | "print(XD[0])\n", 181 | "print(XD[0][1])" 182 | ] 183 | }, 184 | { 185 | "cell_type": "markdown", 186 | "metadata": {}, 187 | "source": [ 188 | "可以使用List的內建函數append()來向後面添加元素\n", 189 | "\n", 190 | "|語法|效果|\n", 191 | "|--|--|\n", 192 | "|**list.extend()**或 **+=** |合併list|\n", 193 | "|**list.insert()**|在指定位置插入元素,如果位置超過最大長度則放在最後面,故不會飛到很遠去或出錯。|\n", 194 | "|**del Object** |用來刪除某個位置的元素,剩餘元素會自動往前補填補|\n", 195 | "|**list.remove()**|用來移除指定元素|\n", 196 | "|**list.pop()**|為類似剪出的效果,可以將指定位置的元素剪出來,預設index為 -1|\n", 197 | "|**list.index()**|找查指定元素第一次出現的index|\n", 198 | "|**in Object** |判斷指定元素是否存在|\n", 199 | "|**list.count()**|計算指定元素出現次數|\n" 200 | ] 201 | }, 202 | { 203 | "cell_type": "code", 204 | "execution_count": 5, 205 | "metadata": { 206 | "collapsed": false 207 | }, 208 | "outputs": [ 209 | { 210 | "name": "stdout", 211 | "output_type": "stream", 212 | "text": [ 213 | "['a', 'b'] ['e', 'f']\n", 214 | "['a', 'b', 'QQ~']\n", 215 | "['a', 'b', 'QQ~', 'e', 'f']\n", 216 | "['a', 'b', 'QQ~', 'e', 'f', 'e', 'f']\n", 217 | "['a', 'b', 'QQ~', 'e', 'f', 'e', 'f', ['e', 'f']]\n", 218 | "['a', 'b', 'c', 'QQ~', 'e', 'f', 'e', 'f', ['e', 'f']]\n", 219 | "['a', 'b', 'c', 'QQ~', 'e', 'f', 'e', 'f', ['e', 'f'], 'ker']\n", 220 | "['a', 'b', 'c', 'QQ~', 'e', 'f', 'e', 'f', 'ker']\n", 221 | "['a', 'b', 'c', 'QQ~', 'f', 'e', 'f', 'ker']\n", 222 | "['a', 'b', 'c', 'f', 'e', 'f', 'ker'] QQ~\n", 223 | "3\n", 224 | "True\n", 225 | "2\n" 226 | ] 227 | } 228 | ], 229 | "source": [ 230 | "XD = ['a', 'b']\n", 231 | "XD2 = ['e', 'f']\n", 232 | "print(XD, XD2)\n", 233 | "\n", 234 | "XD.append('QQ~')\n", 235 | "print(XD)\n", 236 | "\n", 237 | "XD.extend(XD2)\n", 238 | "print(XD)\n", 239 | "\n", 240 | "XD += XD2\n", 241 | "print(XD)\n", 242 | "\n", 243 | "XD.append(XD2)\n", 244 | "print(XD)\n", 245 | "\n", 246 | "XD.insert(2, 'c')\n", 247 | "print(XD)\n", 248 | "\n", 249 | "XD.insert(500, 'ker')\n", 250 | "print(XD)\n", 251 | "\n", 252 | "del XD[8]\n", 253 | "print(XD)\n", 254 | "\n", 255 | "XD.remove('e')\n", 256 | "print(XD)\n", 257 | "\n", 258 | "QQ = XD.pop(3)\n", 259 | "print(XD, QQ)\n", 260 | "\n", 261 | "print(XD.index('f'))\n", 262 | "print('ker' in XD)\n", 263 | "print(XD.count('f'))" 264 | ] 265 | }, 266 | { 267 | "cell_type": "markdown", 268 | "metadata": {}, 269 | "source": [ 270 | "前面2.3節提到的__string.join()__,可以用來組裝List成為字串, \n", 271 | "書中提到這邊的用法看起來有點彆扭,如果改成__List.join(', ')__會更直覺, \n", 272 | "但是當初設計的理念就是join的方法是在字串的型態中, \n", 273 | "這樣後面我想要針對List、Tuples或是字串使用字串做組裝,就只要一種方法就好, \n", 274 | "不用針對每種型態都去設計一個相同的方法來做使用,如下面範例所示範。 \n", 275 | "__string.join()__ 與 __string.split()__兩個為相對應的用法!!!" 276 | ] 277 | }, 278 | { 279 | "cell_type": "code", 280 | "execution_count": 6, 281 | "metadata": { 282 | "collapsed": false 283 | }, 284 | "outputs": [ 285 | { 286 | "name": "stdout", 287 | "output_type": "stream", 288 | "text": [ 289 | "a, b, c\n", 290 | "a, b, c\n", 291 | "a, b, c\n", 292 | "['a', 'b', 'c']\n" 293 | ] 294 | } 295 | ], 296 | "source": [ 297 | "print(', '.join(['a', 'b', 'c']))\n", 298 | "print(', '.join('abc'))\n", 299 | "print(', '.join(('a', 'b', 'c')))\n", 300 | "print('a, b, c'.split(', '))" 301 | ] 302 | }, 303 | { 304 | "cell_type": "markdown", 305 | "metadata": {}, 306 | "source": [ 307 | "* **list.sort()**為list排序方法,\n", 308 | "* **sorted()**為通用的排序函數\n", 309 | "其中的差異在於__sort()__會直接改變輸入的list,__sorted()__則會另外回傳一個排序好的物件,\n", 310 | "\n", 311 | "**len()**可以獲得list的長度。" 312 | ] 313 | }, 314 | { 315 | "cell_type": "code", 316 | "execution_count": 7, 317 | "metadata": { 318 | "collapsed": false 319 | }, 320 | "outputs": [ 321 | { 322 | "name": "stdout", 323 | "output_type": "stream", 324 | "text": [ 325 | "['a', 'b', 'c']\n", 326 | "['a', 'b', 'c']\n", 327 | "3\n" 328 | ] 329 | } 330 | ], 331 | "source": [ 332 | "L = ['b', 'c', 'a']\n", 333 | "L.sort()\n", 334 | "print(L)\n", 335 | "\n", 336 | "t = ['b', 'c', 'a']\n", 337 | "a = sorted(t)\n", 338 | "print(a)\n", 339 | "\n", 340 | "print(len(a))" 341 | ] 342 | }, 343 | { 344 | "cell_type": "markdown", 345 | "metadata": {}, 346 | "source": [ 347 | "使用 '=' 設定變數則會是傳址,等同於前面說的標籤概念,把兩張標籤貼在同一個物件上(number or srting 除外) \n", 348 | "這樣當我改變了物件後,則物件上所有的標籤所指到的值都會跟著改變, \n", 349 | "若要改成傳值的話可以使用**copy()** 、 **list.list()** 與 **list[:]** 來達到目的" 350 | ] 351 | }, 352 | { 353 | "cell_type": "code", 354 | "execution_count": 8, 355 | "metadata": { 356 | "collapsed": false 357 | }, 358 | "outputs": [ 359 | { 360 | "name": "stdout", 361 | "output_type": "stream", 362 | "text": [ 363 | "[4, 2, 3] [4, 2, 3]\n", 364 | "['surprises', 2, 3] ['surprises', 2, 3] [4, 2, 3] [4, 2, 3] [4, 2, 3]\n" 365 | ] 366 | } 367 | ], 368 | "source": [ 369 | "a = [1, 2, 3]\n", 370 | "b = a\n", 371 | "\n", 372 | "a[0] = 4\n", 373 | "print(a, b)\n", 374 | "\n", 375 | "c = a.copy()\n", 376 | "d = list(a)\n", 377 | "e = a[:]\n", 378 | "a[0] = 'surprises'\n", 379 | "print(a, b, c, d, e)" 380 | ] 381 | }, 382 | { 383 | "cell_type": "markdown", 384 | "metadata": {}, 385 | "source": [ 386 | "------\n", 387 | "\n", 388 | "## 3.3 Tuples型態\n", 389 | "[回目錄](#HOME)\n", 390 | "\n", 391 | "也是一個List差別只在不能做修改,一旦给定後,無法再進行增加 刪除 修改等操作,所以可以當作一個常數的List\n", 392 | "\n", 393 | "創建時空的時使用(),一個以上時可以省略,但是一個時最後一個逗號不可以省略。" 394 | ] 395 | }, 396 | { 397 | "cell_type": "code", 398 | "execution_count": 9, 399 | "metadata": { 400 | "collapsed": false 401 | }, 402 | "outputs": [ 403 | { 404 | "name": "stdout", 405 | "output_type": "stream", 406 | "text": [ 407 | "()\n", 408 | "('tem',)\n", 409 | "('tem1', 'tem2', 'tem3')\n", 410 | "tem1 tem2 tem3\n" 411 | ] 412 | } 413 | ], 414 | "source": [ 415 | "a = () #空Tuples\n", 416 | "b = 'tem', #b:(tem,) 括弧可以省略,但是一個的時候逗號不能省略\n", 417 | "c = 'tem1', 'tem2', 'tem3' #('tem1', 'tem2', 'tem3')\n", 418 | "d, e, f = c #d:'tem1', e:'tem2', f:'tem3'\n", 419 | "\n", 420 | "print(a)\n", 421 | "print(b)\n", 422 | "print(c)\n", 423 | "print(d, e, f)" 424 | ] 425 | }, 426 | { 427 | "cell_type": "markdown", 428 | "metadata": {}, 429 | "source": [ 430 | "結合以上的用法可以有一個超級方便直覺的用法,任意交換變數間的值。 \n", 431 | "(在等號右邊的東西會先形成一個Tuples,再分配給前面的變數。)" 432 | ] 433 | }, 434 | { 435 | "cell_type": "code", 436 | "execution_count": 10, 437 | "metadata": { 438 | "collapsed": false 439 | }, 440 | "outputs": [ 441 | { 442 | "name": "stdout", 443 | "output_type": "stream", 444 | "text": [ 445 | "3 1 2\n" 446 | ] 447 | } 448 | ], 449 | "source": [ 450 | "a = '1'\n", 451 | "b = '2'\n", 452 | "c = '3'\n", 453 | "b, c, a = a, b, c\n", 454 | "\n", 455 | "print(a, b, c)" 456 | ] 457 | }, 458 | { 459 | "cell_type": "markdown", 460 | "metadata": {}, 461 | "source": [ 462 | "既然他不能修改等等的那相對於List一定也有其他好處\n", 463 | "\n", 464 | "* 空間較小\n", 465 | "* 不會不小心修改到值\n", 466 | "* 可以當作dictionary的key值 (後一小節有說明)\n", 467 | "* 命名Tuples,可以做為物件的替代 (第六章會說明)\n", 468 | "* 函數的傳遞是以Tuples形式傳遞\n" 469 | ] 470 | }, 471 | { 472 | "cell_type": "markdown", 473 | "metadata": {}, 474 | "source": [ 475 | "------\n", 476 | "\n", 477 | "## 3.4 字典型態\n", 478 | "[回目錄](#HOME)\n", 479 | "\n", 480 | "為一種沒有順序的容器,其使用的是大括弧{},裏頭包含鍵值與值(**key : value**) \n", 481 | "可以使用**dict()**來轉換期他型態至dictionary\n", 482 | "\n", 483 | "|語法|效果|\n", 484 | "|--|--|\n", 485 | "|**D.update()** | 合併不同dictionary|\n", 486 | "|**del Object** | 刪除某項|\n", 487 | "|**in Object** | 是否存在裡面(key)|\n", 488 | "|**D.keys() ** | 獲得所有key值|\n", 489 | "|**D.values()** | 獲得所有value值|\n", 490 | "|**D.items() ** | 獲得全部的key: value( Tuples型態 )|\n", 491 | "|**D.copy() ** | 複製一個dictionary|\n", 492 | "|**D.clear() ** | 清除所有內容|" 493 | ] 494 | }, 495 | { 496 | "cell_type": "code", 497 | "execution_count": 11, 498 | "metadata": { 499 | "collapsed": false 500 | }, 501 | "outputs": [ 502 | { 503 | "name": "stdout", 504 | "output_type": "stream", 505 | "text": [ 506 | "{'a': 'v', 'b': 'w'} {'d': 'y', 'c': 'x'}\n", 507 | "{'e': 'f', 'a': 'b', 'c': 'd'} {'e': 'f', 'a': 'b', 'c': 'd'} {'e': 'f', 'a': 'b', 'c': 'd'}\n", 508 | "{'e': 'f', 'a': 'b', 'c': 'd'} {'e': 'f', 'a': 'b', 'c': 'd'}\n", 509 | "============分隔線============\n", 510 | "x\n", 511 | "z\n", 512 | "{'d': 'y', 'a': 'v', 'c': 'z', 'b': 'w'}\n", 513 | "{'a': 'v', 'c': 'z', 'b': 'w'}\n", 514 | "True\n", 515 | "============分隔線============\n", 516 | "dict_keys(['a', 'c', 'b'])\n", 517 | "dict_values(['v', 'z', 'w'])\n", 518 | "[('a', 'v'), ('c', 'z'), ('b', 'w')]\n", 519 | "============分隔線============\n", 520 | "{'a': 'n', 'c': 'z', 'b': 'w'} {'a': 'n', 'c': 'z', 'b': 'w'}\n", 521 | "{'a': 'n', 'c': 'z', 'b': 'w'} {'a': 'm', 'c': 'z', 'b': 'w'}\n", 522 | "{}\n" 523 | ] 524 | } 525 | ], 526 | "source": [ 527 | "dic = { 'a':'v','b':'w', } #最後一個逗號可以省略\n", 528 | "dic_ = { 'd':'y','c':'x' } #最後一個逗號可以省略\n", 529 | "print(dic, dic_)\n", 530 | "\n", 531 | "\n", 532 | "lol1 = [ ['a', 'b'], ['c', 'd'], ['e', 'f'] ]\n", 533 | "lol2 = [ ('a', 'b'), ('c', 'd'), ('e', 'f') ]\n", 534 | "lol3 = ( ['a', 'b'], ['c', 'd'], ['e', 'f'] )\n", 535 | "print(dict(lol1), dict(lol2), dict(lol3))\n", 536 | "\n", 537 | "\n", 538 | "tos1 = [ 'ab', 'cd', 'ef' ]\n", 539 | "tos2 = ( 'ab', 'cd', 'ef' )\n", 540 | "print(dict(tos1), dict(tos2))\n", 541 | "\n", 542 | "print('============分隔線============')\n", 543 | "print(dic_['c'])\n", 544 | "dic_['c'] = 'z'\n", 545 | "print(dic_['c'])\n", 546 | "\n", 547 | "dic.update(dic_)\n", 548 | "print(dic)\n", 549 | "\n", 550 | "\n", 551 | "del dic['d']\n", 552 | "print(dic)\n", 553 | "\n", 554 | "print('a' in dic)\n", 555 | "\n", 556 | "print('============分隔線============')\n", 557 | "print(dic.keys()) # dict_keys(['a', 'b', 'c'])\n", 558 | "print(dic.values()) # ['v', 'w', 'x']\n", 559 | "print(list(dic.items())) # [('a', 'v'), ('b', 'w'), ('c', 'x')]\n", 560 | "\n", 561 | "print('============分隔線============')\n", 562 | "dic_new = dic\n", 563 | "dic_new['a'] = 'n'\n", 564 | "print(dic, dic_new)\n", 565 | "\n", 566 | "dic_cp = dic.copy()\n", 567 | "dic_cp['a'] = 'm'\n", 568 | "print(dic, dic_cp)\n", 569 | "\n", 570 | "dic.clear() \n", 571 | "print(dic)" 572 | ] 573 | }, 574 | { 575 | "cell_type": "markdown", 576 | "metadata": {}, 577 | "source": [ 578 | "------\n", 579 | "\n", 580 | "## 3.5 集合型態\n", 581 | "[回目錄](#HOME)\n", 582 | "\n", 583 | "集合就好比沒有value的dictionary,一樣沒有順序,使用大括弧**{}**。 \n", 584 | "空白集合為**set()**,也合相當於False。 \n", 585 | "使用**set()**可以轉換其他型態至集合,dictionary轉換至set只會保留key值。 \n", 586 | "**in**也可以檢查特定元素是否存在其中。\n", 587 | "\n", 588 | "![Alt text](http://i.imgur.com/gXChbwA.png \"集合示意圖\")" 589 | ] 590 | }, 591 | { 592 | "cell_type": "code", 593 | "execution_count": 12, 594 | "metadata": { 595 | "collapsed": false 596 | }, 597 | "outputs": [ 598 | { 599 | "name": "stdout", 600 | "output_type": "stream", 601 | "text": [ 602 | "set() {8, 0, 2, 4, 6}\n", 603 | "{'r', 'e', 'l', 't', 's'}\n", 604 | "{'D', 'M', 'P', 'A'}\n", 605 | "{'U', 'Echoes', 'Atom'}\n", 606 | "{'orange', 'apple'}\n" 607 | ] 608 | } 609 | ], 610 | "source": [ 611 | "empty_set = set()\n", 612 | "even_numbers = {0, 2, 4, 6, 8}\n", 613 | "print(empty_set, even_numbers)\n", 614 | "\n", 615 | "\n", 616 | "print(set( 'letters' ))\n", 617 | "print(set( ['D', 'A', 'P', 'M'] ))\n", 618 | "print(set( ('U', 'Echoes', 'Atom') ))\n", 619 | "print(set( {'apple': 'red', 'orange': 'orange'} ))" 620 | ] 621 | }, 622 | { 623 | "cell_type": "markdown", 624 | "metadata": {}, 625 | "source": [ 626 | "------\n", 627 | "\n", 628 | "## 3.6 比較型態差別\n", 629 | "[回目錄](#HOME)\n", 630 | "\n", 631 | "比較不同容器之間的使用差別,請自己在看過一次書中介紹。" 632 | ] 633 | }, 634 | { 635 | "cell_type": "markdown", 636 | "metadata": {}, 637 | "source": [ 638 | "------\n", 639 | "\n", 640 | "## 3.7 建立大型結構\n", 641 | "[回目錄](#HOME)\n", 642 | "\n", 643 | "容器中可以包含不同型態的元素,也可以包含其他的容器物件。" 644 | ] 645 | }, 646 | { 647 | "cell_type": "code", 648 | "execution_count": 13, 649 | "metadata": { 650 | "collapsed": false 651 | }, 652 | "outputs": [ 653 | { 654 | "name": "stdout", 655 | "output_type": "stream", 656 | "text": [ 657 | "{'Pythons': ['Chapman', 'Cleese', 'Gilliam', 'Jones', 'Palin'], 'Marxes': ['Groucho', 'Chico', 'Harpo'], 'Stooges': ['Moe', 'Curly', 'Larry']}\n", 658 | "['Groucho', 'Chico', 'Harpo']\n", 659 | "Chico\n" 660 | ] 661 | } 662 | ], 663 | "source": [ 664 | "dict_of_lists = {'Stooges': ['Moe', 'Curly', 'Larry'],\n", 665 | " 'Marxes': ['Groucho', 'Chico', 'Harpo'],\n", 666 | " 'Pythons': ['Chapman', 'Cleese', 'Gilliam', 'Jones', 'Palin']}\n", 667 | "\n", 668 | "print(dict_of_lists)\n", 669 | "print(dict_of_lists['Marxes'])\n", 670 | "print(dict_of_lists['Marxes'][1])" 671 | ] 672 | } 673 | ], 674 | "metadata": { 675 | "kernelspec": { 676 | "display_name": "Python [Root]", 677 | "language": "python", 678 | "name": "Python [Root]" 679 | }, 680 | "language_info": { 681 | "codemirror_mode": { 682 | "name": "ipython", 683 | "version": 3 684 | }, 685 | "file_extension": ".py", 686 | "mimetype": "text/x-python", 687 | "name": "python", 688 | "nbconvert_exporter": "python", 689 | "pygments_lexer": "ipython3", 690 | "version": "3.5.2" 691 | } 692 | }, 693 | "nbformat": 4, 694 | "nbformat_minor": 0 695 | } 696 | -------------------------------------------------------------------------------- /CHAPTER 5 Py Boxes- Modules, Packages, and Programs.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": false 7 | }, 8 | "source": [ 9 | "\n", 10 | "# CHAPTER 5 Py Boxes: Modules, Packages, and Programs\n", 11 | "## Python模組、包和程序\n", 12 | "\n", 13 | "* [5.1 獨立程式 Standalone Programs](#Standalone)\n", 14 | "* [5.2 命令列參數 Command-Line Arguments](#Command-Line)\n", 15 | "* [5.3 模組與匯入 Modules and the import Statement](#Modules_import)\n", 16 | "* [5.4 打包 Packages](#Packages)\n", 17 | "* [5.5 標準函數庫 The Python Standard Library](#Standard_Library)\n", 18 | "* [5.6 獲取其他程式 More Batteries: Get Other Python Code](#Get_Other)\n", 19 | "\n", 20 | "\n", 21 | "程式若要寫得漂亮,乾淨,清楚,則模組化是很重要的一個技術基礎\n", 22 | "方可把大型的程式拆解能若干小程式,方便管理,維護,重複使用" 23 | ] 24 | }, 25 | { 26 | "cell_type": "markdown", 27 | "metadata": {}, 28 | "source": [ 29 | "---\n", 30 | "\n", 31 | "## 5.1 Standalone Programs 獨立程式\n", 32 | "[回目錄](#HOME)\n", 33 | "\n", 34 | "可以把編寫完的py檔於命令提示字元執行\n", 35 | "\n", 36 | "```\n", 37 | ">>> python test1.py\n", 38 | "```" 39 | ] 40 | }, 41 | { 42 | "cell_type": "markdown", 43 | "metadata": {}, 44 | "source": [ 45 | "---\n", 46 | "\n", 47 | "## 5.2 Command-Line Arguments 命令列參數\n", 48 | "[回目錄](#HOME)\n", 49 | "\n", 50 | "\n", 51 | "sys為命令列函數,import後即可在命令列直接輸入參數。\n", 52 | "\n", 53 | "```python\n", 54 | "import sys\n", 55 | "print('Program arguments:',sys.argv[1])\n", 56 | "```\n", 57 | "test2.py tra la \n", 58 | "```\n", 59 | ">>> python test2.py\n", 60 | "Program arguments: ['test2.py']\n", 61 | ">>> python la\n", 62 | "Program arguments: ['test2.py', 'tra', 'la', 'la']\n", 63 | "```" 64 | ] 65 | }, 66 | { 67 | "cell_type": "markdown", 68 | "metadata": {}, 69 | "source": [ 70 | "---\n", 71 | "\n", 72 | "## 5.3 Modules and the import Statement 模組與匯入\n", 73 | "[回目錄](#HOME)\n", 74 | "\n", 75 | "將程式拆成若干模組(Modules)後,即可使用import匯入,並且可以用as重新取自己想要的名稱\n", 76 | "\n", 77 | "程式預設會先搜尋主程式相同路徑的資料夾,若無則搜尋安裝目錄的\\Lib資料夾\n", 78 | "\n", 79 | "### import 函式庫( as 別名)\n", 80 | "為匯入全部的function\n", 81 | "\n", 82 | "### from 函式庫 import function( as 別名)\n", 83 | "為匯入函式庫中的某隻特定function" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": null, 89 | "metadata": { 90 | "collapsed": false 91 | }, 92 | "outputs": [], 93 | "source": [ 94 | "# weatherman.py\n", 95 | "# 主程式\n", 96 | "# P.S.這裡抓不到,因為沒有準備實體函式在資料中\n", 97 | "\n", 98 | "import report #把 report.py 在相同目錄資料夾中,即可對其呼叫匯入\n", 99 | "description = report.get_description() #使用report中的get_description函數\n", 100 | "\n", 101 | "from get_description import report as get\n", 102 | "\n", 103 | "print(\"Today's weather:\", description)" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": null, 109 | "metadata": { 110 | "collapsed": true 111 | }, 112 | "outputs": [], 113 | "source": [ 114 | "# report.py\n", 115 | "# 函式庫\n", 116 | "\n", 117 | "def get_description():\n", 118 | " \"\"\"Return random weather, just like the pros\"\"\"\n", 119 | " from random import choice #匯入標準函式庫 random 中的 choice函數\n", 120 | " possibilities = ['rain', 'snow', 'sleet', 'fog', 'sun', 'who knows']\n", 121 | " return choice(possibilities)" 122 | ] 123 | }, 124 | { 125 | "cell_type": "markdown", 126 | "metadata": {}, 127 | "source": [ 128 | "---\n", 129 | "\n", 130 | "## 5.4 Packages 打包\n", 131 | "[回目錄](#HOME)\n", 132 | "\n", 133 | "__非常非常非常好用的功能!!!!__\n", 134 | "\n", 135 | "前述用法是把function拆開再同一層目錄,但是如果函式庫相當的多,在管理上會變得複雜 \n", 136 | "所以可以將函式庫利用資料夾作為管理,簡易示意圖如下\n", 137 | "\n", 138 | "![Alt text](http://i.imgur.com/pCwG1Ze.png)\n", 139 | "\n", 140 | "主程式為 __weather.py__ \n", 141 | "modules為__daily.py__ 與 __weekly.py__ \n", 142 | "__init.py__檔則為一個空的檔案,目的為使python將sources視為一個函式庫用\n", 143 | "\n", 144 | "\n", 145 | "主程式[__weather.py__]即可使用import匯入sources資料夾中的函示\n", 146 | "```python\n", 147 | "#----------------------------------------------------weather.py\n", 148 | "from sources import daily, weekly\n", 149 | "\n", 150 | "print(\"Daily forecast:\", daily.forecast())\n", 151 | "print(\"Weekly forecast:\")\n", 152 | "for number, outlook in enumerate(weekly.forecast(), 1):\n", 153 | " print(number, outlook)\n", 154 | "\n", 155 | "#----------------------------------------------------daily.py:\n", 156 | "def forecast():\n", 157 | " 'fake daily forecast'\n", 158 | " return 'like yesterday'\n", 159 | "\n", 160 | "#----------------------------------------------------weekly.py\n", 161 | "def forecast():\n", 162 | " \"\"\"Fake weekly forecast\"\"\"\n", 163 | " return ['snow', 'more snow', 'sleet','freezing rain', 'rain', 'fog', 'hail']\n", 164 | "```" 165 | ] 166 | }, 167 | { 168 | "cell_type": "markdown", 169 | "metadata": {}, 170 | "source": [ 171 | "---\n", 172 | "\n", 173 | "## 5.5 The Python Standard Library 標準函數庫\n", 174 | "[回目錄](#HOME)\n", 175 | "\n", 176 | "介紹一些Python內建的標準函式庫, \n", 177 | "PYTHON把一些較不常用的function拆解為標準函式庫,使得python更輕巧\n", 178 | "\n", 179 | "詳細介紹請看書本,這邊不多說" 180 | ] 181 | }, 182 | { 183 | "cell_type": "markdown", 184 | "metadata": {}, 185 | "source": [ 186 | "---\n", 187 | "\n", 188 | "## 5.6 More Batteries: Get Other Python Code 獲取其他程式\n", 189 | "[回目錄](#HOME)\n", 190 | "\n", 191 | "如果表準函式庫中沒有想到的,可以上到其他網站去尋找,書中介紹了這三個網站\n", 192 | "\n", 193 | "* PyPi( http://pypi.python.org )\n", 194 | "* github( http://github.com/Python )\n", 195 | "* readthedocs( https://readthedocs.org/ )\n", 196 | "* Python Extension Packages,windows環境超級大補帖 ( http://www.lfd.uci.edu/~gohlke/pythonlibs/ )\n" 197 | ] 198 | } 199 | ], 200 | "metadata": { 201 | "anaconda-cloud": {}, 202 | "kernelspec": { 203 | "display_name": "Python [Root]", 204 | "language": "python", 205 | "name": "Python [Root]" 206 | }, 207 | "language_info": { 208 | "codemirror_mode": { 209 | "name": "ipython", 210 | "version": 3 211 | }, 212 | "file_extension": ".py", 213 | "mimetype": "text/x-python", 214 | "name": "python", 215 | "nbconvert_exporter": "python", 216 | "pygments_lexer": "ipython3", 217 | "version": "3.5.2" 218 | } 219 | }, 220 | "nbformat": 4, 221 | "nbformat_minor": 0 222 | } 223 | -------------------------------------------------------------------------------- /CHAPTER 6 Oh Oh- Objects and Classes.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": false 7 | }, 8 | "source": [ 9 | "\n", 10 | "# CHAPTER 6 Oh Oh: Objects and Classes\n", 11 | "## 物件與類別\n", 12 | "\n", 13 | "* [6.1 什麼是物件](#Objects)\n", 14 | "* [6.2 使用class定義類別](#Class)\n", 15 | "* [6.3 繼承](#Inheritance)\n", 16 | "* [6.4 覆蓋方法](#Override)\n", 17 | "* [6.5 添加新方法](#Add)\n", 18 | "* [6.6 使用super得到父類別支援](#super)\n", 19 | "* [6.7 self](#self)\n", 20 | "* [6.8 設置與呼叫特性的屬性](#Attribute)\n", 21 | "* [6.9 使用名稱重整保持私有性](#Privacy)\n", 22 | "* [6.10 方法的類別](#Types)\n", 23 | "* [6.11 鴨子類別](#Duck)\n", 24 | "* [6.12 特殊方法](#Special)\n", 25 | "* [6.13 組合](#Composition)\n", 26 | "* [6.14 類別與對象v.s.模組](#ClassesModules)\n", 27 | "\n", 28 | "\n", 29 | "\n", 30 | "除了python內建的對象,我們也可以通過class來建立屬於自己的類別供使用" 31 | ] 32 | }, 33 | { 34 | "cell_type": "markdown", 35 | "metadata": {}, 36 | "source": [ 37 | "---\n", 38 | "\n", 39 | "## 6.1 什麼是物件\n", 40 | "[回目錄](#HOME)\t\t\t\t\t \n", 41 | "\n", 42 | "\n", 43 | "第二章節提到,python裡面所有的東西都是物件(_objects_),連同一個整數也是一種物件,python的語法設計可以巧妙的隱藏諸多細節\n", 44 | "\n", 45 | "本章節將會介紹到自訂新的物件以及修改現有的物件。\n", 46 | "\n", 47 | "物件包含屬性(__attribute__)與方法(__methods__), \n", 48 | "例如整數5和7都是整數物件,都包含了基本的+-\\*/方法, \n", 49 | "'cat' 和 'duck'都是字串物件,都包含了 __capitalize()__ 和 __replace()__ 兩種方法\n", 50 | "\n", 51 | "所以當你要創造一個新的物件時,就必須先定義一個類別,用它來清楚規範其類別可以創造出來的物件有什麼樣的屬性(__attribute__)與方法(__methods__)\n", 52 | "\n", 53 | "物件像名詞,方法就像個動詞。對象代表一個獨立的事物,方法用來定義她如何與其他事物相互作用 \n", 54 | "與模組不同的是,你可以同時創建多個同類別的物件,他們之間的屬性值可能各有不同,對象像是個結構,包含著數據。\n" 55 | ] 56 | }, 57 | { 58 | "cell_type": "markdown", 59 | "metadata": {}, 60 | "source": [ 61 | "---\n", 62 | "\n", 63 | "## 6.2 使用class定義類別\n", 64 | "[回目錄](#HOME)\t\t\t \n", 65 | "\t \n", 66 | "我們可以通過class來定義自己的類別,就可以創造出新的物件\n" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": 1, 72 | "metadata": { 73 | "collapsed": false 74 | }, 75 | "outputs": [ 76 | { 77 | "name": "stdout", 78 | "output_type": "stream", 79 | "text": [ 80 | "Elmer Fudd\n", 81 | "QQ@WW.tw\n", 82 | "I am Elmer Fudd!!!\n", 83 | "Hsuky\n", 84 | "XDD@WW.tw\n" 85 | ] 86 | } 87 | ], 88 | "source": [ 89 | "# 自定義一個Person()\n", 90 | "# __init__為定義屬性部分\n", 91 | "# self為物件自己\n", 92 | "\n", 93 | "class Person():\n", 94 | " def __init__(self, name, email):\n", 95 | " self.name = name\n", 96 | " self.email = email\n", 97 | " \n", 98 | " def XDD(self, tem):\n", 99 | " return 'I am ' + self.name + tem\n", 100 | "\n", 101 | "hunter = Person('Elmer Fudd', \"QQ@WW.tw\")\n", 102 | "\n", 103 | "Husky = Person('Hsuky', \"XDD@WW.tw\")\n", 104 | "\n", 105 | "print(hunter.name)\n", 106 | "print(hunter.email)\n", 107 | "\n", 108 | "print(hunter.XDD('!!!'))\n", 109 | "\n", 110 | "print(Husky.name)\n", 111 | "print(Husky.email)" 112 | ] 113 | }, 114 | { 115 | "cell_type": "markdown", 116 | "metadata": {}, 117 | "source": [ 118 | "---\n", 119 | "\n", 120 | "## 6.3 繼承\n", 121 | "[回目錄](#HOME)\t\t\t\t\t\t\t \n", 122 | "\n", 123 | "在編寫類別時,如果發現已經有前人開發過,那就可以不用整段複製,可以採用繼承的方法取得他的屬性與方法 \n", 124 | "並且補充自己會用到的功能,一方面可以減少去改既有的類別辛苦,也可省去複製貼上的功" 125 | ] 126 | }, 127 | { 128 | "cell_type": "code", 129 | "execution_count": 2, 130 | "metadata": { 131 | "collapsed": false 132 | }, 133 | "outputs": [ 134 | { 135 | "name": "stdout", 136 | "output_type": "stream", 137 | "text": [ 138 | "add: 4\n", 139 | "add: 6\n" 140 | ] 141 | } 142 | ], 143 | "source": [ 144 | "class math():\n", 145 | " def add(self, a, b):\n", 146 | " print(\"add:\", a + b)\n", 147 | "\n", 148 | "class mean(math):\n", 149 | " pass\n", 150 | " \n", 151 | "ab = mean()\n", 152 | "ab.add(1, 3)\n", 153 | "\n", 154 | "ac = math()\n", 155 | "ac.add(1,5)" 156 | ] 157 | }, 158 | { 159 | "cell_type": "markdown", 160 | "metadata": {}, 161 | "source": [ 162 | "---\n", 163 | "\n", 164 | "## 6.4 覆蓋方法\n", 165 | "[回目錄](#HOME) \n", 166 | "\n", 167 | "當然我們也可以覆蓋掉原有的方法" 168 | ] 169 | }, 170 | { 171 | "cell_type": "code", 172 | "execution_count": 3, 173 | "metadata": { 174 | "collapsed": false 175 | }, 176 | "outputs": [ 177 | { 178 | "name": "stdout", 179 | "output_type": "stream", 180 | "text": [ 181 | "add: 7\n" 182 | ] 183 | } 184 | ], 185 | "source": [ 186 | "class math():\n", 187 | " def add(self, a, b):\n", 188 | " print(\"add:\", a + b)\n", 189 | "\n", 190 | "class mean(math):\n", 191 | " def add(self, a, b):\n", 192 | " print(\"add:\", a + b + b)\n", 193 | " \n", 194 | "ab = mean()\n", 195 | "ab.add(1, 3)" 196 | ] 197 | }, 198 | { 199 | "cell_type": "markdown", 200 | "metadata": {}, 201 | "source": [ 202 | "---\n", 203 | "\n", 204 | "## 6.5 添加新方法\n", 205 | "[回目錄](#HOME) \n", 206 | "\n", 207 | "前面的都是複製與修改接著我們也可以在新的類別中加入新的方法" 208 | ] 209 | }, 210 | { 211 | "cell_type": "code", 212 | "execution_count": 4, 213 | "metadata": { 214 | "collapsed": false 215 | }, 216 | "outputs": [ 217 | { 218 | "name": "stdout", 219 | "output_type": "stream", 220 | "text": [ 221 | "add: 4\n", 222 | "add: -2\n", 223 | "add: 6\n" 224 | ] 225 | } 226 | ], 227 | "source": [ 228 | "class math():\n", 229 | " def add(self, a, b):\n", 230 | " print(\"add:\", a + b)\n", 231 | "\n", 232 | "class mean(math):\n", 233 | " def less(self, a, b):\n", 234 | " print(\"add:\", a - b)\n", 235 | " \n", 236 | "ab = mean()\n", 237 | "ab.add(1, 3)\n", 238 | "ab.less(1, 3)\n", 239 | "\n", 240 | "ac = math()\n", 241 | "ac.add(1, 5)\n" 242 | ] 243 | }, 244 | { 245 | "cell_type": "markdown", 246 | "metadata": {}, 247 | "source": [ 248 | "---\n", 249 | "\n", 250 | "## 6.6 使用super得到父類別支援\n", 251 | "[回目錄](#HOME) \n", 252 | "\n", 253 | "那如果們我要修改屬性部分( *\\_\\_int\\_\\_* ),除了直接重寫一個蓋掉以外還有__super()__方法可以用來擴充既有的屬性,這樣才有達到既成的目的" 254 | ] 255 | }, 256 | { 257 | "cell_type": "code", 258 | "execution_count": 5, 259 | "metadata": { 260 | "collapsed": false 261 | }, 262 | "outputs": [ 263 | { 264 | "name": "stdout", 265 | "output_type": "stream", 266 | "text": [ 267 | "Elmer Fudd\n", 268 | "QQ@CC.tw\n", 269 | "=============\n", 270 | "Elmer Fudd\n", 271 | "QQ@CC.tw\n", 272 | "2016/05/07\n" 273 | ] 274 | } 275 | ], 276 | "source": [ 277 | "class Person():\n", 278 | " def __init__(self, name, email):\n", 279 | " self.name = name\n", 280 | " self.email = email\n", 281 | " \n", 282 | "class Person_day(Person):\n", 283 | " def __init__(self, name, email, birthday):\n", 284 | " super().__init__(name, email)\n", 285 | " self.birthday = birthday\n", 286 | " \n", 287 | " \n", 288 | "hunter = Person('Elmer Fudd', 'QQ@CC.tw')\n", 289 | "husky = Person_day('Elmer Fudd', 'QQ@CC.tw', '2016/05/07')\n", 290 | "\n", 291 | "print(hunter.name)\n", 292 | "print(hunter.email)\n", 293 | "print('=============')\n", 294 | "print(husky.name)\n", 295 | "print(husky.email)\n", 296 | "print(husky.birthday)\n" 297 | ] 298 | }, 299 | { 300 | "cell_type": "markdown", 301 | "metadata": {}, 302 | "source": [ 303 | "---\n", 304 | "\n", 305 | "## 6.7 self\n", 306 | "[回目錄](#HOME) \n", 307 | "\n", 308 | "在定義屬性時常常會看到__self__,__self__指的就是被創造出來的物件它自身。 \n", 309 | "所以在__\\_\\_int\\_\\_(self, name)__的參數部分,實際在__self__並不用傳入參數。\n", 310 | "\n", 311 | "```python\n", 312 | "class Person():\n", 313 | " def __init__(self, name, email):\n", 314 | " self.name = name\n", 315 | " self.email = email\n", 316 | "\n", 317 | "XDD = Person('QQ', 'QQ@gmail.com') #不須傳入self參數\n", 318 | "```" 319 | ] 320 | }, 321 | { 322 | "cell_type": "markdown", 323 | "metadata": {}, 324 | "source": [ 325 | "---\n", 326 | "\n", 327 | "## 6.8 設置與呼叫特性的屬性\n", 328 | "[回目錄](#HOME) \n", 329 | "\n", 330 | "在其他語言中,可以設置__getter__ 和 __setter__來確保私有屬性的讀寫,但是在python一切都是公開的, \n", 331 | "可以透過__property()__來達到python風格的寫法,即可將屬性值藏起來,不用透過呼叫每個__getter()__和__setter()__來達到改變斯有變數 \n", 332 | "\n", 333 | "若沒有給定setter函數,則無法透過__property()__來改變屬性質,當然前提是在別人不知道實在儲存變數的屬性名稱是什麼" 334 | ] 335 | }, 336 | { 337 | "cell_type": "code", 338 | "execution_count": 6, 339 | "metadata": { 340 | "collapsed": false 341 | }, 342 | "outputs": [ 343 | { 344 | "name": "stdout", 345 | "output_type": "stream", 346 | "text": [ 347 | "提取名稱時,則呼叫get函數\n", 348 | "---使用get函數---\n", 349 | "Howard!!\n", 350 | "\n", 351 | "設定名稱時,則呼叫set函數\n", 352 | "---使用set函數---\n", 353 | "nname被改成Daffy\n", 354 | "---使用get函數---\n", 355 | "Daffy??!!\n", 356 | "\n", 357 | "當然也可以透過原始的set_name()與get_name()進行修改私有屬性\n", 358 | "---使用get函數---\n", 359 | "Daffy??!!\n", 360 | "---使用set函數---\n", 361 | "---使用get函數---\n", 362 | "Daffyyyy??!!\n" 363 | ] 364 | } 365 | ], 366 | "source": [ 367 | "class Duck():\n", 368 | " def __init__(self, input_name):\n", 369 | " self.hidden_name = input_name\n", 370 | " \n", 371 | " #取的 name 的函數\n", 372 | " def get_name(self):\n", 373 | " print('---使用get函數---')\n", 374 | " return self.hidden_name + '!!'\n", 375 | " \n", 376 | " #設定 name 的函數\n", 377 | " def set_name(self, input_name):\n", 378 | " print('---使用set函數---')\n", 379 | " self.hidden_name = input_name + '??'\n", 380 | " \n", 381 | " #使用property(get,set)來包裝,讓使用上更方便\n", 382 | " name = property(get_name, set_name)\n", 383 | "\n", 384 | "#宣告物件為Duck類別,並給定name,從頭到尾都沒有直接抄作hidden_name來改變屬性值\n", 385 | "fowl = Duck('Howard')\n", 386 | "print('提取名稱時,則呼叫get函數')\n", 387 | "print(fowl.name)\n", 388 | "\n", 389 | "print('\\n設定名稱時,則呼叫set函數')\n", 390 | "fowl.name = 'Daffy'\n", 391 | "print('nname被改成Daffy')\n", 392 | "print(fowl.name)\n", 393 | "\n", 394 | "print('\\n當然也可以透過原始的set_name()與get_name()進行修改私有屬性')\n", 395 | "print(fowl.get_name())\n", 396 | "fowl.set_name('Daffyyyy')\n", 397 | "print(fowl.get_name())" 398 | ] 399 | }, 400 | { 401 | "cell_type": "code", 402 | "execution_count": 7, 403 | "metadata": { 404 | "collapsed": false 405 | }, 406 | "outputs": [ 407 | { 408 | "name": "stdout", 409 | "output_type": "stream", 410 | "text": [ 411 | "提取名稱時,則呼叫get函數\n", 412 | "---使用get函數---\n", 413 | "Howard\n", 414 | "\n", 415 | "設定名稱時,則呼叫set函數\n", 416 | "---使用set函數---\n", 417 | "nname被改成Daffy\n", 418 | "---使用get函數---\n", 419 | "Daffy\n" 420 | ] 421 | } 422 | ], 423 | "source": [ 424 | "#當然可以透過裝飾器,來寫得更漂亮!!!\n", 425 | "\n", 426 | "class Duck():\n", 427 | " def __init__(self, input_name):\n", 428 | " self.hidden_name = input_name\n", 429 | " \n", 430 | " @property\n", 431 | " def name(self):\n", 432 | " print('---使用get函數---')\n", 433 | " return self.hidden_name\n", 434 | "\n", 435 | " @name.setter\n", 436 | " def name(self, input_name):\n", 437 | " print('---使用set函數---')\n", 438 | " self.hidden_name = input_name\n", 439 | " \n", 440 | "#宣告物件為Duck類別,並給定name\n", 441 | "fowl = Duck('Howard')\n", 442 | "\n", 443 | "print('提取名稱時,則呼叫get函數')\n", 444 | "print(fowl.name)\n", 445 | "\n", 446 | "print('\\n設定名稱時,則呼叫set函數')\n", 447 | "fowl.name = 'Daffy'\n", 448 | "print('nname被改成Daffy')\n", 449 | "print(fowl.name)" 450 | ] 451 | }, 452 | { 453 | "cell_type": "markdown", 454 | "metadata": {}, 455 | "source": [ 456 | "---\n", 457 | "\n", 458 | "## 6.9 使用名稱重整保持私有性\n", 459 | "[回目錄](#HOME) \n", 460 | "\n", 461 | "前面的用法如果被知道實際儲存屬性的名稱為什麼,也是可以對其修改\n", 462 | "所以可以透過名稱重整來把實際儲存屬性的名稱改寫\n", 463 | "\n", 464 | "在屬性名稱前面加上( \\_\\_ )來重整名稱,雖然不能完全的防止修改私有屬性,但可以透過有效的方法降低有意或無意的修改" 465 | ] 466 | }, 467 | { 468 | "cell_type": "code", 469 | "execution_count": 8, 470 | "metadata": { 471 | "collapsed": false 472 | }, 473 | "outputs": [ 474 | { 475 | "name": "stdout", 476 | "output_type": "stream", 477 | "text": [ 478 | "---使用get函數---\n", 479 | "Howard\n", 480 | "---使用set函數---\n", 481 | "---使用get函數---\n", 482 | "Donald\n" 483 | ] 484 | } 485 | ], 486 | "source": [ 487 | "class Duck():\n", 488 | " def __init__(self, input_name):\n", 489 | " self.__name = input_name\n", 490 | " \n", 491 | " @property\n", 492 | " def name(self):\n", 493 | " print('---使用get函數---')\n", 494 | " return self.__name\n", 495 | " \n", 496 | " @name.setter\n", 497 | " def name(self, input_name):\n", 498 | " print('---使用set函數---')\n", 499 | " self.__name = input_name\n", 500 | "\n", 501 | " \n", 502 | " \n", 503 | "fowl = Duck('Howard')\n", 504 | "print(fowl.name)\n", 505 | "fowl.name = 'Donald'\n", 506 | "print(fowl.name)\n", 507 | "\n", 508 | "#fowl.__name #直接修改會錯誤\n", 509 | "#fowl._Duck__name #重整完的名稱" 510 | ] 511 | }, 512 | { 513 | "cell_type": "markdown", 514 | "metadata": {}, 515 | "source": [ 516 | "---\n", 517 | "\n", 518 | "## 6.10 方法的類別\n", 519 | "[回目錄](#HOME) \n", 520 | "\n", 521 | "前述交的都是物件的方法,對於類別本身也是可以設定屬性以及方法 \n", 522 | "分別使用 __類別.屬性__ 以及 __@classmethod__\n", 523 | "\n", 524 | "在類別的方法中,呼叫自己使用 __cls__ 或是 **類別名稱** 皆可以\n", 525 | "\n", 526 | "還有一種 __@staticmethod__ 可以設定類別的函數,差異在於 \n", 527 | "* @staticmethod不需使用cls參數\n", 528 | "* @classmethod第一個參數需為cls參數\n", 529 | "\n", 530 | "在使用上來說,若__@staticmethod__要調用到這個類別的屬性只能直接用名稱來取得,而__@classmethod__因為有cls參數傳入,所以可以透過cls來調用類別函數\n" 531 | ] 532 | }, 533 | { 534 | "cell_type": "code", 535 | "execution_count": 9, 536 | "metadata": { 537 | "collapsed": false 538 | }, 539 | "outputs": [ 540 | { 541 | "name": "stdout", 542 | "output_type": "stream", 543 | "text": [ 544 | "A has 3 little objects.\n", 545 | "A has 3 little objects.\n", 546 | "This CoyoteWeapon has been brought to you by Acme\n" 547 | ] 548 | } 549 | ], 550 | "source": [ 551 | "class A():\n", 552 | " count = 0 #類別的屬性\n", 553 | " def __init__(self):\n", 554 | " A.count += 1 #修改類別的屬性\n", 555 | " \n", 556 | " def exclaim(self):\n", 557 | " print(\"I'm an A!\")\n", 558 | " \n", 559 | " @classmethod #類別的方法(methond)\n", 560 | " def kids(cls):\n", 561 | " print(\"A has\", cls.count, \"little objects.\")\n", 562 | " \n", 563 | " @classmethod #類別的方法(methond)\n", 564 | " def kids2(A):\n", 565 | " print(\"A has\", A.count, \"little objects.\")\n", 566 | "\n", 567 | "easy_a = A()\n", 568 | "breezy_a = A()\n", 569 | "wheezy_a = A()\n", 570 | "A.kids()\n", 571 | "A.kids2()\n", 572 | "\n", 573 | "\n", 574 | "class CoyoteWeapon():\n", 575 | " @staticmethod\n", 576 | " def commercial():\n", 577 | " print('This CoyoteWeapon has been brought to you by Acme')\n", 578 | " \n", 579 | "CoyoteWeapon.commercial()" 580 | ] 581 | }, 582 | { 583 | "cell_type": "markdown", 584 | "metadata": {}, 585 | "source": [ 586 | "---\n", 587 | "\n", 588 | "## 6.11 鴨子類別\n", 589 | "[回目錄](#HOME) \n", 590 | "\n", 591 | "在物件導向的語言中多態(polymorphism)的使用,可以讓我們更方便的調用物件的函數\n", 592 | "\n", 593 | "不用管物件本身的類別是什麼,只要擁有相同的方法就可以呼叫到\n", 594 | "\n", 595 | "\n", 596 | "鴨子一詞的由來為,如果能像鴨子一樣叫,像鴨子一樣走路,那他就是一隻鴨子。 \n", 597 | "所以我們不用太在意是什麼物件,只要他能夠有一樣的方法可以使用,那我們就可以安心的使用了" 598 | ] 599 | }, 600 | { 601 | "cell_type": "code", 602 | "execution_count": 10, 603 | "metadata": { 604 | "collapsed": false, 605 | "scrolled": true 606 | }, 607 | "outputs": [ 608 | { 609 | "name": "stdout", 610 | "output_type": "stream", 611 | "text": [ 612 | "Elmer Fudd says I'm hunting wabbits.\n", 613 | "Brook says Babble\n" 614 | ] 615 | } 616 | ], 617 | "source": [ 618 | "class Quote():\n", 619 | " def __init__(self, person, words):\n", 620 | " self.person = person\n", 621 | " self.words = words\n", 622 | " \n", 623 | " def who(self):\n", 624 | " return self.person\n", 625 | "\n", 626 | " def says(self):\n", 627 | " return self.words + '.'\n", 628 | " \n", 629 | "class BabblingBrook():\n", 630 | " def who(self):\n", 631 | " return 'Brook'\n", 632 | " \n", 633 | " def says(self):\n", 634 | " return 'Babble'\n", 635 | " \n", 636 | "hunter = Quote('Elmer Fudd', \"I'm hunting wabbits\")\n", 637 | "brook = BabblingBrook()\n", 638 | "\n", 639 | "#儘管兩者完全獨立沒有關係,但只要有相同名稱的函數就可以呼叫到\n", 640 | "def who_says(obj):\n", 641 | " print(obj.who(), 'says', obj.says())\n", 642 | " \n", 643 | "who_says(hunter)\n", 644 | "who_says(brook)" 645 | ] 646 | }, 647 | { 648 | "cell_type": "markdown", 649 | "metadata": {}, 650 | "source": [ 651 | "---\n", 652 | "\n", 653 | "## 6.12 特殊方法\n", 654 | "[回目錄](#HOME) \n", 655 | "\n", 656 | "在python中,存在一些特殊方法( special method )或者稱回( magic method ), \n", 657 | "這些方法為雙底線( **\\_\\_** )開頭與結束用法,前面介紹過的( **\\_\\_init\\_\\_** )就是一個特殊方法,他是用來對新物件初始化用\n", 658 | "\n", 659 | "假設我有一隻class裡面有個method可以用來判斷兩個字串的小寫是否相同\n", 660 | "\n", 661 | "```python\n", 662 | "#---------------採用一般方法寫法\n", 663 | "class Word():\n", 664 | " def __init__(self, text):\n", 665 | " self.text = text\n", 666 | " \n", 667 | " def equals(self, word2):\n", 668 | " return self.text.lower() == word2.text.lower()\n", 669 | "\n", 670 | "#創建三個單字物件\n", 671 | "first = Word('ha')\n", 672 | "second = Word('HA')\n", 673 | "third = Word('eh')\n", 674 | "\n", 675 | "#進行比較\n", 676 | "first.equals(second) #True\n", 677 | "first.equals(third) #False\n", 678 | "\n", 679 | "#---------------採用特殊方法寫法\n", 680 | "class Word():\n", 681 | " def __init__(self, text):\n", 682 | " self.text = text\n", 683 | " \n", 684 | " def __eq__(self, word2):\n", 685 | " return self.text.lower() == word2.text.lower()\n", 686 | "\n", 687 | "#創建三個單字物件\n", 688 | "first = Word('ha')\n", 689 | "second = Word('HA')\n", 690 | "third = Word('eh')\n", 691 | "\n", 692 | "#進行比較\n", 693 | "first == second #True\n", 694 | "first == third #False\n", 695 | "```\n", 696 | "\n", 697 | "是~不~是~漂亮許多啦!!!!\n", 698 | "\n", 699 | "一些常用的特殊用法整理如下\n", 700 | "\n", 701 | "\n", 702 | "### 比較用\n", 703 | "|方法名稱 | 使用 |\n", 704 | "|:------------------:|:---------------------:|\n", 705 | "|\\_\\_eq\\_\\_(self, other) | self == other |\n", 706 | "|\\_\\_ne\\_\\_(self, other) | self != other |\n", 707 | "|\\_\\_lt\\_\\_(self, other) | self < other |\n", 708 | "|\\_\\_gt\\_\\_(self, other) | self > other |\n", 709 | "|\\_\\_le\\_\\_(self, other) | self <= other |\n", 710 | "|\\_\\_ge\\_\\_(self, other) | self >= other |\n", 711 | "\n", 712 | "\n", 713 | "### 數學用\n", 714 | "|方法名 | 使用 |\n", 715 | "|:------------------:|:---------------------:|\n", 716 | "|\\_\\_add\\_\\_(self, other)|self + other |\n", 717 | "|\\_\\_sub\\_\\_(self, other)|self - other |\n", 718 | "|\\_\\_mul\\_\\_(self, other)|self * other |\n", 719 | "|\\_\\_floordiv\\_\\_(self, other)|self // other |\n", 720 | "|\\_\\_truediv\\_\\_(self, other)|self / other |\n", 721 | "|\\_\\_mod\\_\\_(self, other)|self % other |\n", 722 | "|\\_\\_pow\\_\\_(self, other)|self ** other |\n", 723 | "\n", 724 | "### 其他常用\n", 725 | "|方法名 | 使用 |\n", 726 | "|:------------------:|:---------------------:|\n", 727 | "|\\_\\_str\\_\\_(self)|str(self) |\n", 728 | "|\\_\\_repr\\_\\_(self)|repr(self) |\n", 729 | "|\\_\\_len\\_\\_(self)|len(self) |\n", 730 | "\n", 731 | "\n", 732 | "完整清單請看官方文件。\n", 733 | "https://docs.python.org/3/reference/datamodel.html#special-method-names" 734 | ] 735 | }, 736 | { 737 | "cell_type": "code", 738 | "execution_count": 11, 739 | "metadata": { 740 | "collapsed": false 741 | }, 742 | "outputs": [ 743 | { 744 | "name": "stdout", 745 | "output_type": "stream", 746 | "text": [ 747 | "hahaha!!\n", 748 | "20\n", 749 | "min:3,max:10\n", 750 | "min:3,max:10\n" 751 | ] 752 | } 753 | ], 754 | "source": [ 755 | "class Word():\n", 756 | " def __init__(self, text):\n", 757 | " self.text = text\n", 758 | " \n", 759 | " def __str__(self):\n", 760 | " return self.text + 'haha!!'\n", 761 | "\n", 762 | "class sqrtt():\n", 763 | " def __init__(self, num):\n", 764 | " self.num = num\n", 765 | " \n", 766 | " def __mul__(self, number):\n", 767 | " return self.num * number.num\n", 768 | " \n", 769 | "class minmax():\n", 770 | " def __init__(self, minn, maxx):\n", 771 | " self.minn = minn\n", 772 | " self.maxx = maxx\n", 773 | " \n", 774 | " def __str__(self):\n", 775 | " return 'min:' + str(self.minn) + ',max:'+ str(self.maxx)\n", 776 | " \n", 777 | "\n", 778 | "#創建三個單字物件\n", 779 | "first = Word('ha')\n", 780 | "\n", 781 | "print(first) #print必須為字串,所以程式自行使用str()轉換成字串\n", 782 | "\n", 783 | "XD = sqrtt(4)\n", 784 | "XDD = sqrtt(5)\n", 785 | "print( XD * XDD )\n", 786 | "\n", 787 | "AM = minmax(3, 10)\n", 788 | "print(AM)\n", 789 | "print('min:' + str(AM.minn) + ',max:'+ str(AM.maxx))" 790 | ] 791 | }, 792 | { 793 | "cell_type": "markdown", 794 | "metadata": {}, 795 | "source": [ 796 | "---\n", 797 | "\n", 798 | "## 6.13 組合\n", 799 | "[回目錄](#HOME) \n", 800 | "\n", 801 | "\n", 802 | "如果要新建的類別有相似的類別可以繼承的話就可以採用繼承來取得父類別的所有, \n", 803 | "但若兩個類別差異太大,或是沒有關係,我們就可以採用組合來合併這些類別\n", 804 | "\n", 805 | "例如,鴨子是鳥的一種,所以可以繼承鳥的類別, \n", 806 | "但是嘴巴和尾巴不是鴨子的一種,而是鴨子的組成。\n" 807 | ] 808 | }, 809 | { 810 | "cell_type": "code", 811 | "execution_count": 12, 812 | "metadata": { 813 | "collapsed": false 814 | }, 815 | "outputs": [ 816 | { 817 | "name": "stdout", 818 | "output_type": "stream", 819 | "text": [ 820 | "這隻鴨子有一個 紅色的 嘴巴,然後有 白色,15cm 長的尾巴\n" 821 | ] 822 | } 823 | ], 824 | "source": [ 825 | "\n", 826 | "class Bill():\n", 827 | " def __init__(self, description):\n", 828 | " self.description = description\n", 829 | " \n", 830 | "class Tail():\n", 831 | " def __init__(self, length):\n", 832 | " self.length = length\n", 833 | " \n", 834 | "\n", 835 | "class Duck():\n", 836 | " def __init__(self, bill, tail):\n", 837 | " self.bill = bill\n", 838 | " self.tail = tail\n", 839 | " def about(self):\n", 840 | " print('這隻鴨子有一個', bill.description, '嘴巴,然後有', tail.length, '長的尾巴')\n", 841 | "\n", 842 | " \n", 843 | "bill = Bill('紅色的')\n", 844 | "tail = Tail('白色,15cm')\n", 845 | "\n", 846 | "duck = Duck(bill, tail)\n", 847 | "duck.about()" 848 | ] 849 | }, 850 | { 851 | "cell_type": "markdown", 852 | "metadata": {}, 853 | "source": [ 854 | "---\n", 855 | "\n", 856 | "## 6.14 類別與對象v.s.模組\n", 857 | "[回目錄](#HOME)\n", 858 | "\n", 859 | "有一些方法可以幫助你決定是把你的代碼封裝到類裡還是模塊裡。\n", 860 | "* 當你需要許多具有相似行為(方法),但不同狀態(特性)的實例時,使用對象是最好的選擇。\n", 861 | "* 類支持繼承,但模塊不支持。\n", 862 | "* 如果你想要保證實例的唯一性,使用模塊是最好的選擇。不管模塊在程序中被引用多少次,始終只有一個實例被加載。 \n", 863 | "* 如果你有一系列包含多個值的變量,並且它們能作為參數傳入不同的函數,那麼最好將它們封裝到類裡面。舉個例子,你可能會使用以大小和顏色為鍵的字典代表一張\n", 864 | "彩色图片。你可以在程序中为每张图片创建不同的字典,并把它们作为参数传递给像規模()或者變換()之類的函數。但這麼做的話,一旦你想要添加其他的鍵或者函數會變得非常麻煩。為了保證統一性,應該定義一個圖片類,把大小和顏色作為特性,把規模()和變換()定義為方法。這麼一來,關於一張圖片的所有數據和可執行的操作都存儲在了統一的位置。\n", 865 | "* 用最簡單的方式解決問題。使用字典,列表和元組往往要比使用模塊更加簡單,簡潔且快速。而使用類則更為複雜。\n", 866 | "\n", 867 | "\n", 868 | "---\n", 869 | "### 命名Tuple(named tuple)\n", 870 | "\n", 871 | "可以用來創造可以用名稱訪問的Tuple子類\n", 872 | "\n", 873 | "跟Tuple一樣,不可被改變,但是可以透過替換來產生新的命名Tuple" 874 | ] 875 | }, 876 | { 877 | "cell_type": "code", 878 | "execution_count": 13, 879 | "metadata": { 880 | "collapsed": false 881 | }, 882 | "outputs": [ 883 | { 884 | "name": "stdout", 885 | "output_type": "stream", 886 | "text": [ 887 | "Duck(bill='wide orange', tail='long')\n", 888 | "wide orange\n", 889 | "long\n", 890 | "Duck(bill='wide orange', tail='long')\n", 891 | "Duck(bill='crushing', tail='magnificent')\n" 892 | ] 893 | } 894 | ], 895 | "source": [ 896 | "from collections import namedtuple #引入函式庫\n", 897 | "\n", 898 | "Duck = namedtuple('Duck', 'bill tail') #宣告為命名Tuple,並且有bill和tail兩種名稱\n", 899 | "duck = Duck('wide orange', 'long') #給值\n", 900 | "\n", 901 | "print(duck)\n", 902 | "print(duck.bill)\n", 903 | "print(duck.tail)\n", 904 | "\n", 905 | "parts = {'bill': 'wide orange', 'tail': 'long'} #使用dictionary給值\n", 906 | "duck2 = Duck(**parts)\n", 907 | "print(duck2)\n", 908 | "\n", 909 | "duck3 = duck2._replace(tail='magnificent', bill='crushing') #替換內容\n", 910 | "print(duck3)" 911 | ] 912 | } 913 | ], 914 | "metadata": { 915 | "kernelspec": { 916 | "display_name": "Python [Root]", 917 | "language": "python", 918 | "name": "Python [Root]" 919 | }, 920 | "language_info": { 921 | "codemirror_mode": { 922 | "name": "ipython", 923 | "version": 3 924 | }, 925 | "file_extension": ".py", 926 | "mimetype": "text/x-python", 927 | "name": "python", 928 | "nbconvert_exporter": "python", 929 | "pygments_lexer": "ipython3", 930 | "version": "3.5.2" 931 | } 932 | }, 933 | "nbformat": 4, 934 | "nbformat_minor": 0 935 | } 936 | -------------------------------------------------------------------------------- /CHAPTER 7 Mangle Data Like a Pro.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": false 7 | }, 8 | "source": [ 9 | "\n", 10 | "# CHAPTER 7 Mangle Data Like a Pro\n", 11 | "## 向高手一樣玩轉數據\n", 12 | "\n", 13 | "* [7.1.1 Unicode](#Unicode)\n", 14 | "* [7.1.2 格式化](#Format)\n", 15 | "* [7.1.3 正規表達式](#RegularExpressions)\n", 16 | "* [7.2.1 bytes and bytearray](#bytesbytearray)\n", 17 | "* [7.2.2 使用struct轉換二進位資料](#struct)\n", 18 | "* [7.2.3 其他二進位工具](#OtherTools)\n", 19 | "* [7.2.4 binascii函數](#binascii)\n", 20 | "* [7.2.5 位元運算](#BitOperators)\n" 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "metadata": {}, 26 | "source": [ 27 | "---\n", 28 | "\n", 29 | "## 7.1.1 Unicode\n", 30 | "[回目錄](#HOME)\n", 31 | "\n", 32 | "早期電腦發展時的所使用的ASCII只有128種,只能應付英文和數字以及一些基本的符號,所以發展出了Unicode來面對全世界所有的符號\n", 33 | "\n", 34 | "\\u 加上4碼16進位的數字表示Unicode 中的 256 個基本語言,前兩碼為類別,後兩碼為索引 \n", 35 | "\\U 加上8碼16進位的數字為表示超出上述範圍內的字符,最左一位須為0,\\N{name}用來指定字符名稱\n", 36 | "(完整清單 http://www.unicode.org/charts/charindex.html)\n", 37 | "\n", 38 | "python的unicodedata模組提供了下面兩個方向的轉換函數:\n", 39 | "\n", 40 | "* __lookup()__ - 接受不區分大小寫的標準名稱,返回一個Unicode的字符;\n", 41 | "* __name()__ - 接受一個的Unicode字符,返回大寫形式的名稱。" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 1, 47 | "metadata": { 48 | "collapsed": false, 49 | "scrolled": true 50 | }, 51 | "outputs": [ 52 | { 53 | "name": "stdout", 54 | "output_type": "stream", 55 | "text": [ 56 | "value=\"A\", name=\"LATIN CAPITAL LETTER A\", value2=\"A\"\n", 57 | "value=\"$\", name=\"DOLLAR SIGN\", value2=\"$\"\n", 58 | "value=\"¢\", name=\"CENT SIGN\", value2=\"¢\"\n", 59 | "value=\"€\", name=\"EURO SIGN\", value2=\"€\"\n", 60 | "value=\"☃\", name=\"SNOWMAN\", value2=\"☃\"\n", 61 | "café\n", 62 | "value=\"é\", name=\"LATIN SMALL LETTER E WITH ACUTE\", value2=\"é\"\n", 63 | "b'\\\\xe9'\n", 64 | "value=\"é\", name=\"LATIN SMALL LETTER E WITH ACUTE\", value2=\"é\"\n" 65 | ] 66 | } 67 | ], 68 | "source": [ 69 | "def unicode_test(value):\n", 70 | " import unicodedata\n", 71 | " name = unicodedata.name(value)\n", 72 | " value2 = unicodedata.lookup(name)\n", 73 | " print('value=\"%s\", name=\"%s\", value2=\"%s\"' % (value, name, value2))\n", 74 | " \n", 75 | "unicode_test('A')\n", 76 | "unicode_test('$')\n", 77 | "unicode_test('\\u00a2')\n", 78 | "unicode_test('\\u20ac')\n", 79 | "unicode_test('\\u2603')\n", 80 | "\n", 81 | "\n", 82 | "# 想知道é這個符號的編碼\n", 83 | "place = 'café'\n", 84 | "print(place)\n", 85 | "unicode_test('é')\n", 86 | "print('é'.encode('unicode-escape')) #這裡\n", 87 | "\n", 88 | "unicode_test('\\u00e9')" 89 | ] 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "metadata": {}, 94 | "source": [ 95 | "---\n", 96 | "使用utf-8進行編碼與解碼\n", 97 | "\n", 98 | "* 將字符串編碼為字節;\n", 99 | "* 將字節解碼為字符串。\n", 100 | "\n", 101 | "使用__encode()__來編碼字符串成我們看得懂的\n", 102 | "\n", 103 | "|編碼 | 說明 |\n", 104 | "|:---:|-----|\n", 105 | "|'ascii' | ASCII 編碼|\n", 106 | "|'utf-8' |最常用的編碼|\n", 107 | "|'latin-1' | ISO 8859-1 編碼|\n", 108 | "|'cp-1252' |Windows 常用編碼|\n", 109 | "|'unicode-escape' |Python 中 Unicode 的文本格式, \\uxxxx 或者 \\Uxxxxxxxx|" 110 | ] 111 | }, 112 | { 113 | "cell_type": "code", 114 | "execution_count": 2, 115 | "metadata": { 116 | "collapsed": false 117 | }, 118 | "outputs": [ 119 | { 120 | "name": "stdout", 121 | "output_type": "stream", 122 | "text": [ 123 | "☃\n", 124 | "b'\\\\u2603'\n", 125 | "1\n", 126 | "3\n", 127 | "b'\\xe2\\x98\\x83'\n", 128 | "☃\n" 129 | ] 130 | } 131 | ], 132 | "source": [ 133 | "#編碼\n", 134 | "snowman = '\\u2603'\n", 135 | "\n", 136 | "print(snowman)\n", 137 | "print(snowman.encode('unicode-escape'))\n", 138 | "\n", 139 | "\n", 140 | "print(len(snowman))\n", 141 | "ds = snowman.encode('utf-8')\n", 142 | "\n", 143 | "print(len(ds))\n", 144 | "print(ds)\n", 145 | "print('☃')" 146 | ] 147 | }, 148 | { 149 | "cell_type": "code", 150 | "execution_count": 3, 151 | "metadata": { 152 | "collapsed": false 153 | }, 154 | "outputs": [ 155 | { 156 | "name": "stdout", 157 | "output_type": "stream", 158 | "text": [ 159 | "café\n", 160 | "b'caf\\xc3\\xa9'\n", 161 | "café\n" 162 | ] 163 | } 164 | ], 165 | "source": [ 166 | "#解碼\n", 167 | "\n", 168 | "place = 'caf\\u00e9'\n", 169 | "print(place)\n", 170 | "\n", 171 | "place_bytes = place.encode('utf-8')\n", 172 | "print(place_bytes)\n", 173 | "\n", 174 | "place2 = place_bytes.decode('utf-8')\n", 175 | "print(place2)" 176 | ] 177 | }, 178 | { 179 | "cell_type": "markdown", 180 | "metadata": {}, 181 | "source": [ 182 | "---\n", 183 | "\n", 184 | "## 7.1.2 格式化\n", 185 | "[回目錄](#HOME)\n", 186 | "\n", 187 | "有兩種方法可以格式化文字\n", 188 | "* __string % data__\n", 189 | "* __{}.format__ (新的寫法,推薦使用)\n", 190 | "* __f\"{Variable Name}\"__ (Python 3.6之後才有)\n", 191 | "\n", 192 | "第一種搭配的format符號表如下\n", 193 | "\n", 194 | "|符號|種類|\n", 195 | "|---|---|\n", 196 | "|%s | 字串|\n", 197 | "|%d | 十進制整數|\n", 198 | "|%x | 十六進制整數|\n", 199 | "|%o | 八進制整數|\n", 200 | "|%f | 十進制浮點數|\n", 201 | "|%e | 以科學計數法表示的浮點數|\n", 202 | "|%g | 十進製或科學計數法表示的浮點數|\n", 203 | "|%% | 文本值 % 本身|" 204 | ] 205 | }, 206 | { 207 | "cell_type": "code", 208 | "execution_count": 4, 209 | "metadata": { 210 | "collapsed": false, 211 | "scrolled": true 212 | }, 213 | "outputs": [ 214 | { 215 | "name": "stdout", 216 | "output_type": "stream", 217 | "text": [ 218 | "42\n", 219 | "42\n", 220 | "2a\n", 221 | "52\n", 222 | "7.03\n", 223 | "7.030000\n", 224 | "7.030000e+00\n", 225 | "7.03\n", 226 | "100%\n", 227 | "混合搭配文字[我是文字],以及數字[87.000000]\n", 228 | " 42\n", 229 | " 0042\n", 230 | " 42.0\n", 231 | "42.0\n", 232 | "42 \n", 233 | "42.0 \n" 234 | ] 235 | } 236 | ], 237 | "source": [ 238 | "# 方法一\n", 239 | "\n", 240 | "print('%s' % 42)\n", 241 | "print('%d' % 42)\n", 242 | "print('%x' % 42)\n", 243 | "print('%o' % 42)\n", 244 | "print('%s' % 7.03)\n", 245 | "print('%f' % 7.03)\n", 246 | "print('%e' % 7.03)\n", 247 | "print('%g' % 7.03)\n", 248 | "print('%d%%' % 100)\n", 249 | "print('混合搭配文字[%s],以及數字[%f]' % ('我是文字',87))\n", 250 | "\n", 251 | "#可搭配數字做位數控制\n", 252 | "print('%10d' % 42)\n", 253 | "print('%10.4d' % 42)\n", 254 | "print('%10.1f' % 42)\n", 255 | "print('%.1f' % 42)\n", 256 | "\n", 257 | "print('%-10d' % 42)\n", 258 | "print('%-10.1f' % 42)\n" 259 | ] 260 | }, 261 | { 262 | "cell_type": "code", 263 | "execution_count": 5, 264 | "metadata": { 265 | "collapsed": false 266 | }, 267 | "outputs": [ 268 | { 269 | "name": "stdout", 270 | "output_type": "stream", 271 | "text": [ 272 | "42 7.03 string cheese\n", 273 | "string cheese 42 7.03\n", 274 | "42 7.03 string cheese\n", 275 | "42 7.03 string cheese other\n", 276 | "===========分隔線===========\n", 277 | "42 7.030000 string cheese\n", 278 | "42 7.030000 string cheese\n", 279 | "===========分隔線===========\n", 280 | " 42 7.030000 string cheese\n", 281 | " 42 7.030000 string cheese\n", 282 | "42 7.030000 string cheese\n", 283 | " 42 7.030000 string cheese\n", 284 | "0000000042 7.0300 stri\n", 285 | "!!!!!!BIG SALE!!!!!!\n" 286 | ] 287 | } 288 | ], 289 | "source": [ 290 | "# 方法二\n", 291 | "\n", 292 | "n = 42\n", 293 | "f = 7.03\n", 294 | "s = 'string cheese'\n", 295 | "\n", 296 | "print('{} {} {}'.format(n, f, s))\n", 297 | "print('{2} {0} {1}'.format(n, f, s))\n", 298 | "print('{n} {f} {s}'.format(n=42, f=7.03, s='string cheese'))\n", 299 | "\n", 300 | "# 使用字典傳入\n", 301 | "d = {'n': 42, 'f': 7.03, 's': 'string cheese'}\n", 302 | "print('{0[n]} {0[f]} {0[s]} {1}'.format(d, 'other')) #0表示format的第一個參數,1表示第二個參數\n", 303 | "\n", 304 | "# 方法一中的format也可以用在新方法,採用:來做銜接\n", 305 | "print('===========分隔線===========')\n", 306 | "print('{0:d} {1:f} {2:s}'.format(n, f, s))\n", 307 | "print('{n:d} {f:f} {s:s}'.format(n=42, f=7.03, s='string cheese'))\n", 308 | "print('===========分隔線===========')\n", 309 | "print('{0:10d} {1:10f} {2:10s}'.format(n, f, s)) #指定寬度\n", 310 | "print('{0:>10d} {1:>10f} {2:>10s}'.format(n, f, s)) #右對齊\n", 311 | "print('{0:<10d} {1:<10f} {2:<10s}'.format(n, f, s)) #左對齊\n", 312 | "print('{0:^10d} {1:^10f} {2:^10s}'.format(n, f, s)) #置中對齊\n", 313 | "print('{0:>010d} {1:>10.4f} {2:>10.4s}'.format(n, f, s)) #與舊方法不同,整數沒有經度設定項\n", 314 | "print('{0:!^20s}'.format('BIG SALE')) #指定填充符號" 315 | ] 316 | }, 317 | { 318 | "cell_type": "markdown", 319 | "metadata": {}, 320 | "source": [ 321 | "---\n", 322 | "\n", 323 | "## 7.1.3 正規表達式\n", 324 | "[回目錄](#HOME)\n", 325 | "\n", 326 | "\n", 327 | "採用wiki的說法\n", 328 | "\n", 329 | "正規表示式,又稱正則表達式、正規表示法、正規運算式、規則運算式、常規表示法(英語:Regular Expression,在代碼中常簡寫為regex、regexp或RE), \n", 330 | "電腦科學的一個概念。正規表示式使用單個字串來描述、符合一系列符合某個句法規則的字串。 \n", 331 | "在很多文字編輯器裡,正則運算式通常被用來檢索、取代那些符合某個模式的文字。\n", 332 | "\n", 333 | "簡單來說,就是可以用來匹配__字串(source)__中的__規則(pattern)__\n", 334 | "\n", 335 | "```python\n", 336 | "import re #從標準函式庫引入\n", 337 | "```\n", 338 | "\n", 339 | "|function | 功能 |\n", 340 | "|----------|------|\n", 341 | "|re.match( pattern, source ) | 查看字串是否以規定的規則開頭 |\n", 342 | "|re.search( pattern, source ) | 會返回第一次成功的匹配值 (如果有成功) |\n", 343 | "|re.findall( pattern, source) | 會返回所有成功且不重複的匹配值 (如果有成功) |\n", 344 | "|re.split( pattern, source ) | 會根據 規則 將 字串 切分成若干段,返回由這些片段組成的list |\n", 345 | "|re.sub( pattern, replacement, source ) | 還需一個額外的參數 replacement,它會把 字串 中所有匹配規則的字串 替換成 replacement|" 346 | ] 347 | }, 348 | { 349 | "cell_type": "code", 350 | "execution_count": 6, 351 | "metadata": { 352 | "collapsed": false 353 | }, 354 | "outputs": [ 355 | { 356 | "name": "stdout", 357 | "output_type": "stream", 358 | "text": [ 359 | "----------match----------\n", 360 | "You\n", 361 | "\n", 362 | "----------compile後match----------\n", 363 | "<_sre.SRE_Match object; span=(0, 3), match='You'>\n", 364 | "You\n", 365 | "\n", 366 | "----------match使用.*找任何位置----------\n", 367 | "Young Frank\n", 368 | "\n", 369 | "----------search----------\n", 370 | "Frank\n", 371 | "\n", 372 | "----------findall----------\n", 373 | "['n', 'n', 'n', 'n']\n", 374 | "共找到 4 筆符合值\n", 375 | "\n", 376 | "['ng ', 'nke', 'nst']\n", 377 | "['ng', 'nk', 'ns', 'n']\n", 378 | "\n", 379 | "----------split----------\n", 380 | "['You', 'g Fra', 'ke', 'stei', '']\n", 381 | "\n", 382 | "----------sub----------\n", 383 | "You?g Fra?ke?stei?\n", 384 | "['Fra']\n" 385 | ] 386 | } 387 | ], 388 | "source": [ 389 | "import re\n", 390 | "# .group()可以叫出符合正規表達式的字串部分\n", 391 | "\n", 392 | "print('----------match----------')\n", 393 | "# 檢查'Young Frankenstein'是否以'You'開頭\n", 394 | "result = re.match('You', 'Young Frankenstein')\n", 395 | "if result:\n", 396 | " print(result.group())\n", 397 | "\n", 398 | "\n", 399 | "print('\\n----------compile後match----------')\n", 400 | "# 針對較複雜情況可以先編譯一個物件出來加速判斷\n", 401 | "youpattern = re.compile('You')\n", 402 | "result = youpattern.match('Young Frankenstein')\n", 403 | "print(result)\n", 404 | "if result:\n", 405 | " print(result.group())\n", 406 | "\n", 407 | "print('\\n----------match使用.*找任何位置----------')\n", 408 | "# \".\"為除「\\n」之外的任何單個字元。 \"*\"為符合前面的子運算式零次或多次。\n", 409 | "# 組合在一起則成為匹配任意長度任意字元(除「\\n」)的規則\n", 410 | "m = re.match('.*Frank', 'Young Frankenstein')\n", 411 | "if m:\n", 412 | " print(m.group())\n", 413 | "\n", 414 | "print('\\n----------search----------')\n", 415 | "# 可以不用透過\".*\"來找任意位置的符合值\n", 416 | "m = re.search('Frank', 'Young Frankenstein')\n", 417 | "if m: # search返回物件\n", 418 | " print(m.group())\n", 419 | " \n", 420 | "print('\\n----------findall----------')\n", 421 | "# 尋找所有符合的\n", 422 | "m = re.findall('n', 'Young Frankenstein')\n", 423 | "print(m) # findall返回了一个列表\n", 424 | "print('共找到', len(m), '筆符合值\\n')\n", 425 | "\n", 426 | "#尋找後方有一個字元的\n", 427 | "m = re.findall('n..', 'Young Frankenstein')\n", 428 | "print(m) # findall返回了一个列表\n", 429 | "\n", 430 | "#尋找後方有一個字元(可以沒有)的\n", 431 | "m = re.findall('n.?', 'Young Frankenstein')\n", 432 | "print(m) # findall返回了一个列表\n", 433 | "\n", 434 | "print('\\n----------split----------')\n", 435 | "# 利用規格做切割字串\n", 436 | "m = re.split('n', 'Young Frankenstein')\n", 437 | "print(m) # split返回了一个列表\n", 438 | "\n", 439 | "print('\\n----------sub----------')\n", 440 | "# 利用規格做替換字串\n", 441 | "m = re.sub('n', '?', 'Young Frankenstein')\n", 442 | "print(m) # sub返回了一个列表\n", 443 | "\n", 444 | "\n", 445 | "#尋找英文單字邊界\n", 446 | "m = re.findall(r'\\bFra', 'Young Frankenstein')\n", 447 | "print(m) # findall返回了一个列表" 448 | ] 449 | }, 450 | { 451 | "cell_type": "markdown", 452 | "metadata": {}, 453 | "source": [ 454 | "\n", 455 | "|特殊字元|功能|\n", 456 | "|:---:|--------|\n", 457 | "|. |代表任意除 \\n 外的字元|\n", 458 | "|\\* |表示任意多個字元(包括 0 個)|\n", 459 | "|? |表示可選字元( 0 個或 1 個)|\n", 460 | "|\\d |一個數字字元。等價於[0-9]|\n", 461 | "|\\D |一個非數字字元。等價於[^0-9]|\n", 462 | "|\\w |一個 字母 或 數字 包括底線字元。等價於[A-Za-z0-9\\_]|\n", 463 | "|\\W |一個 非字母 非數字 非底線字元。等價於[^A-Za-z0-9\\_]|\n", 464 | "|\\s |空白字元。等價於[ \\f\\n\\r\\t\\v]|\n", 465 | "|\\S |非空白字元。等價於[^ \\f\\n\\r\\t\\v]|\n", 466 | "|\\b |單詞邊界(一個 \\w 與 \\W 之間的範圍,順序可逆)|\n", 467 | "|\\B |非單詞邊界|" 468 | ] 469 | }, 470 | { 471 | "cell_type": "code", 472 | "execution_count": 7, 473 | "metadata": { 474 | "collapsed": false, 475 | "scrolled": true 476 | }, 477 | "outputs": [ 478 | { 479 | "name": "stdout", 480 | "output_type": "stream", 481 | "text": [ 482 | "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\n", 483 | "OPQRSTUVWXYZ!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n", 484 | "\r", 485 | "\u000b", 486 | "\f", 487 | "\n", 488 | "['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']\n", 489 | "['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '_']\n", 490 | "[' ', '\\t', '\\n', '\\r', '\\x0b', '\\x0c']\n" 491 | ] 492 | } 493 | ], 494 | "source": [ 495 | "import string\n", 496 | "printable = string.printable #100個ASCII字元\n", 497 | "len(printable)\n", 498 | "\n", 499 | "print(printable[0:50])\n", 500 | "print(printable[50:])\n", 501 | "\n", 502 | "print(re.findall('\\d', printable)) #找數字\n", 503 | "print(re.findall('\\w', printable)) #找字母與數字\n", 504 | "print(re.findall('\\s', printable)) #找空白\n", 505 | "\n" 506 | ] 507 | }, 508 | { 509 | "cell_type": "markdown", 510 | "metadata": {}, 511 | "source": [ 512 | "直線符號(|)在markdown中的表格會變成區分格子用,我打不出來....請各位使用時自行替換\n", 513 | "\n", 514 | "|規則\t\t\t\t|功能 |\n", 515 | "|-------------------|--------------------------------------|\n", 516 | "|abc\t\t\t\t|文本值 abc |\n", 517 | "|(expr)\t\t\t\t|expr |\n", 518 | "|expr1 直線符號 expr2\t\t|expr1 或 expr2 |\n", 519 | "|. \t\t\t\t\t|除 \\n 外的任何字元 |\n", 520 | "|^\t\t\t\t\t|源字元串的開頭 |\n", 521 | "|$\t\t\t\t\t|源字元串的結尾 |\n", 522 | "|prev?\t\t\t\t|0 個或 1 個 prev |\n", 523 | "|prev*\t\t\t\t|0 個或多個 prev,盡可能多地匹配 |\n", 524 | "|prev*?\t\t\t\t|0 個或多個 prev,盡可能少地匹配 |\n", 525 | "|prev+\t\t\t\t|1 個或多個 prev,盡可能多地匹配 |\n", 526 | "|prev+?\t\t\t\t|1 個或多個 prev,盡可能少地匹配 |\n", 527 | "|prev{m}\t\t\t|m 個連續的 prev |\n", 528 | "|prev{m, n}\t\t\t|m 到 n 個連續的 prev,盡可能多地匹配 |\n", 529 | "|prev{m, n}?\t\t|m 到 n 個連續的 prev,盡可能少地匹配 |\n", 530 | "|[abc]\t\t\t\t|a 或 b 或 c(和 a直線符號b直線符號c 一樣) |\n", 531 | "|[^abc]\t\t\t\t|非(a 或 b 或 c) |\n", 532 | "|prev (?=next)\t\t|如果後面為 next,返回 prev |\n", 533 | "|prev (?!next)\t\t|如果後面非 next,返回 prev |\n", 534 | "|(?<=prev) next\t\t|如果前面為 prev,返回 next |\n", 535 | "|(?設定名稱\n", 623 | "m = re.search(r'(. dish\\b).*(\\bfish)', source)\n", 624 | "print(m.group())\n", 625 | "print(m.groups())\n", 626 | "\n", 627 | "\n", 628 | "m = re.search(r'(?P. dish\\b).*(?P\\bfish)', source)\n", 629 | "print(m.group())\n", 630 | "print(m.groups())\n", 631 | "\n", 632 | "print(m.group('DISH'))\n", 633 | "print(m.group('FISH'))" 634 | ] 635 | }, 636 | { 637 | "cell_type": "markdown", 638 | "metadata": {}, 639 | "source": [ 640 | "---\n", 641 | "\n", 642 | "## 7.2.1 bytes and bytearray\n", 643 | "[回目錄](#HOME)\n", 644 | "\n", 645 | "恩...就是介紹bytes 和 bytearray的差別,一個可變一個不可變\n" 646 | ] 647 | }, 648 | { 649 | "cell_type": "code", 650 | "execution_count": 9, 651 | "metadata": { 652 | "collapsed": false 653 | }, 654 | "outputs": [ 655 | { 656 | "name": "stdout", 657 | "output_type": "stream", 658 | "text": [ 659 | "b'\\x01\\x02\\x03\\xff'\n", 660 | "bytearray(b'\\x01\\x02\\x03\\xff')\n", 661 | "bytearray(b'\\x01\\x7f\\x03\\xff')\n" 662 | ] 663 | } 664 | ], 665 | "source": [ 666 | "blist = [1, 2, 3, 255]\n", 667 | "the_bytes = bytes(blist)\n", 668 | "print(the_bytes)\n", 669 | "\n", 670 | "the_byte_array = bytearray(blist)\n", 671 | "print(the_byte_array)\n", 672 | "\n", 673 | "the_byte_array[1] = 127 #可變\n", 674 | "print(the_byte_array)" 675 | ] 676 | }, 677 | { 678 | "cell_type": "markdown", 679 | "metadata": {}, 680 | "source": [ 681 | "---\n", 682 | "\n", 683 | "## 7.2.2 使用struct轉換二進位資料\n", 684 | "[回目錄](#HOME)\n", 685 | "\n", 686 | "使用標準函式庫裡的struct來做為轉換二進位資料\n", 687 | "\n", 688 | "|符號 | Byte order |\n", 689 | "|----|--------|\n", 690 | "|<| 小端方案|\n", 691 | "|>| 大端方案|\n", 692 | "\n", 693 | "|標識符|\t描述|\t字節|\n", 694 | "|:--:|-----|:----:|\n", 695 | "|x\t|跳過一個字節|\t1|\n", 696 | "|b\t|有符號字節|\t1|\n", 697 | "|B\t|無符號字節|\t1|\n", 698 | "|h\t|有符號短整數|\t2|\n", 699 | "|H\t|無符號短整數|\t2|\n", 700 | "|i\t|有符號整數|\t4|\n", 701 | "|I\t|無符號整數|\t4|\n", 702 | "|l\t|有符號長整數|\t4|\n", 703 | "|L\t|無符號長整數|\t4|\n", 704 | "|Q\t|無符號 long long 型整數|\t8|\n", 705 | "|f\t|單精度浮點數|\t4\t|\t\t\n", 706 | "|d\t|雙精度浮點數|\t8\t\t|\t\n", 707 | "|p\t|數量和字符|\t1\t+\t數量\t|\n", 708 | "|s\t|字符|\t數量|\t\t\t\n" 709 | ] 710 | }, 711 | { 712 | "cell_type": "code", 713 | "execution_count": 10, 714 | "metadata": { 715 | "collapsed": false 716 | }, 717 | "outputs": [ 718 | { 719 | "name": "stdout", 720 | "output_type": "stream", 721 | "text": [ 722 | "Valid PNG, width 154 height 141\n", 723 | "b'\\x00\\x00\\x00\\x9a'\n", 724 | "b'\\x00\\x00\\x00\\x8d'\n", 725 | "(154, 141)\n", 726 | "(154, 141)\n" 727 | ] 728 | } 729 | ], 730 | "source": [ 731 | "import struct\n", 732 | "valid_png_header = b'\\x89PNG\\r\\n\\x1a\\n' #png的檔頭\n", 733 | "data = b'\\x89PNG\\r\\n\\x1a\\n\\x00\\x00\\x00\\rIHDR' + \\\n", 734 | " b'\\x00\\x00\\x00\\x9a\\x00\\x00\\x00\\x8d\\x08\\x02\\x00\\x00\\x00\\xc0' #一個圖檔的前段\n", 735 | " \n", 736 | "if data[:8] == valid_png_header:\n", 737 | " width, height = struct.unpack('>LL', data[16:24])\n", 738 | " print('Valid PNG, width', width, 'height', height)\n", 739 | "else:\n", 740 | " print('Not a valid PNG')\n", 741 | " \n", 742 | "#反過來轉換\n", 743 | "print(struct.pack('>L', 154))\n", 744 | "print(struct.pack('>L', 141))\n", 745 | "\n", 746 | "print(struct.unpack('>2L', data[16:24]))\n", 747 | "print(struct.unpack('>16x2L6x', data))\n" 748 | ] 749 | }, 750 | { 751 | "cell_type": "markdown", 752 | "metadata": {}, 753 | "source": [ 754 | "---\n", 755 | "\n", 756 | "## 7.2.3 其他二進位工具\n", 757 | "[回目錄](#HOME)\n", 758 | "\n", 759 | "* bitstring( https://code.google.com/p/python-bitstring/ )\n", 760 | "* construct( http://construct.readthedocs.org/en/latest/ )\n", 761 | "* hachoir( https://bitbucket.org/haypo/hachoir/wiki/Home )\n", 762 | "* binio( http://spika.net/py/binio/ )\n" 763 | ] 764 | }, 765 | { 766 | "cell_type": "markdown", 767 | "metadata": {}, 768 | "source": [ 769 | "---\n", 770 | "\n", 771 | "## 7.2.4 binascii函數\n", 772 | "[回目錄](#HOME)\n", 773 | "\n", 774 | "十六進制、六十四進制、uuencoded,等等之間轉換的函數。" 775 | ] 776 | }, 777 | { 778 | "cell_type": "code", 779 | "execution_count": 11, 780 | "metadata": { 781 | "collapsed": false 782 | }, 783 | "outputs": [ 784 | { 785 | "name": "stdout", 786 | "output_type": "stream", 787 | "text": [ 788 | "b'89504e470d0a1a0a'\n", 789 | "b'\\x89PNG\\r\\n\\x1a\\n'\n" 790 | ] 791 | } 792 | ], 793 | "source": [ 794 | "import binascii\n", 795 | "\n", 796 | "#八字節轉十六bytes\n", 797 | "valid_png_header = b'\\x89PNG\\r\\n\\x1a\\n'\n", 798 | "print(binascii.hexlify(valid_png_header))\n", 799 | "\n", 800 | "#十六bytes轉八bytes\n", 801 | "print(binascii.unhexlify(b'89504e470d0a1a0a'))" 802 | ] 803 | }, 804 | { 805 | "cell_type": "markdown", 806 | "metadata": {}, 807 | "source": [ 808 | "---\n", 809 | "\n", 810 | "## 7.2.5 位元運算\n", 811 | "[回目錄](#HOME)\n", 812 | "\n", 813 | "以整數 a(十進制 5,二進制 0b0101)和 b(十進制 1,二進制 0b0001)做示範\n", 814 | "\n", 815 | "\n", 816 | " \n", 817 | " \n", 818 | " \n", 819 | " \n", 820 | " \n", 821 | " \n", 822 | " \n", 823 | " \n", 824 | " \n", 825 | " \n", 826 | " \n", 827 | " \n", 828 | " \n", 829 | " \n", 830 | " \n", 831 | " \n", 832 | " \n", 833 | " \n", 834 | " \n", 835 | " \n", 836 | " \n", 837 | " \n", 838 | " \n", 839 | " \n", 840 | " \n", 841 | " \n", 842 | " \n", 843 | " \n", 844 | " \n", 845 | " \n", 846 | " \n", 847 | " \n", 848 | " \n", 849 | " \n", 850 | " \n", 851 | " \n", 852 | " \n", 853 | " \n", 854 | " \n", 855 | " \n", 856 | " \n", 857 | " \n", 858 | " \n", 859 | " \n", 860 | " \n", 861 | " \n", 862 | " \n", 863 | " \n", 864 | " \n", 865 | "
運算符描述示範十進制結果二進制結果
&a & b10b0001
|a | b50b0101
^異或 a ^ b40b0100
~翻轉~a-6取決於 int 類型的大小
<<左位移a << 1100b1010
>>右位移a >> 120b0010
\n", 866 | "\n", 867 | "\n", 868 | "\n", 869 | "\n", 870 | "\n", 871 | "\n", 872 | "\n" 873 | ] 874 | } 875 | ], 876 | "metadata": { 877 | "kernelspec": { 878 | "display_name": "Python [Root]", 879 | "language": "python", 880 | "name": "Python [Root]" 881 | }, 882 | "language_info": { 883 | "codemirror_mode": { 884 | "name": "ipython", 885 | "version": 3 886 | }, 887 | "file_extension": ".py", 888 | "mimetype": "text/x-python", 889 | "name": "python", 890 | "nbconvert_exporter": "python", 891 | "pygments_lexer": "ipython3", 892 | "version": "3.5.2" 893 | } 894 | }, 895 | "nbformat": 4, 896 | "nbformat_minor": 0 897 | } 898 | -------------------------------------------------------------------------------- /CHAPTER 8 Data Has to Go Somewhere.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": false 7 | }, 8 | "source": [ 9 | "\n", 10 | "# CHAPTER 8 Data Has to Go Somewhere\n", 11 | "## 資料的歸宿\n", 12 | "\n", 13 | "* [8.1 資料的輸出與輸入](#IO)\n", 14 | "* [8.2 結構化資料檔案](#StructuredText)\n", 15 | "* [8.3 結構化二進位檔案](#StructuredBinary)\n", 16 | "* [8.4 關聯式資料庫](#RelationalDatabases)\n", 17 | "* [8.5 NoSQL資料庫](#NoSQL)\n", 18 | "* [8.6 全文檢索資料庫](#Full-TextDatabases)\n", 19 | "\n" 20 | ] 21 | }, 22 | { 23 | "cell_type": "markdown", 24 | "metadata": {}, 25 | "source": [ 26 | "---\n", 27 | "\n", 28 | "## 8.1 資料的輸出與輸入\n", 29 | "[回目錄](#HOME)\n", 30 | "\n", 31 | "```python\n", 32 | "fileobj = open(filename, mode)\n", 33 | "```\n", 34 | "\n", 35 | "|mode 第一個字母|解釋|\n", 36 | "|:---:|----|\n", 37 | "|r |表示讀模式|\n", 38 | "|w |表示寫模式。如果文件不存在則新創建,如果存在則重寫新內容|\n", 39 | "|x |表示在文件不存在的情況下新創建並寫文件|\n", 40 | "|a |表示如果文件存在,在文件末尾追加寫內容|\n", 41 | "\n", 42 | "\n", 43 | "|mode 第二個字母|解釋|\n", 44 | "|:---:|----|\n", 45 | "|t|(或者省略)代表文本類型|\n", 46 | "|b| 代表二進位文件|\n" 47 | ] 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "metadata": {}, 52 | "source": [ 53 | "### 8.1.1 使用write()與print()寫入檔案\n", 54 | "\n", 55 | "\n", 56 | "使用print寫入時可以使用sep與end參數指定分隔符號與結束符號\n", 57 | "* sep,預設為' '\n", 58 | "* end,預設為'\\n'" 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": 1, 64 | "metadata": { 65 | "collapsed": false 66 | }, 67 | "outputs": [], 68 | "source": [ 69 | "abc = 'abc'\n", 70 | "defg = 'defg'\n", 71 | "\n", 72 | "#wirte寫入\n", 73 | "fout = open('Data/relativity', 'wt')\n", 74 | "fout.write('{0}-{1}。'.format(abc, 'XD'))\n", 75 | "fout.write(defg)\n", 76 | "fout.close()\n", 77 | "\n", 78 | "#print寫入(預設)\n", 79 | "fout = open('Data/relativity', 'wt')\n", 80 | "print(abc, defg, file=fout)\n", 81 | "fout.close()\n", 82 | "\n", 83 | "##print寫入(更換分隔與結束符號)\n", 84 | "fout = open('Data/relativity', 'wt')\n", 85 | "print(abc, defg, sep='-', end='。', file=fout)\n", 86 | "fout.close()" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": 2, 92 | "metadata": { 93 | "collapsed": false 94 | }, 95 | "outputs": [ 96 | { 97 | "name": "stdout", 98 | "output_type": "stream", 99 | "text": [ 100 | "文件已存在。\n" 101 | ] 102 | } 103 | ], 104 | "source": [ 105 | "#分段寫入\n", 106 | "poem = '''There was a young lady named Bright,\n", 107 | "Whose speed was far faster than light;\n", 108 | "She started one day\n", 109 | "In a relative way,\n", 110 | "And returned on the previous night.'''\n", 111 | "size = len(poem)\n", 112 | "\n", 113 | "fout = open('Data/relativity', 'wt')\n", 114 | "\n", 115 | "offset = 0\n", 116 | "chunk = 100\n", 117 | "while True:\n", 118 | " if offset > size:\n", 119 | " fout.close()\n", 120 | " break\n", 121 | " fout.write(poem[offset:offset+chunk])\n", 122 | " offset += chunk\n", 123 | " \n", 124 | "\n", 125 | "#open模式改為x可以防止覆蓋已存在之文件\n", 126 | "try:\n", 127 | " fout = open('Data/relativity', 'xt')\n", 128 | " fout.write('stomp stomp stomp')\n", 129 | "except FileExistsError:\n", 130 | " print('文件已存在。')" 131 | ] 132 | }, 133 | { 134 | "cell_type": "markdown", 135 | "metadata": {}, 136 | "source": [ 137 | "### 8.1.2使用read(),readline()或者readlines()讀取檔案\n", 138 | "\n", 139 | "* __fin.read()__,一次讀入全部,或是指定讀入字節數,注意記憶體占用情況\n", 140 | "* __fin.readline()__,一次讀入一行\n", 141 | "* __fin.readlines()__,疊代器用法,寫法更好看" 142 | ] 143 | }, 144 | { 145 | "cell_type": "code", 146 | "execution_count": 3, 147 | "metadata": { 148 | "collapsed": false 149 | }, 150 | "outputs": [ 151 | { 152 | "name": "stdout", 153 | "output_type": "stream", 154 | "text": [ 155 | "There was a young lady named Bright,\n", 156 | "Whose speed was far faster than light;\n", 157 | "She started one day\n", 158 | "In a relative way,\n", 159 | "And returned on the previous night.\n", 160 | "\n", 161 | "================\n", 162 | "There was a young lady named Bright,\n", 163 | "Whose speed was far faster than light;\n", 164 | "She started one day\n", 165 | "In a relative way,\n", 166 | "And returned on the previous night.\n", 167 | "\n", 168 | "================\n", 169 | "There was a young lady named Bright,\n", 170 | "Whose speed was far faster than light;\n", 171 | "She started one day\n", 172 | "In a relative way,\n", 173 | "And returned on the previous night.\n", 174 | "\n", 175 | "================\n", 176 | "共 5 行\n", 177 | "There was a young lady named Bright,\n", 178 | "。Whose speed was far faster than light;\n", 179 | "。She started one day\n", 180 | "。In a relative way,\n", 181 | "。And returned on the previous night.。" 182 | ] 183 | } 184 | ], 185 | "source": [ 186 | "#一次讀入\n", 187 | "fin = open('Data/relativity', 'rt' )\n", 188 | "poem = fin.read()\n", 189 | "fin.close()\n", 190 | "print(poem)\n", 191 | "\n", 192 | "\n", 193 | "#指定一次100字節\n", 194 | "print('\\n================')\n", 195 | "poem = ''\n", 196 | "fin = open('Data/relativity', 'rt' )\n", 197 | "chunk = 100\n", 198 | "while True:\n", 199 | " fragment = fin.read(chunk)\n", 200 | " if not fragment:\n", 201 | " fin.close()\n", 202 | " break\n", 203 | " poem += fragment\n", 204 | "\n", 205 | "print(poem)\n", 206 | "\n", 207 | "#使用readline一次讀入一行\n", 208 | "print('\\n================')\n", 209 | "poem = ''\n", 210 | "fin = open('Data/relativity', 'rt' )\n", 211 | "while True:\n", 212 | " line = fin.readline()\n", 213 | " if not line:\n", 214 | " fin.close()\n", 215 | " break\n", 216 | " poem += line\n", 217 | "\n", 218 | "print(poem)\n", 219 | "\n", 220 | "#使用readlines疊代器\n", 221 | "print('\\n================')\n", 222 | "fin = open('Data/relativity', 'rt' )\n", 223 | "lines = fin.readlines()\n", 224 | "fin.close()\n", 225 | "print('共', len(lines), '行')\n", 226 | "\n", 227 | "for line in lines:\n", 228 | " print(line, end='。')" 229 | ] 230 | }, 231 | { 232 | "cell_type": "markdown", 233 | "metadata": {}, 234 | "source": [ 235 | "### 8.1.3 寫入二進位檔案" 236 | ] 237 | }, 238 | { 239 | "cell_type": "code", 240 | "execution_count": 4, 241 | "metadata": { 242 | "collapsed": false 243 | }, 244 | "outputs": [], 245 | "source": [ 246 | "bdata = bytes(range(0, 256))\n", 247 | "#print(bdata)\n", 248 | "\n", 249 | "#一次寫入\n", 250 | "fout = open('Data/bfile', 'wb')\n", 251 | "fout.write(bdata)\n", 252 | "fout.close()\n", 253 | "\n", 254 | "#批次寫入\n", 255 | "fout = open('Data/bfile', 'wb')\n", 256 | "size = len(bdata)\n", 257 | "offset = 0\n", 258 | "chunk = 100\n", 259 | "while True:\n", 260 | " if offset > size:\n", 261 | " fout.close()\n", 262 | " break\n", 263 | " fout.write(bdata[offset:offset+chunk])\n", 264 | " offset += chunk\n" 265 | ] 266 | }, 267 | { 268 | "cell_type": "markdown", 269 | "metadata": {}, 270 | "source": [ 271 | "### 8.1.4 讀取二進位檔案" 272 | ] 273 | }, 274 | { 275 | "cell_type": "code", 276 | "execution_count": 5, 277 | "metadata": { 278 | "collapsed": false 279 | }, 280 | "outputs": [ 281 | { 282 | "name": "stdout", 283 | "output_type": "stream", 284 | "text": [ 285 | "b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\\x7f\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x8b\\x8c\\x8d\\x8e\\x8f\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b\\x9c\\x9d\\x9e\\x9f\\xa0\\xa1\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\\xa8\\xa9\\xaa\\xab\\xac\\xad\\xae\\xaf\\xb0\\xb1\\xb2\\xb3\\xb4\\xb5\\xb6\\xb7\\xb8\\xb9\\xba\\xbb\\xbc\\xbd\\xbe\\xbf\\xc0\\xc1\\xc2\\xc3\\xc4\\xc5\\xc6\\xc7\\xc8\\xc9\\xca\\xcb\\xcc\\xcd\\xce\\xcf\\xd0\\xd1\\xd2\\xd3\\xd4\\xd5\\xd6\\xd7\\xd8\\xd9\\xda\\xdb\\xdc\\xdd\\xde\\xdf\\xe0\\xe1\\xe2\\xe3\\xe4\\xe5\\xe6\\xe7\\xe8\\xe9\\xea\\xeb\\xec\\xed\\xee\\xef\\xf0\\xf1\\xf2\\xf3\\xf4\\xf5\\xf6\\xf7\\xf8\\xf9\\xfa\\xfb\\xfc\\xfd\\xfe\\xff'\n" 286 | ] 287 | } 288 | ], 289 | "source": [ 290 | "fin = open('Data/bfile', 'rb')\n", 291 | "bdata = fin.read()\n", 292 | "fin.close()\n", 293 | "\n", 294 | "print(bdata)" 295 | ] 296 | }, 297 | { 298 | "cell_type": "markdown", 299 | "metadata": {}, 300 | "source": [ 301 | "### 8.1.5使用with自動關閉檔案\n", 302 | "\n", 303 | "python若後續沒有再繼續使用檔案則會自動關閉,所以在一個function中開啟檔案就算沒有關閉最後也會自動關閉。 \n", 304 | "但是在一個主程式中開啟則不會自動關閉,所以可以使用with as來做為自動關閉檔案用" 305 | ] 306 | }, 307 | { 308 | "cell_type": "code", 309 | "execution_count": 6, 310 | "metadata": { 311 | "collapsed": true 312 | }, 313 | "outputs": [], 314 | "source": [ 315 | "with open('Data/relativity', 'wt') as fout:\n", 316 | " fout.write(poem)" 317 | ] 318 | }, 319 | { 320 | "cell_type": "markdown", 321 | "metadata": {}, 322 | "source": [ 323 | "### 使用seek()改變位置\n", 324 | "\n", 325 | "__file.tell()__可以查詢讀取位置\n", 326 | "seek(offset,origin)\n", 327 | "\n", 328 | "origin = 0,預設,從頭開始位移。 \n", 329 | "origin = 1,從目前位置開始位移。 \n", 330 | "origin = 2,從最後往前為位移。" 331 | ] 332 | }, 333 | { 334 | "cell_type": "code", 335 | "execution_count": 7, 336 | "metadata": { 337 | "collapsed": false 338 | }, 339 | "outputs": [ 340 | { 341 | "name": "stdout", 342 | "output_type": "stream", 343 | "text": [ 344 | "1\n", 345 | "255\n", 346 | "1\n", 347 | "255\n", 348 | "255\n" 349 | ] 350 | } 351 | ], 352 | "source": [ 353 | "fin = open('Data/bfile', 'rb')\n", 354 | "fin.seek(255)\n", 355 | "\n", 356 | "bdata = fin.read()\n", 357 | "print(len(bdata))\n", 358 | "print(bdata[0])\n", 359 | "fin.close()\n", 360 | "\n", 361 | "#使用不同方法讀取最後一個字節\n", 362 | "fin = open('Data/bfile', 'rb')\n", 363 | "\n", 364 | "fin.seek(-1, 2)\n", 365 | "bdata = fin.read()\n", 366 | "print(len(bdata))\n", 367 | "print(bdata[0])\n", 368 | "fin.close()\n", 369 | "\n", 370 | "#\n", 371 | "fin = open('Data/bfile', 'rb')\n", 372 | "fin.seek(254, 0)\n", 373 | "fin.tell()\n", 374 | "fin.seek(1, 1)\n", 375 | "fin.tell()\n", 376 | "\n", 377 | "bdata = fin.read()\n", 378 | "print(bdata[0])" 379 | ] 380 | }, 381 | { 382 | "cell_type": "markdown", 383 | "metadata": {}, 384 | "source": [ 385 | "---\n", 386 | "\n", 387 | "## 8.2 結構化資料檔案\n", 388 | "[回目錄](#HOME)\n", 389 | "\n", 390 | "* CSV\n", 391 | "* XML\n", 392 | "* HTML\n", 393 | "* JSON" 394 | ] 395 | }, 396 | { 397 | "cell_type": "code", 398 | "execution_count": 8, 399 | "metadata": { 400 | "collapsed": false 401 | }, 402 | "outputs": [ 403 | { 404 | "name": "stdout", 405 | "output_type": "stream", 406 | "text": [ 407 | "[['Doctor', 'No'], [], ['Rosa', 'Klebb'], [], ['Mister', 'Big'], [], ['Auric', 'Goldfinger'], [], ['Ernst', 'Blofeld'], []]\n", 408 | "[{'first': 'Doctor', 'last': 'No'}, {'first': 'Rosa', 'last': 'Klebb'}, {'first': 'Mister', 'last': 'Big'}, {'first': 'Auric', 'last': 'Goldfinger'}, {'first': 'Ernst', 'last': 'Blofeld'}]\n", 409 | "[{'first': 'Doctor', 'last33': 'Blofeld', 'last': 'No'}, {'first': 'Rosa', 'last33': 'Blofeld', 'last': 'Klebb'}, {'first': 'Mister', 'last33': 'Blofeld', 'last': 'Big'}, {'first': 'Auric', 'last33': 'Blofeld', 'last': 'Goldfinger'}, {'first': 'Ernst', 'last33': 'Blofeld', 'last': 'Blofeld'}]\n" 410 | ] 411 | } 412 | ], 413 | "source": [ 414 | "import csv\n", 415 | "villains = [\n", 416 | " ['Doctor', 'No'],\n", 417 | " ['Rosa', 'Klebb'],\n", 418 | " ['Mister', 'Big'],\n", 419 | " ['Auric', 'Goldfinger'],\n", 420 | " ['Ernst', 'Blofeld']]\n", 421 | "\n", 422 | "# 寫入\n", 423 | "with open('Data/villains', 'wt') as fout:\n", 424 | " csvout = csv.writer(fout)\n", 425 | " csvout.writerows(villains)\n", 426 | "\n", 427 | "# 讀取\n", 428 | "with open('Data/villains', 'rt') as fin:\n", 429 | " cin = csv.reader(fin)\n", 430 | " villains = [row for row in cin]\n", 431 | "print(villains)\n", 432 | "\n", 433 | "# 讀成字典\n", 434 | "with open('Data/villains', 'rt') as fin:\n", 435 | " cin = csv.DictReader(fin, fieldnames=['first', 'last'])\n", 436 | " villains = [row for row in cin]\n", 437 | "print(villains)\n", 438 | "\n", 439 | "# 用字典格式寫入\n", 440 | "villains = [{'first': 'Doctor', 'last': 'No', 'last33': 'Blofeld'},\n", 441 | " {'first': 'Rosa', 'last': 'Klebb', 'last33': 'Blofeld'},\n", 442 | " {'first': 'Mister', 'last': 'Big', 'last33': 'Blofeld'},\n", 443 | " {'first': 'Auric', 'last': 'Goldfinger', 'last33': 'Blofeld'},\n", 444 | " {'first': 'Ernst', 'last': 'Blofeld', 'last33': 'Blofeld'}]\n", 445 | "\n", 446 | "with open('Data/villains', 'wt') as fout:\n", 447 | "# cout = csv.DictWriter(fout, ['first', 'last'])\n", 448 | " cout = csv.DictWriter(fout, ['first', 'last','last33'])\n", 449 | " cout.writeheader() #寫檔頭\n", 450 | " cout.writerows(villains)\n", 451 | " \n", 452 | "with open('Data/villains', 'rt') as fin:\n", 453 | " cin = csv.DictReader(fin)\n", 454 | " villains = [row for row in cin]\n", 455 | "print(villains)" 456 | ] 457 | }, 458 | { 459 | "cell_type": "code", 460 | "execution_count": 9, 461 | "metadata": { 462 | "collapsed": false 463 | }, 464 | "outputs": [ 465 | { 466 | "name": "stdout", 467 | "output_type": "stream", 468 | "text": [ 469 | "menu\n", 470 | "\ttag: item attributes: breakfast burritos\n", 471 | "\ttag: item attributes: {'price': '$6.00'}\n", 472 | "\ttag: item attributes: pancakes\n", 473 | "\ttag: item attributes: {'price': '$4.00', 'XDD': 'QQ'}\n", 474 | "\ttag: item attributes: hamburger\n", 475 | "\ttag: item attributes: {'price': '$5.00'}\n", 476 | "\ttag: item attributes: spaghetti\n", 477 | "\ttag: item attributes: {'price': '8.00'}\n", 478 | "3\n", 479 | "2\n" 480 | ] 481 | } 482 | ], 483 | "source": [ 484 | "import xml.etree.ElementTree as et\n", 485 | "tree = et.ElementTree(file='Data/menu.xml')\n", 486 | "root = tree.getroot()\n", 487 | "print(root.tag)\n", 488 | "\n", 489 | "for child in root:\n", 490 | " #print('tag:', child.tag, 'attributes:', child.attrib)\n", 491 | " for grandchild in child:\n", 492 | " print('\\ttag:', grandchild.tag, 'attributes:', grandchild.text)\n", 493 | " print('\\ttag:', grandchild.tag, 'attributes:', grandchild.attrib)\n", 494 | " \n", 495 | " \n", 496 | "print(len(root))\n", 497 | "print(len(root[0]))" 498 | ] 499 | }, 500 | { 501 | "cell_type": "code", 502 | "execution_count": 10, 503 | "metadata": { 504 | "collapsed": false 505 | }, 506 | "outputs": [ 507 | { 508 | "name": "stdout", 509 | "output_type": "stream", 510 | "text": [ 511 | "\n", 512 | "{'lunch': {'items': {'hamburger': '$5.00'}, 'hours': '11-3'}, 'breakfast': {'items': {'breakfast burritos': '$6.00', 'pancakes': '$4.00'}, 'hours': '7-11'}, 'dinner': {'items': {'spaghetti': '$8.00'}, 'hours': '3-10'}}\n", 513 | "{'items': {'breakfast burritos': '$6.00', 'pancakes': '$4.00'}, 'hours': '7-11'}\n" 514 | ] 515 | } 516 | ], 517 | "source": [ 518 | "menu = \\\n", 519 | "{\n", 520 | " \"breakfast\": {\n", 521 | " \"hours\": \"7-11\",\n", 522 | " \"items\": {\n", 523 | " \"breakfast burritos\": \"$6.00\",\n", 524 | " \"pancakes\": \"$4.00\"\n", 525 | " }\n", 526 | " },\n", 527 | " \"lunch\" : {\n", 528 | " \"hours\": \"11-3\",\n", 529 | " \"items\": {\n", 530 | " \"hamburger\": \"$5.00\"\n", 531 | " }\n", 532 | " },\n", 533 | " \"dinner\": {\n", 534 | " \"hours\": \"3-10\",\n", 535 | " \"items\": {\n", 536 | " \"spaghetti\": \"$8.00\"\n", 537 | " }\n", 538 | " }\n", 539 | "}\n", 540 | "\n", 541 | "import json\n", 542 | "menu_json = json.dumps(menu)\n", 543 | "print(type(menu_json))\n", 544 | "# print(menu_json['breakfast'])\n", 545 | "\n", 546 | "menu2 = json.loads(menu_json)\n", 547 | "print(menu2)\n", 548 | "print(menu2['breakfast'])" 549 | ] 550 | }, 551 | { 552 | "cell_type": "markdown", 553 | "metadata": {}, 554 | "source": [ 555 | "---\n", 556 | "\n", 557 | "## 8.3 結構化二進位檔案\n", 558 | "[回目錄](#HOME)" 559 | ] 560 | }, 561 | { 562 | "cell_type": "markdown", 563 | "metadata": {}, 564 | "source": [ 565 | "---\n", 566 | "\n", 567 | "## 8.4 關聯式資料庫 SQL\n", 568 | "[回目錄](#HOME)\n" 569 | ] 570 | }, 571 | { 572 | "cell_type": "markdown", 573 | "metadata": {}, 574 | "source": [ 575 | "---\n", 576 | "\n", 577 | "## 8.5 NoSQL資料庫\n", 578 | "[回目錄](#HOME)\n", 579 | "\n", 580 | "\n" 581 | ] 582 | }, 583 | { 584 | "cell_type": "markdown", 585 | "metadata": {}, 586 | "source": [ 587 | "---\n", 588 | "\n", 589 | "## 8.6 全文檢索資料庫\n", 590 | "[回目錄](#HOME)\n", 591 | "\n" 592 | ] 593 | } 594 | ], 595 | "metadata": { 596 | "anaconda-cloud": {}, 597 | "kernelspec": { 598 | "display_name": "Python [Root]", 599 | "language": "python", 600 | "name": "Python [Root]" 601 | }, 602 | "language_info": { 603 | "codemirror_mode": { 604 | "name": "ipython", 605 | "version": 3 606 | }, 607 | "file_extension": ".py", 608 | "mimetype": "text/x-python", 609 | "name": "python", 610 | "nbconvert_exporter": "python", 611 | "pygments_lexer": "ipython3", 612 | "version": "3.5.2" 613 | } 614 | }, 615 | "nbformat": 4, 616 | "nbformat_minor": 0 617 | } 618 | -------------------------------------------------------------------------------- /Data/bfile: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HuskyHsu/Introducing-Python/50066c397988ada84541a4ca264f528914a22724/Data/bfile -------------------------------------------------------------------------------- /Data/dishes.py: -------------------------------------------------------------------------------- 1 | import os 2 | import time 3 | from datetime import datetime 4 | 5 | def washer(dishes, now_): 6 | for dish in dishes: 7 | now = datetime.now() 8 | print('Washing', dish, ', time:', now - now_, ', pid', os.getpid()) 9 | time.sleep(1) 10 | dryer(dish, now_) 11 | 12 | def dryer(dish, now_): 13 | now = datetime.now() 14 | print('Drying ', dish, ', time:', now - now_, ', pid', os.getpid()) 15 | time.sleep(2) 16 | 17 | 18 | if __name__ == "__main__": 19 | now_ = datetime.now() 20 | dishes = ['dish-1', 'dish-2', 'dish-3', 'dish-4'] 21 | washer(dishes, now_) -------------------------------------------------------------------------------- /Data/dishes_process.py: -------------------------------------------------------------------------------- 1 | import multiprocessing as mp 2 | import os 3 | import time 4 | from datetime import datetime 5 | 6 | def washer(dishes, output, now_): 7 | for dish in dishes: 8 | now = datetime.now() 9 | print('Washing', dish, ', time:', now - now_, ', pid', os.getpid()) 10 | time.sleep(1) 11 | #把東西丟給行程(處理程序)後繼續執行下一個 12 | output.put(dish) 13 | 14 | def dryer(input, now_): 15 | while True: 16 | dish = input.get() 17 | now = datetime.now() 18 | print('Drying ', dish, ', time:', now - now_, ', pid', os.getpid()) 19 | time.sleep(2) 20 | input.task_done() 21 | 22 | if __name__ == "__main__": 23 | now_ = datetime.now() 24 | #建立佇列 25 | dish_queue = mp.JoinableQueue() 26 | #創建行程(烘乾人員) 27 | dryer_proc = mp.Process(target=dryer, args=(dish_queue, now_,)) 28 | dryer_proc.daemon = True 29 | #啟動行程(上班囉) 30 | dryer_proc.start() 31 | #time.sleep(1) 32 | 33 | dishes = ['dish-1', 'dish-2', 'dish-3', 'dish-4'] 34 | washer(dishes, dish_queue, now_) 35 | dish_queue.join() -------------------------------------------------------------------------------- /Data/dishes_threads.py: -------------------------------------------------------------------------------- 1 | import threading, queue 2 | import os 3 | import time 4 | from datetime import datetime 5 | 6 | def washer(dishes, dish_queue, now_): 7 | for dish in dishes: 8 | now = datetime.now() 9 | print ("Washing", dish, now - now_, ', pid', os.getpid(), threading.current_thread()) 10 | time.sleep(1) 11 | dish_queue.put(dish) 12 | 13 | def dryer(dish_queue, now_): 14 | while True: 15 | dish = dish_queue.get() 16 | now = datetime.now() 17 | print ("Drying ", dish, now - now_, ', pid', os.getpid(), threading.current_thread()) 18 | time.sleep(2) 19 | dish_queue.task_done() 20 | 21 | if __name__ == "__main__": 22 | dish_queue = queue.Queue() 23 | now_ = datetime.now() 24 | #控制要開幾條執行緒 25 | for n in range(2): 26 | dryer_thread = threading.Thread(target=dryer, args=(dish_queue, now_)) 27 | dryer_thread.daemon = True 28 | dryer_thread.start() 29 | 30 | dishes = ['dishe-1', 'dishe-2', 'dishe-3', 'dishe-4'] 31 | washer(dishes, dish_queue, now_) 32 | dish_queue.join() -------------------------------------------------------------------------------- /Data/menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | breakfast burritos 5 | pancakes 6 | 7 | 8 | hamburger 9 | 10 | 11 | spaghetti 12 | 13 | -------------------------------------------------------------------------------- /Data/mp.py: -------------------------------------------------------------------------------- 1 | import multiprocessing 2 | import os 3 | 4 | def do_this(what): 5 | whoami(what) 6 | 7 | def whoami(what): 8 | print("Process %s says: %s" % (os.getpid(), what)) 9 | 10 | if __name__ == "__main__": 11 | whoami("I'm the main program") 12 | for n in range(4): 13 | p = multiprocessing.Process(target=do_this,args=("I'm function %s" % n,)) 14 | p.start() -------------------------------------------------------------------------------- /Data/mp2.py: -------------------------------------------------------------------------------- 1 | import multiprocessing 2 | import time 3 | import os 4 | 5 | def whoami(name): 6 | print("I'm %s, in process %s" % (name, os.getpid())) 7 | 8 | def loopy(name): 9 | whoami(name) 10 | start = 1 11 | stop = 1000000 12 | for num in range(start, stop): 13 | print("\tNumber %s of %s. Honk!" % (num, stop)) 14 | time.sleep(1) 15 | 16 | if __name__ == "__main__": 17 | whoami("main") 18 | p = multiprocessing.Process(target=loopy, args=("loopy",)) 19 | p.start() 20 | time.sleep(5) 21 | p.terminate() -------------------------------------------------------------------------------- /Data/mp_threads.py: -------------------------------------------------------------------------------- 1 | import threading 2 | 3 | def do_this(what): 4 | whoami(what) 5 | 6 | def whoami(what): 7 | print("Thread %s says: %s" % (threading.current_thread(), what)) 8 | 9 | if __name__ == "__main__": 10 | whoami("I'm the main program") 11 | for n in range(4): 12 | p = threading.Thread(target=do_this,args=("I'm function %s" % n,)) 13 | p.start() -------------------------------------------------------------------------------- /Data/relativity: -------------------------------------------------------------------------------- 1 | There was a young lady named Bright, 2 | Whose speed was far faster than light; 3 | She started one day 4 | In a relative way, 5 | And returned on the previous night. -------------------------------------------------------------------------------- /Data/villains: -------------------------------------------------------------------------------- 1 | first,last,last33 2 | Doctor,No,Blofeld 3 | Rosa,Klebb,Blofeld 4 | Mister,Big,Blofeld 5 | Auric,Goldfinger,Blofeld 6 | Ernst,Blofeld,Blofeld 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Introducing Python By Bill Lubanovic 讀書筆記 2 | 3 | ![Alt text](http://akamaicovers.oreilly.com/images/0636920028659/lrg.jpg) 4 | 5 | [天瓏網路書店-【精通 Python】](https://www.tenlong.com.tw/items/9863477311?item_id=1007464 "天瓏網路書店-[精通 Python]") 6 | 7 | ### ipython notebook筆記: 8 | 9 | * 第一章 初嘗 Py 10 | * [第二章 Py 食材:數字、字串與變數](http://nbviewer.jupyter.org/github/HuskyHsu/Introducing-Python/blob/master/CHAPTER%202%20Numbers%2C%20Strings%2Cand%20Variables.ipynb) 11 | * [第三章 Py 填充:串列、Tuple、字典,與集合](http://nbviewer.jupyter.org/github/HuskyHsu/Introducing-Python/blob/master/CHAPTER%203%20Py%20Filling%20Lists%2C%20Tuples%2C%20Dictionaries%20and%20Sets.ipynb) 12 | * [第四章 Py 之殼:程式結構](http://nbviewer.jupyter.org/github/HuskyHsu/Introducing-Python/blob/master/CHAPTER%204%20Py%20Crust-%20Code%20Structures.ipynb) 13 | * [第五章 Py 盒子:模組、套件與程式](http://nbviewer.jupyter.org/github/HuskyHsu/Introducing-Python/blob/master/CHAPTER%205%20Py%20Boxes-%20Modules%2C%20Packages%2C%20and%20Programs.ipynb) 14 | * [第六章 喔喔:物件與類別](http://nbviewer.jupyter.org/github/HuskyHsu/Introducing-Python/blob/master/CHAPTER%206%20Oh%20Oh-%20Objects%20and%20Classes.ipynb) 15 | * [第七章 像專家一樣處理資料](http://nbviewer.jupyter.org/github/HuskyHsu/Introducing-Python/blob/master/CHAPTER%207%20Mangle%20Data%20Like%20a%20Pro.ipynb) 16 | * [第八章 資料的去處](http://nbviewer.jupyter.org/github/HuskyHsu/Introducing-Python/blob/master/CHAPTER%208%20Data%20Has%20to%20Go%20Somewhere.ipynb) 17 | * [第九章 Web,開展](http://nbviewer.jupyter.org/github/HuskyHsu/Introducing-Python/blob/master/CHAPTER%209%20The%20Web%2C%20Untangled.ipynb) 18 | * [第十章 系統](http://nbviewer.jupyter.org/github/HuskyHsu/Introducing-Python/blob/master/CHAPTER%2010%20Systems.ipynb) 19 | * [第十一章 並行處理與網路](http://nbviewer.jupyter.org/github/HuskyHsu/Introducing-Python/blob/master/CHAPTER%2011%20Concurrency%20and%20Networks.ipynb) 20 | * 第十二章 當一位 Python 忠貞黨員 21 | 22 | 有誤以及描述不清楚歡迎修正。 --------------------------------------------------------------------------------