Published 12月 11, 2018 by with 0 comment

Automate The Boring Stuff With Python - Chapter 3 - 函數


今天是看這本書Automate the Boring Stuff with Python(Python編程快速上手--讓繁瑣工作自動化)
第3章節(Functions)所做的練習

這章節有幾個重點
局部作用域(Local Scope):
當一個函數被調用時, 就創建了一個局部作用域. 在這涵數內賦值的所有變量, 都只存在於該局部作用域內.

全局作用域(Global Scope):
就是除了在涵數以外, 在整個程式範圍內. 在這範圍內, 就是全局作用域.

局部變量(Local variable):
處於局部作用域的變量.

全局變量(Global variable):
處於全局作用域的變量.

這些作用域與變量有下列規則:
1. 變量不能既是局部又是全局, 只能是其中一種.
2. 局部變量不能在全局作用域中被使用.
3. 局部作用域不能其他局部作用域的局部變量.
4. 局部作用域可以使用全局變量
5. 局部變量與全局變量名稱可以一樣.

以下是程式示範
2. 局部變量不能在全局作用域中使用.
def spam():
    eggs = 31337
spam()
print(eggs)

------以下為輸出------
Traceback (most recent call last):

  File "C:/Users/Peter/PycharmProjects/untitled2/test.py", line 4, in 
    print(eggs)
NameError: name 'eggs' is not defined

說明:
程式一開始執行spam(), 然後他會去找涵數def spam(),
涵數spam內定義了eggs = 31337, 這是屬於局部作用域內的局部變量(eggs).
然後從spam返回全局作用域時, 原本的局部作用域spam銷毀了.
該局部作用域內的局部變量(eggs)也跟著消失了.
所以當print(eggs)時. 程式找不到eggs的定義.


3. 局部作用域不能其他局部作用域的局部變量.
def spam():
    eggs = 99
    bacon ()
    print(eggs)
def bacon():
    ham = 101
    eggs = 0
spam()

------以下為輸出------
99

說明:
程式一開始執行涵數spam(), 然後他會去找涵數def spam(),
發現局部變量eggs = 99, 然後調用另一個涵數bacon.
在第二個局部作用域涵數bacon中. 發現ham = 101 及 eggs = 0.
然後從涵數bacon跳出返回涵數spam, 此時局部作用域bacon就銷毀了.
ham = 101 及 eggs = 0的局部變量也被銷毀了.
返回涵數spam後, 印出eggs數值, 此時eggs = 99.


4. 局部作用域可以使用全局變量
def spam():
    print(eggs)
eggs = 42
spam()
print(eggs)

------以下為輸出------
42
42

說明:
程式一開始定義全局變量eggs = 42,
然後調用涵數spam(),
在局部作用域spam()中, 要印出eggs的值.
所以局部作用域使用全局變量印出42.
然後返回. 返回時局部作用域spam被銷毀.
然後再要印出eggs值, 所以全局變量eggs不受局部作用域spam被銷毀的影響
仍印出42之值.


5. 局部變量與全局變量名稱可以一樣.
def spam():
    eggs = 'spam local'
    print('1: ' + eggs)
def bacon():
    eggs = 'bacon local'
    print('2: ' + eggs)
    spam()
    print('3: ' + eggs)

eggs = 'global'
bacon()
print('4: ' + eggs)

------以下為輸出------
2: bacon local
1: spam local
3: bacon local
4: global

說明:
一開始定義了全局變量eggs = 'global',
然後調用涵數bacon, 建立一個局部作用域bacon,
在第一個局部作用域bacon中, 建立局部變量eggs ='bacon local', 並印出
然後調用第二個局部作用域sapm, 建立局部變量eggs = 'spam local', 並印出.
印完後返回第一個局部作用域bacon, 所以第二個局部作用域sapm就被銷毀了.
再印一次eggs, 仍就會是eggs = 'bacon local'
然後在回來全局作用域, 此時第一個局部作用域bacon就被銷毀了.
再印一次就是全局變量eggs = 'global'.


最後global, 如果需要在一個涵數內修改全局變量, 就用global
def spam():
    global eggs
    eggs = 'spam local'
eggs = 'spam global'
spam()
print(eggs)

------以下為輸出------
spam local

說明:
一開始全局作用域定義了全局變量eggs = 'spam global',
然後調用spam涵數, 創建了局部作用域spam
在局部作用域中用global語句修改了eggs, 使全局變量eggs 改為spam local
返回全局作用域, 則局部作用域spam銷毀.
印出已被修改過的全局變量eggs = 'spam local'


章節3習題, 用Notepad++打下列的程式碼,
另存為Chapter_3.py. 我附上中文注釋方便好讀.
# -*- coding: UTF-8 -*-
# http://juilin77.blogspot.com/
# v20181212
# Automate The Boring Stuff With Python - Chapter 3

# 定義一個涵數叫collatz, 
# 如果參數除2的餘數為0, 該參數就是偶數
# 偶數就返回一個參數除2的商數之值
# 如果參數除2的餘數不為0, 該參數就是奇數
# 奇數就返回一個參數*3再加1之值
def collatz(number):
    if number % 2 == 0:
        return number // 2
    else:
        return 3 * number + 1

try:
# 輸入一個整數
    number = int(input('Enter a number:\n'))
    while True:

# 當返回值不等於1, 再把返回值代進collatz(number)
        if collatz(number) != 1:
            number = collatz(number)
            print(number)

# 當返回值等於1, 則印出1, 結束程式.
        else:
            print('1')
            break

# 若輸入的值不是整數, 則印出Type an Integer!!!, 結束程式.
except ValueError:
    print('Type an Integer!!!')

然後用Windows的cmd, 執行python.
D:\Tech\Python\Automate The Boring Stuff With Python>python Chapter_3.py
Enter a number:
3
10
5
16
8
4
2
1

D:\Tech\Python\Automate The Boring Stuff With Python>

完成

Reference:
Automate the Boring Stuff with Python
Python编程快速上手:让繁琐工作自动化
ISBN-10: B01N6B9BSA
https://www.amazon.com/Python%E7%BC%96%E7%A8%8B%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B-%E8%AE%A9%E7%B9%81%E7%90%90%E5%B7%A5%E4%BD%9C%E8%87%AA%E5%8A%A8%E5%8C%96-%E7%BE%8E-Al-Sweigart%EF%BC%88%E6%96%AF%E7%BB%B4%E5%8A%A0%E7%89%B9%EF%BC%89/dp/B01I0XN8XY/ref=sr_1_1?ie=UTF8&qid=1543814481&sr=8-1&keywords=9787115422699

官網:
https://automatetheboringstuff.com/

最初發表 / 最後更新: 2018.12.11 / 2018.12.11

0 comments:

張貼留言