這回明中增添了八個檢驗規則, 使得總數來到 26 個 (規則 2~27), 因為除了正式運轉要執行這 26 個規則之檢測外, 我另外加寫了一個手動檢測介面, 既然有雙重用途, 所以我將每個規則都改寫成個別的函式, 其中全部檢測功能利用迴圈依序呼叫這 26 個函式, 依據其傳回值來判斷是要丟棄還是納入此字集.
當然可以一個一個呼叫這 26 個函式, 這樣既直觀又簡單, 但我們都知道 simple is stupid, 而且缺乏匠氣, 所以我使用了 eval() 函式透過函式名稱字串來取得函式實體, 這樣程式就不會落落長, 而且顯得既匠氣又專業. 以下用簡化的範例來說明做法 :
測試 1 : 從函式名稱字串取得函式實體
# 有特定命名規則之函式
def rule1():
print('Running rule1.')
def rule2():
print('Running rule2.')
def rule3():
print('Running rule3.')
def rule4():
print('Running rule4.')
# 用串列生程式動態產生函式名稱串列
function_names=[f'rule{i}' for i in range(1, 5)]
print(function_names)
# 用迴圈依序呼叫透過 eval() 從函式名稱字串取得之函式實體
for function_name in function_names:
function=eval(function_name) # 用 eval() 從函式名稱字串取得函式實體
function()
此例的四個函式名稱都是有規則可循的, 所以可以用串列生成式產生函式名稱字串串列, 也可以很方便地用迴圈來逐一呼叫, 但呼叫前必須將函式名稱字串 function_name 傳給 eval(), 它會傳回該字串對應之函式實體, 這樣才能呼叫, 不能直接用字串變數 function_name 呼叫.
執行結果如下 :
>>> %Run eval_function_1.py
['rule1', 'rule2', 'rule3', 'rule4']
Running rule1.
Running rule2.
Running rule3.
Running rule4.
eval() 的妙用還不只如此, 我們可以利用它從名稱字串取得任何物件, 例如 :
測試 2 : 從元件名稱字串取得 tkinter 物件實體
import tkinter as tk
from tkinter import ttk
def change_color():
labels=[f'label_{i}' for i in range(1, 5)]
print(labels)
for idx, label in enumerate(labels):
widget=eval(label)
print(widget)
widget.config(bg='yellow', text='Color changed!')
#建立視窗
root=tk.Tk()
root.title('eval()測試')
root.geometry('300x200') # 設定視窗大小
label_1=tk.Label(root, text='Hello World 1')
label_1.pack()
label_2=tk.Label(root, text='Hello World 2')
label_2.pack()
label_3=tk.Label(root, text='Hello World 3')
label_3.pack()
label_4=tk.Label(root, text='Hello World 4')
label_4.pack()
button=ttk.Button(root, text='確定', command=change_color)
button.pack()
root.mainloop()
此例在視窗上放置了四個 Label 元件與一個按鈕, Label 物件的名稱是有規則的, 所以可以利用 eval() 從元件名稱字串取得元件之實體, 然後方便地使用迴圈來控制這些 Label 的內容, 此處是按下按鈕後更改 Label 的 text 與 bg 屬性, 結果如下 :
沒有留言 :
張貼留言