PYTHON

Lesson 5

Lecturer : 溫室蔡、乘一

Decorator裝飾器?

Function!

還記得上一堂課教的...

def 函數名稱(參數1, 參數2, ...):
    # 你要做的事情
    # ...
    # ...
    return 回傳值
#偷

先看這個code

import time
def caculate():
    fstart = time.perf_counter()
    sum=0
    for i in range(10001):
        sum +=i
    print(sum)
    fend = time.perf_counter()
    ftotal = fend-fstart
    print(ftotal//1) #計算1~100加總所花時間
def iamhappy():
    fstart = time.perf_counter()
    print("I like python!!!")
    time.sleep(3)
    fend = time.perf_counter()
    ftotal = fend-fstart
    print(ftotal//1) #計算輸出並休息3秒所花時間
caculate()
iamhappy()
#500500 0.0 I like python!!! 3.0
#好多重複好可怕QAQ

Decorator!

  • 一種函式,輔助並修飾其他函式

  • 簡潔度高

  • 靈活度高

  • 可讀性高

  • 封裝效果好

  • 優雅!

Decorator!

def 裝飾器名稱(回傳函式名稱):
    def 內部函式名稱():
        #你想做的事
        #...
  	回呼函式名稱()
    return 內部函式 
#上面這些是裝飾器
  
@裝飾器名稱
def 函式名稱:
    #blablabla
函式名稱()#呼叫經修飾後的函式

修飾器~

import time
def timecounter(func):
    def wrap():
        tstart = time.perf_counter()
        func()
        tend = time.perf_counter()
        ttotal = tend-tstart #計算函式執行時間
        print(ttotal//1)
    return wrap
def caculate():
    sum=0
    for i in range(10001):
        sum +=i
    print(sum)
def iamhappy():
    print("I like python!!!")
    time.sleep(3)
    
timecounter(caculate)() #wrap()
timecounter(iamhappy)()
# 500500 0.0 I like python!!! 3.0

語法糖~@

import time
def timecounter(func):
    def wrap():
        fstart = time.perf_counter()
        func()
        fend = time.perf_counter()
        ftotal = fend-fstart
        print(ftotal//1)
    return wrap
  
@timecounter
def caculate():
    sum=0
    for i in range(10001):
        sum +=i
    print(sum)
    
@timecounter
def iamhappy():
    print("I like python!!!")
    time.sleep(3)

caculate()
iamhappy()
# 500500 0.0 I like python!!! 3.0
#蛤?你說很沒用?

感覺很好吃?

decorator的順序性

import time
def timecounter(func):
    def wrap():
        fstart = time.perf_counter()
        func()
        fend = time.perf_counter()
        ftotal = fend-fstart
        print(ftotal//1)
    return wrap
def hello(func):
    def something():
        print("hello")
        func()
    return something
  
@timecounter
@hello         #先hello,才timecounter
def iamhappy():
    print("I like python!!!")
    time.sleep(3)

iamhappy()
# hello I like python 3.0

Decorator Factory!

就這樣?我要傳參數怎麼辦?

#定義裝飾器工廠
def 裝飾器工廠名稱(參數1,...):
    def 裝飾器名稱(回傳函式名稱):
        def 內部函式名稱():
            #你想做的事
            #...
            回呼函式名稱()
        return 內部函式 
    return 裝飾器名稱
  
#使用
@裝飾器工廠名稱(參數)
def 函式名稱:
    #blablabla
函式名稱()#呼叫經修飾後的函式

Decorator Factory!

就這樣?我要傳參數怎麼辦?

def wordfactory(string):
    def hello(func):
        def something():
            print(f"{string}")
            func(string+"123")
        return something
    return hello
#使用
var = input()
@wordfactory(var)
def hi(string):
    print(f"{string}")
hi()

模組 module

沒有模組的世界...

  • 重複度高

  • 可讀性低

  • 維護困難

  • 開發效率低

  • 耗費龐大資源

  • 所有code都在同一個檔案

模組!!!

  • 將code拆成多份檔案

  • 使用容易

  • 語法簡潔

  • 組織性高

如何使用?

import 模組
#引入random模組
import random

#使用
模組名稱.想使用的東西的名稱
print(random.randint(1,100))

太長好麻煩?

import 模組 as 名稱
#引入random模組
import random as rd

#使用
名稱.想使用的東西的名稱
print(rd.randint(1,100))

還是太長不喜歡?

from 模組 import 想使用的東西的名稱
#引入random模組
from random import randint

#使用
想使用的東西的名稱
print(randint(1,100))

還能再更短嗎?

from 模組 import 想用東西的名稱 as 名稱 
#引入random模組
from random import randint as rdi

#使用
想使用的東西的名稱
print(rdi(1,100))

python 內建模組

import random
#可以生出隨機變數的模組
print(random.random())

.random() 生成隨機 0-1 之間的小數

python 內建模組

import random
#可以生出隨機變數的模組
print(random.randint(1, 1000)) #900
print(random.randint(1, 5)) #1

.randint(a, b) 生成隨機 a-b 之間的整數

python 內建模組

import random
#可以生出隨機變數的模組
list = ['a', 'b', 'c', 'd', 'e']
print(random.choice(list)) #e

.choice(list) 可以從串列裡面隨機挑一項

python 內建模組

import random
#可以生出隨機變數的模組
list = ['a', 'b', 'c', 'd', 'e']
random.shuffle(list)
print(list) #['d', 'a', 'b', 'e', 'c']

.shuffle(list) 可以從串列裡面隨機挑一項

python 內建模組

import time
#內含跟時間功能有關的模組
import time
print(time.time()) #1668069093.5578256

.time() 回傳從1970年1月1日0時0分0秒以來的時間(aka Unix time)

python 內建模組

print("hello")
time.sleep(2)
print("hello")

.sleep(t) 讓程式暫時停止t秒

import time
#內含跟時間功能有關的模組

python 內建模組

import calendar
#跟年曆有關的東西的模組
print(calendar.calendar(2022)

.month(month) 回傳該年的年曆

python 內建模組

import calendar
#跟年曆有關的東西的模組
print(calendar.month(2022, 11))

.month(year, month) 回傳該月的月曆

自訂模組

自訂模組

  • 每一個.py檔案都是一個模組

  • 可以直接引用

  • 把要引用文件放在同一個目錄下

自製模組

#hello.py
def hello():
    print("hello!")
#main.py
import hello
hello.hello()
#hello!

自製模組

#hello.py
def hello():
    print("hello!")
#main.py
import hello
hello.hello()
#hello!

運行自製模組

#hello.py
def hello():
    print("hello!")
    
if __name__ == "__main__":
    print("I am working!")

如果我不加...

#hello.py
def hello():
    print("hello!")
    

print("I am working!")

套件 package

套件 package

就是一堆模組在一起!

套件 package

sound/                          Top-level package
      __init__.py               Initialize the sound package
      formats/                  Subpackage for file format conversions
              __init__.py
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py
              ...

要放__init__.py,系統才會偵測這是一個模組

下課啦~~~

import antigravity
Made with Slides.com