2014-08-28 42 views
0

我正在學習Python。我讀包含像這樣一些代碼:Python:爲特定功能創建臨時名稱

class Menu: 
    '''Display a menu and respond to choices when run.''' 
    def __init__(self): 
     self.notebook = Notebook() 
     self.choices = { 
      "1": self.show_notes, 
      "2": self.search_notes, 
      "3": self.add_note, 
      "4": self.modify_note, 
      "5": self.quit 
      } 

    def display_menu(self): 
     print(""" 
Notebook Menu 

1. Show all Notes 
2. Search Notes 
3. Add Note 
4. Modify Note 
5. Quit 
""") 

    def run(self): 
     """Display the menu and respond to choices.""" 
     while True: 
      self.display_menu() 
      choice = input("Enter an option: ") 
      action = self.choice.get(choice) 
      if action: 
       action() 
      else: 
       print("{0} is not a valid choice".format(choice)) 

def show_notes(self): 
    pass 

def search_notes(self): 
    pass 

def add_note(self): 
    pass 

def modify_note(self): 
    pass 

def quit(self): 
    pass 

有一些行非常有趣:

action = self.choice.get(choice) 
if action: 
    action() 

好像它是一個特定函數創建一個臨時名稱。 所以我做了以下測試以瞭解詳情:

>>> def show_notes(): 
    print("show notes") 

>>> def search_notes(): 
    print("search notes") 

>>> choice = {"1": show_notes, "2": search_notes} 
>>> action = choice.get(1) 
>>> action() 

,但我得到了以下錯誤:

Traceback (most recent call last): 
    File "<pyshell#64>", line 1, in <module> 
    action() 
TypeError: 'NoneType' object is not callable 

有人能告訴我的技術是什麼,什麼樣的原則是落後?

回答

5

函數是第一類對象,你可以創建他們額外的引用。這些只是你需要的暫時的,但它們也可以是永久的。

然而你自己的嘗試混淆了字符串和整數;你使用了1(一個整數),其中實際的鍵是'1'(一個字符串)。由於您使用了錯誤的密鑰,因此dict.get() method返回了默認值NoneNone不是函數對象,調用失敗。

假如你用右鍵你的代碼會工作過:

>>> def show_notes(): 
...  print("show notes") 
... 
>>> def search_notes(): 
...  print("search notes") 
... 
>>> choice = {"1": show_notes, "2": search_notes} 
>>> choice['1'] 
<function show_notes at 0x10b1fae18> 
>>> choice['1']() 
show notes 

您可以使用dict.get()這裏也返回默認情況下,通過給該方法更好的默認返回:

>>> choice.get('none-such-key', search_notes)() 
search notes 
1

它不爲函數創建隨機名稱。類方法choice正在選擇一個函數並將其返回,隨後將其分配給變量action。然後通過調用動作來調用該函數,就像任何函數一樣。

下面是一個例子:

def foo(): 
    print(5) 

def getFunction(): 
    return foo 

x = getFunction() 

x() 

從該輸出將是5.

退一步從所有的這種情況,可以任何對象分配給任何變量。因此,考慮下面的例子(我認爲這將有助於你瞭解一點點):

def foo(): 
    print(5) 

bar = foo 
foo = 5 

foo() 

這將產生一個錯誤沿着整數對象的線不調用。其工作方式是將包含在foo中的函數對象分配給變量bar,並將整數5分配給foo。函數沒有改變,但包含它的變量有。

定義函數def foo的第一部分是讓解釋器知道您正在定義函數對象並將其存儲在變量foo中。函數的名稱和機制是分開的。

這是否有意義?

2

看來你的測試有錯誤。你應該得到"1"而不是11正在返回None,因爲沒有爲密鑰1定義任何內容。因此,當你將它稱爲函數時,它是無效的。

澄清,"1"是一個字符串,1是一個整數,它們是不同的鍵。

例子:

>>> a = {"1": "yes"} 
>>> a.get(1) 
>>> a.get("1") 
'yes' 

例II(使用功能):

>>> def hello(): 
...  print "hello" 
... 
>>> hello() 
hello 
>>> a = {"1": hello} 
>>> b = a.get(1) 
>>> b() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: 'NoneType' object is not callable 
>>> b = a.get("1") 
>>> b() 
hello