面向非程式設計師的 Python 3 教程/定義函式
為了開始本章,我將給你一個你可以做但你不應該做的例子(所以不要把它輸入進去)
a = 23
b = -23
if a < 0:
a = -a
if b < 0:
b = -b
if a == b:
print("The absolute values of", a, "and", b, "are equal.")
else:
print("The absolute values of", a, "and", b, "are different.")
輸出為
The absolute values of 23 and 23 are equal.
這個程式看起來有點重複。程式設計師討厭重複的事情——畢竟,這就是計算機存在的意義!(還要注意,求絕對值改變了變數的值,這就是為什麼輸出中列印的是 23,而不是 -23。)幸運的是,Python 允許你建立函式來消除重複。以下是重寫的示例
a = 23
b = -23
def absolute_value(n):
if n < 0:
n = -n
return n
if absolute_value(a) == absolute_value(b):
print("The absolute values of", a, "and", b, "are equal.")
else:
print("The absolute values of", a, "and", b, "are different.")
輸出為
The absolute values of 23 and -23 are equal.
這個程式的關鍵特徵是 def 語句。def(定義的縮寫)開始一個函式定義。def 後面跟著函式名 absolute_value。接下來是一個 '(',後面跟著引數 n(當函式被呼叫時,n 從程式傳遞到函式)。冒號後面的語句在使用函式時執行。這些語句一直持續到縮排的語句結束或遇到 return。return 語句將一個值返回到呼叫函式的地方。我們已經在第一個程式中遇到了一個函式,即 print 函式。現在我們可以建立新的函數了。
注意 a 和 b 的值沒有改變。函式可以用來重複不返回值的任務。以下是一些示例
def hello():
print("Hello")
def area(width, height):
return width * height
def print_welcome(name):
print("Welcome", name)
hello()
hello()
print_welcome("Fred")
w = 4
h = 5
print("width =", w, " height =", h, " area =", area(w, h))
輸出為
Hello Hello Welcome Fred width = 4 height = 5 area = 20
這個例子展示了你可以用函式做的一些事情。注意你可以使用 0 個引數或 2 個或更多引數。還要注意,當函式不需要返回一個值時,返回是可選的。
在消除重複程式碼時,你經常在重複程式碼中使用變數。在 Python 中,這些變數以一種特殊的方式處理。到目前為止,我們看到的所有變數都是全域性變數。函式有一種特殊的變數型別,稱為區域性變數。這些變數只在函式執行時存在。當局部變數與另一個變數(例如全域性變數)同名時,區域性變數會隱藏另一個變數。聽起來很混亂嗎?好吧,以下這些例子(有點牽強)應該能幫助你弄清楚。
a = 4
def print_func():
a = 17
print("in print_func a =", a)
print_func()
print("a = ", a)
執行後,我們將收到以下輸出
in print_func a = 17 a = 4
函式內部的變數賦值不會覆蓋全域性變數,它們只在函式內部存在。即使 a 在函式內部被賦予了一個新值,這個新賦值的值只對 print_func 有效,當函式執行結束,a 的值再次被列印,我們看到的是最初賦值的值。
以下是一個更復雜的例子。
a_var = 10
b_var = 15
e_var = 25
def a_func(a_var):
print("in a_func a_var =", a_var)
b_var = 100 + a_var
d_var = 2 * a_var
print("in a_func b_var =", b_var)
print("in a_func d_var =", d_var)
print("in a_func e_var =", e_var)
return b_var + 10
c_var = a_func(b_var)
print("a_var =", a_var)
print("b_var =", b_var)
print("c_var =", c_var)
print("d_var =", d_var)
輸出
in a_func a_var = 15
in a_func b_var = 115
in a_func d_var = 30
in a_func e_var = 25
a_var = 10
b_var = 15
c_var = 125
d_var =
Traceback (most recent call last):
File "C:\def2.py", line 19, in <module>
print("d_var = ", d_var)
NameError: name 'd_var' is not defined
在這個例子中,變數 a_var、b_var 和 d_var 在 a_func 函式內部都是區域性變數。在執行語句 return b_var + 10 之後,它們都將不再存在。變數 a_var 自動成為區域性變數,因為它是一個引數名。變數 b_var 和 d_var 是區域性變數,因為它們出現在函式中語句 b_var = 100 + a_var 和 d_var = 2 * a_var 中等號的左側。
在函式內部,a_var 沒有被賦值。當函式被呼叫時,使用 c_var = a_func(b_var),15 被分配給 a_var,因為此時 b_var 為 15,這使得對函式的呼叫 a_func(15)。這最終將 a_var 設定為 15,當它在 a_func 內部時。
如你所見,一旦函式執行結束,隱藏了同名全域性變數的區域性變數 a_var 和 b_var 就消失了。然後語句 print("a_var = ", a_var) 列印值 10 而不是值 15,因為隱藏全域性變數的區域性變數已經消失了。
另一件需要注意的是最後發生的 NameError。這似乎是因為變數 d_var 不再存在,因為 a_func 已經結束。所有區域性變數都在函式退出時被刪除。如果你想從函式中獲取東西,那麼你必須使用 return something。
最後要注意的是,e_var 的值在 a_func 內部保持不變,因為它不是一個引數,它從未出現在 a_func 函式內部等號的左側。當全域性變數在函式內部被訪問時,它來自外部的全域性變數。
函式允許區域性變數,這些變數只存在於函式內部,並且可以隱藏函式外部的其他變數。
temperature2.py
#! /usr/bin/python
#-*-coding: utf-8 -*-
# converts temperature to Fahrenheit or Celsius
def print_options():
print("Options:")
print(" 'p' print options")
print(" 'c' convert from Celsius")
print(" 'f' convert from Fahrenheit")
print(" 'q' quit the program")
def celsius_to_fahrenheit(c_temp):
return 9.0 / 5.0 * c_temp + 32
def fahrenheit_to_celsius(f_temp):
return (f_temp - 32.0) * 5.0 / 9.0
choice = "p"
while choice != "q":
if choice == "c":
c_temp = float(input("Celsius temperature: "))
print("Fahrenheit:", celsius_to_fahrenheit(c_temp))
choice = input("option: ")
elif choice == "f":
f_temp = float(input("Fahrenheit temperature: "))
print("Celsius:", fahrenheit_to_celsius(f_temp))
choice = input("option: ")
else:
choice = "p" #Alternatively choice != "q": so that print
#when anything unexpected inputed
print_options()
choice = input("option: ")
示例執行
Options: 'p' print options 'c' convert from celsius 'f' convert from fahrenheit 'q' quit the program option: c Celsius temperature: 30 Fahrenheit: 86.0 option: f Fahrenheit temperature: 60 Celsius: 15.5555555556 option: q
area2.py
#! /usr/bin/python
#-*-coding: utf-8 -*-
# calculates a given rectangle area
def hello():
print('Hello!')
def area(width, height):
return width * height
def print_welcome(name):
print('Welcome,', name)
def positive_input(prompt):
number = float(input(prompt))
while number <= 0:
print('Must be a positive number')
number = float(input(prompt))
return number
name = input('Your Name: ')
hello()
print_welcome(name)
print()
print('To find the area of a rectangle,')
print('enter the width and height below.')
print()
w = positive_input('Width: ')
h = positive_input('Height: ')
print('Width =', w, ' Height =', h, ' so Area =', area(w, h))
示例執行
Your Name: Josh Hello! Welcome, Josh To find the area of a rectangle, enter the width and height below. Width: -4 Must be a positive number Width: 4 Height: 3 Width = 4 Height = 3 so Area = 12
重寫上面示例中的 area2.py 程式,使其包含一個單獨的函式來計算正方形的面積、矩形的面積和圓形的面積(3.14 * radius**2)。這個程式應該包含一個選單介面。
def square(L):
return L * L
def rectangle(width , height):
return width * height
def circle(radius):
return 3.14159 * radius ** 2
def options():
print()
print("Options:")
print("s = calculate the area of a square.")
print("c = calculate the area of a circle.")
print("r = calculate the area of a rectangle.")
print("q = quit")
print()
print("This program will calculate the area of a square, circle or rectangle.")
choice = "x"
options()
while choice != "q":
choice = input("Please enter your choice: ")
if choice == "s":
L = float(input("Length of square side: "))
print("The area of this square is", square(L))
options()
elif choice == "c":
radius = float(input("Radius of the circle: "))
print("The area of the circle is", circle(radius))
options()
elif choice == "r":
width = float(input("Width of the rectangle: "))
height = float(input("Height of the rectangle: "))
print("The area of the rectangle is", rectangle(width, height))
options()
elif choice == "q":
print(" ",end="")
else:
print("Unrecognized option.")
options()