0% found this document useful (0 votes)
49 views48 pages

基礎 Python Part04 - 函式

Uploaded by

f07945052
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
49 views48 pages

基礎 Python Part04 - 函式

Uploaded by

f07945052
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 48

基礎 Python

李智揚

1
函式
function

2
function 函式(函數)
● 將重複使用的程式碼包裝在函式中使用
● 函式有名稱、包含獨立的程式片段
● 可以接收任意數量和型態的輸入參數(parameters)
● 可回傳(return)任何數量與型態的輸出結果

定義函式 函式名稱 輸入參數


(definition)

def myFunction(參數0, 參數1, …):



return 結果
3
呼叫函式
def greeting():
print('Hello~')
return

greeting() # 使用小括號呼叫函式
# Hello~

4
利用回傳值
def agree():
return True

if agree():
print('I Agree!')
else:
print('I Disagree')

# I Agree!

5
練習題

寫一個函數 calculate_sum(),該函數會計算並返回從 1 到
10 的整數總和。

HINT: 55

6
函式引數(arguments)與參數(parameters)
def echo(string):
return f'{string} ~~~~~ {string}'

echo_str = echo('LaLaLa')
print(echo_str)
# LaLaLa ~~~~~ LaLaLa

1. 使用echo函式,並將字串作為引數(arguments)傳入函式
2. 在函式中,以string參數代表外部傳入引數
3. 使用string參數進行運算,並返回運算成果

7
函式回傳值
def add_and_multiply(a, b):
return a+b, a*b

values = add_and_multiply(3, 2)
print(values) # (5, 6)

add, multiply = values


print(add, multiply) # 5 6

add, multiply = add_and_multiply(3, 2)


print(add, multiply) # 5 6

8
試試看
撰寫函式,接受矩形的長和寬作為參數,並同時回傳面積和周長

a, b = rectangle(1, 2)
a # 2
b # 6

9
None
通常inplace函式不會return (None)
● 空值、缺失值、沒有有效值或未知值 my_list.sort()
● type: NoneType my_list.append()
● 作為預設函式返回 值 …
● 初始化變數時未知初始 值

def empty_function(): my_variable = None


return # ...
my_variable = 56
result = empty_function()
print(result) # None

10
None: 檢查None
thing = None
if thing:
print("Something")
else:
print("No thing")
# No thing

thing = None
if thing is None:
print("Nothing")
else:
print("Something")
# Nothing

11
試試看
def whatisit(thing):
if thing is None:
print(f'{thing} is None')
elif thing:
print(f'{thing} is True')
else:
print(f'{thing} is False')

# 使用以上函式測試以下的值
None, True, False,
0, 0.0, '', (), [], {}, set(),
0.01, [0], [''], ' '

12
位置引數 positinal argument
def menu(starter, main, dessert):
return {
'starter': starter,
'main': main,
'dessert': dessert
}

print(menu('salad', 'steak', 'icecream'))


# {'starter': 'salad', 'main': 'steak', 'dessert': 'icecream'}

print(menu('icecream', 'steak', 'salad'))


# {'starter': 'icecream', 'main': 'steak', 'dessert': 'salad'}

13
關鍵字引數 keyword argument
def menu(starter, main, dessert):
return {
'前菜': starter,
'主菜': main,
'甜點': dessert
}

print(menu(main='steak', dessert='icecream', starter='salad'))


# {'前菜': 'salad', '主菜': 'steak', '甜點': 'icecream'}

# 混用位置+關鍵字引數
print(menu('salad', dessert='icecream', main='steak'))

14
預設參數值
def menu(starter, main, dessert='pudding'):
return {'前菜': starter, '主菜': main, '甜點': dessert}

print(menu('salad', 'steak'))
# {'前菜': 'salad', '主菜': 'steak', '甜點': 'pudding'}

print(menu('salad', 'steak', 'tiramisu'))


# {'前菜': 'salad', '主菜': 'steak', '甜點': 'tiramisu'}

15
試試看
題目:生成一個帶有問候語的字串
輸入:姓名
輸入:問候語,預設值: Hey
輸入:結尾符號,預設值: !
輸出:字串
result = generate_greeting("Bob", "Hi")
print(result) # 輸出: Hi, Bob!

result = generate_greeting("Charlie", "Greetings", "?")


print(result) # 輸出: Greetings, Charlie?

result = generate_greeting("Apple")
print(result) # 輸出: Hey, Apple!
16
* :解開束縛,收集位置引數
def print_args(*args):
print("Positional args tuple: ", args)
def print_args(*params):
print("Positional args tuple: ", params)

print_args()
# Positional args tuple: ()

print_args('a')
# Positional args tuple: ('a',)

print_args('a', 'b', 'c')


# Positional args tuple: ('a', 'b', 'c')

17
*args: 接受動態數量引數
def use_dynamic_args(require0, require1, *args):
print('Require0: ', require0)
print('Require1: ', require1)
print('Others: ', args)

use_dynamic_args('Hi', 'Hey', 'Hello', 'Yo bro')


# Require0: Hi
# Require1: Hey
# Others: ('Hello', 'Yo bro')

18
*args 解開包裝進階用法
def use_dynamic_args(require0, require1, *args):
print('Require0: ', require0)
print('Require1: ', require1)
print('Others: ', args)

use_dynamic_args('a', 'b', 'c')


# Require0: a
# Require1: b
# Others: ('c',)
args = (3, 4)
use_dynamic_args(1, 2, args) # use_dynamic_args(1, 2, (3, 4))
# Require0: 1
# Require1: 2
# Others: ((3, 4),)
use_dynamic_args(1, 2, *args) # use_dynamic_args(1, 2, 3, 4)
# Require0: 1
# Require1: 2
# Others: (3, 4)
19
**kwargs 解開束縛,收集關鍵字引數
def print_kwargs(**kwargs):
print(f'print_kwargs: {kwargs}')

print_kwargs()
# print_kwargs: {}
print_kwargs(main='steak', dessert='icecream', starter='salad')
# print_kwargs: {'main': 'steak', 'dessert': 'icecream', 'starter': 'salad'}

20
引數順序
def print_menu(drink, *args, **kwargs):
print(f'單點: {drink}')
for arg in args:
print(f'加點: {arg}')
for key, value in kwargs.items():
print(f'{key}: {value}')

print_menu('珍珠奶茶', '椰果', '芋圓', ice='少冰', sugar='微糖')

# 單點: 珍珠奶茶
# 加點: 椰果
# 加點: 芋圓
# ice: 少冰
# sugar: 微糖

21
試試看
寫一個函式 dynamic_adder,它可以接受不定數量的參數,並回傳它們的總和。

result = dynamic_adder(1)
print(result) # 1

result = dynamic_adder(1, 2)
print(result) # 3

result = dynamic_adder(1, 2, 3)
print(result) # 6

22
內部函式:函式 in 函式
def outer_func(a, b):
def inner(c, d):
return c + d
return inner(a, b)
outer_func(2, 3) # 5

def add_two_even(a, b):


def make_even(x):
return x // 2 * 2

return make_even(a) + make_even(b)

add_two_even(2, 3) # 4

23
__name__, __doc__
def myFunc():
'''我的函式 自己做主'''
print('The name of this function: ', myFunc.__name__)
print('The docstring is: ', myFunc.__doc__)

myFunc()
# The name of this function: myFunc
# The docstring is: 我的函式 自己做主

24
lambda: 匿名函式
lambda arguments: expression
numbers = [1, 2, 3, 4]

def add_100_to_numbers(numbers, func):


for n in numbers:
print(func(n))

def add_100(a):
return a+100

add_100_to_numbers(numbers, add_100)
add_100_to_numbers(numbers, lambda n: n+100)
# 101
# 102
# 103 ● 將lambda函式當作輸入引數
# 104
● 此lambda函式接收一個輸入引數
● 輸出: 引數+100
25
lambda: 匿名函式
lambda x, y: x + y
# v.s
def add(x, y):
return x+y

is_even = lambda x: x % 2 == 0
print(is_even(7)) # 輸出: False
(lambda x: x % 2 == 0)(7) # 輸出: False

names = ['Alice', 'Bob', 'Charlie', 'David']


names.sort(key=lambda x: len(x))
print(names) # 輸出: ['Bob', 'Alice', 'David', 'Charlie']

26
名稱空間(namespace) 與 作用域(scope)
name = 'Eric'
def print_global():
print('inside global: ', name)

print('at top level: ', name)


# at top level: Eric
print_global()
# inside global: Eric

27
名稱空間(namespace) 與 作用域(scope)
name = 'Eric'
def change_name():
print('inside global: ', name)
name = 'Messi'
print('change name: ', name)

change_name()
# UnboundLocalError: local variable 'name' referenced before assignment

28
作用域(scope)
name = 'Eric'
def change_name():
name = 'Messi'
print('change name: ', name)

change_name()
# change name: Messi
print('at top level: ', name)
# at top level: Eric

29
作用域(scope): global
name = 'Eric'
def change_name():
global name
name = 'Messi'
print('change name: ', name)

change_name()
# change name: Messi Clarity is better than obscurity
print('at top level: ', name)
明確勝於晦暗

# at top level: Messi


30
遞迴 (recursion)
def fibonacci(n):
if n <= 1:
return n
a, b = 0, 1
for _ in range(2, n+1):
a, b = b, a + b
return b

for i in range(6):
print(fibonacci(i))

# 0, 1, 1, 2, 3, 5

31
遞迴 (recursion)
def fibonacci(n):
if n <= 1:
return n
else:
return fibonacci(n-1) + fibonacci(n-2)

for i in range(6):
print(fibonacci(i))

# 0, 1, 1, 2, 3, 5
To iterate is human, to recursive, divine!
遞迴只應天上有,凡人應當用迴圈
L Peter Deutsch

32
例外處理
myList = [1, 2, 3, 4]

index = 5566

myList[index]

# IndexError: list index out of range

33
例外處理:try / except
myList = [1, 2, 3, 4]
index = 5566
try:
myList[index]
except:
print(f'爆炸啦! 0 < index < {len(myList)}')

# 爆炸啦! 0 < index < 4

34
例外處理:try / except
myList = [1, 2, 3, 4]
while True:
value = input("輸入位置: [q 結束]: ")
if value == 'q':
break
try:
index = int(value)
print(myList[index])
except IndexError as error:
print('Wrong index: ', index)
except Exception as other_error:
print('Something is wrong: ', other_error)
finally:
print('Finally') # 無論如何都會執行

# 輸入位置: [q 結束]: 4
# Wrong index: 4
# Finally
# 輸入位置: [q 結束]: sdaf
# Something is wrong: invalid literal for int() with base 10: 'sdaf'
# Finally 35
進階函式

36
函式: 一級公民 def favorite():
print('Messi')
● 可當作變數
● 可當作引數 favorite() # Messi
● 可當作返回值
● 可儲存在資料結構中 # 傳入favorite本身
# 不是favorite()執行完的結果
# 在say中執行輸入的引數,引數是個函式
def say(func):
func()
say(favorite) # Messi

type(say) # function
type(favorite) # function

37
透過傳入的函式改變行為
def do_something(func, args0, args1):
print(func(args0, args1))

def add(a, b):


return a+b

def to_string(a,b):
return str(a) + str(b)

do_something(add, 3, 6) # 9
do_something(to_string, 3, 6) # 36

38
生成器 generator:動態生成值
● 製作序列的物件
● 可用來迭代大型序列,使用較少量記憶體
● 可記憶狀態
● e.g: range(start, stop, step)

def my_range(first=0, last=5, step=1): for i in my_range():


number = first print(i)
while number < last: # 0
yield number # 1
number += step # 2
# 3
# 4

39
裝飾器 decorator:為函式加上額外功能
# 定義一個簡單的裝飾器
def my_decorator(func):
def wrapper():
print("Before function call")
func()
print("After function call")
return wrapper

# 使用裝飾器
@my_decorator
def say_hello():
print("Hey Apple!")

# 呼叫被裝飾後的函數
say_hello()

40
裝飾器 decorator:為函式加上額外功能
# 定義一個簡單的裝飾器
def say_first(func):
def wrapper():
print(f"要用 {func.__name__} 要早說")
func()
print("晚了就不要了")
return wrapper

# 使用裝飾器
@say_first
def say_hello():
print("Hey Apple!")

# 呼叫被裝飾後的函數
say_hello()

# 要用 say_hello 要早說
# Hey Apple!
41
# 晚了就不要了
裝飾器 decorator:為函式加上額外功能
def document_func(func):
def new_func(*args, **kwargs):
print('執行函式:', func.__name__)
print('位置引數', args)
print('關鍵字引數', kwargs)
result = func(*args, **kwargs)
print('Result: ', result)
return result
return new_func

@document_func
def add_two(a, b): 執行函式: add_two
return a+b
位置引數 (100, 23)
add_two(100, 23) 關鍵字引數 {}
Result: 123
123
42
試試看
定義一個名叫testMicrophone的裝飾器,用它在一個函式被呼叫時印出"test 1, 2, 3
麥克風測試 ",函式結束時印出"麥克風測試完畢 "

被裝飾的函式自訂,或用以下函式

def myFunc():
print("太神啦~~~")

43
試試看
撰寫一個例外處理:當捕捉到除法的除數為0時,印出"分母不可為0"

Hint: 可以先弄爆你的除法,取得該錯誤的種類

44
Python 常用內建函式

45
Python 內建函式

Build-in functions

46
eval, exec: 執行動態程式碼
# 執行程式碼
result = eval('1+2+3')
print(result) # 6

# 將字串中的變數當成程式碼執行
x = 1
result = eval('x+1')
print(result) # 2

# 執行函式/使用類別
eval('print("hello")') # hello

# 轉換成數字
age = input("age: ")
a = eval(age)
print(a, type(a))

47
eval, exec: 執行動態程式碼
code_str = """
x = 15
y = 20
print(x + y)
"""
exec(code_str) # 35

使用動態執行方法時,要小心!

48

You might also like