Python

function 

講師 - 呂家睿

  • 建中資訊38屆學術長+副社
  • 玩原神跟雀魂
  • 頭像是應急食品
  • 被電爛
  • 有問題歡迎來問我啊
  • C++
  • python
  • 競程是什麼可以吃嗎?
  • 數學好難
  • 雖然很菜但喜歡遊戲開發
  • 打開電腦

學術力

function

函式

function(函式)

把一段程式碼打包起來,給它一個名字,之後可以重複使用。

Ex : print(), input()

名稱

回傳值

參數值

參數值

function(函式)

把一段程式碼打包起來,給它一個名字,之後可以重複使用。

def hello():
	print("hello")
    print("world")
    
hello()

宣告函式

呼叫函式

名字

這個函式裡面的程式記得縮排

參數(parameter)

用來接收外面傳進來的資料

def add(a, b):
	print(a+b)
    
add(10, 11)

現在試試看在後面加一行

print(a, b)

區域變數 vs 全域變數

在程式最外層宣告的變數,可以在整個程式裡使用。

在函式裡面宣告的變數,只能在函式裡面用

a = 0
def eat(a):
  global b = 10
  c = 10
  print("eat", a)
  print(b, c)

print(a)
print(c)
print(b)

飯粒

回傳值(return value)

可以把一個值傳回來

通常傳回來的是執行得到的結果

def add(a, b):
	return a+b
    
print(add(1, 10))

會回傳 a+b的值也就是11

more function

函式++

type

def intro(age:int, name:str) -> None:
  print("Hello, my name is", name)
  print("And I am", age, "years old")
 
intro(88888888, "aaaaaaaa")

參數的型態

回傳值的型態

所以說嚴格來講他只能輔助你,實際上如果你亂傳參數他也會照樣跑

預設值和關鍵字引數

如果呼叫沒有給引數的話就會用預設值

 

你可以使用關鍵字引數來指定參數名稱

def intro(age = 0, name = "a") -> None:
  print("Hello, my name is", name)
  print("And I am", age, "years old")
 
intro(88888888, "aaaaaaaa")
intro()
intro(10)
intro(name = "tree")

*args & **kwargs

可挖格斯

處理可變數量的引數

存在元組(tuple)裡

def intro(*args, **kwargs):
    message = "Hello, "
    message += " ".join(args)
    message += " Details: " + ", ".join(f"{key} = {value}" for key, value in kwargs.items())
    return message


print(intro("super", "idol", "的", "笑容", age = 8, name = "月", hobby = "正午的陽光"))

阿格斯

處理可變數量的關鍵字引數

存在字典(dictionary)裡

函式作為物件

def shout(text):
    return text.upper()

f = shout  
print(f("hello"))  

Python 的函式就像其他物件一樣,具有唯一的ID、可以被賦予名稱並儲存於變數中。 

遞迴(recursion)

def factorial(n):
	if n == 0:
		return 1
	return n*factorial(n-1)

print(factorial(5))

遞迴的基本概念是"可以在一個函式call自己"

會有一個最基本的狀態,叫做base case

base case

call 自己

lambda λ

lambda λ

def square(x):
    return x * x
print(square(5))
square = lambda x: x*x
print(square(5))

一樣是函式,但是比較短的寫法

特色:短、沒有名字

參數

函式內容

lambda λ

def add_1(a, b):
    return a+b
  
add_2 = lambda a, b: a+b

print(add_1(5,6), add_2(5,6))

怕你們覺得lambda有點抽象,所以再給一個飯粒

lambda 常見用途

lambda通常搭配其他函式使用

比如說sort

words = ["apple", "banana", "kiwi"]
print(sorted(words, key=lambda w: len(w)))
nums = [1, 2, 3, 4, 5]
squares = list(map(lambda x: x*x, nums))
print(squares)

根據字的長度排序

把每個元素平方

小明打算要唱熱愛105度的你,但是他不小心把歌詞打亂了(而且是每個字都打亂了)

請你幫他組回正確的歌詞!

lyrics = {"super": 1, "的": 3, "笑": 4, "idol": 2, "眼": 22, "沒":7, "陽": 16, "正": 13,"der":15, "do":18,"都": 6, "光": 17,"耀":21, "mei":19, "你":8, "ni":20, "午":14, "容": 5, "derr": 9, "甜": 10, "八": 11, "月": 12}

亂掉的歌詞在這裡

練習題

答案

lyrics = {"super": 1, "的": 3, "笑": 4, "idol": 2, "眼": 22, "沒":7, "陽": 16, "正": 13,"der":15, "do":18,"都": 6, "光": 17,"耀":21, "mei":19, "你":8, "ni":20, "午":14, "容": 5, "derr": 9, "甜": 10, "八": 11, "月": 12}
sorted_lyrics = sorted(lyrics, key=lambda k: lyrics[k])
print(" ".join(sorted_lyrics))
def get_lyrics_value(key):
    return lyrics[key]

lyrics = {"super": 1, "的": 3, "笑": 4, "idol": 2, "眼": 22, "沒":7, "陽": 16, "正": 13,"der":15, "do":18,"都": 6, "光": 17,"耀":21, "mei":19, "你":8, "ni":20, "午":14, "容": 5, "derr": 9, "甜": 10, "八": 11, "月": 12}
print(sorted(lyrics, key=get_lyrics_value))

以防萬一有人真的不想用lambda

decorator

裝飾器

decorator(裝飾器)

  • 把一個函式包在另外一個函式外面
  • 不會影響裡面的函式
  • "裝飾"這個函式

decorator

decorator

function

function

decorator

decorator(裝飾器)

def print_function_name(func):
    def wrapper():
        print("Using function: " + func.__name__)
        func()
    return wrapper

def dog():
    print("bark!")

def cat():
    print("meow~")

dog_func_with_name = print_function_name(dog)
cat_func_with_name = print_function_name(cat)
dog_func_with_name()
cat_func_with_name()

沒錯你可以把函式當參數

函式的名稱

把它包起來

執行被包起來的函式

記住,function是一個物件

寫起來好長

decorator(裝飾器)

def print_function_name(func):
    def wrapper():
        print("Using function: " + func.__name__)
        func()
    return wrapper

@print_function_name
def dog():
    print("bark!")

@print_function_name
def cat():
    print("meow~")

cat()
dog()

這樣就像正常依樣執行函式了

語法糖 :

在你包的函式前面 @裝飾器函式

有參數的函式

def print_function_name(func):
    def wrapper(*args, **kwargs):
        print("Using function: " + func.__name__)
        func(*args, **kwargs)
    return wrapper

@print_function_name
def dog(times):
    for i in range(times):
        print("bark!")

@print_function_name
def cat():
    print("meow~")

cat()
dog(10)

通常我們會用*args, **kwargs來保持彈性

有參數的裝飾器

import time
def print_function_name(show_time = False):
    def decorator(func):
        def wrapper(*args, **kwargs):
            print("Start time " + time.ctime())
            print("Using function: " + func.__name__)
            func(*args, **kwargs)
            print("End time " + time.ctime())
        return wrapper
    return decorator

@print_function_name(show_time = True)
def dog(times):
    for i in range(times):
        print("bark!")

@print_function_name()
def cat():
    print("meow~")

cat()
dog(10)

基本上就是多包一層

就像寫一般函式帶參數

好幾層裝飾器

def decorator_1(func):
    def wrapper():
        print("Decorator 1 start")
        func()
        print("Decorator 1 end")
    return wrapper

def decorator_2(func):
    def wrapper():
        print("Decorator 2 start")
        func()
        print("Decorator 2 end")
    return wrapper

@decorator_1
@decorator_2
def my_func():
    print("Function is functioning")

my_func()

decorator_1

decorator_1

decorator_2

decorator_2

my_func

下課!!!!!

Made with Slides.com