2015-09-11 22 views
4

我正在用Python寫一個數據庫遷移腳本,其中我創建了一個可以在不同版本之間遷移數據庫的字典。我目前做如下:如何在Python中創建函數的字典?

def from1To2(): 
    pass # migration script here 
def from2To1(): 
    pass # migration script here 
# etc 

migrations = { 
    1: {'up': from1To2}, 
    2: {'down': from2To1, 'up': from2To3}, 
    3: {'down': from3To2, 'up': from3To4}, 
    4: {'down': from4To3}, 
} 

但每次我創建一個新的遷移時間,我需要寫兩個遷移腳本(上下),並把它們在遷徙字典。由於遷移函數非常小(通常是兩行),所以我想直接將它們寫入遷移字典中。在Javascript中,這看起來像這樣:

migrations = { 
    1: { 
     'up': function(){ addSomeColumn(); recordChange(); }, 
     'down': function(){ dropSomeColumn(); recordChange(); } 
    }, 
    2: etc 
} 

因爲遷移函數通常是兩行,所以我不認爲我可以使用lambda函數。有沒有人知道任何其他方式直接在Python的字典中編寫函數?歡迎所有提示!

+0

如果你創建一個lambda列表的字典?像:'migrations = {1:[lambda:add_some_column(),lambda:record_change()]}' –

回答

6

寫定製的裝飾:

migrations = {} 

def migrate(old_version, new_version): 
    assert abs(new_version-old_version)==1 

    def decorator(f): 
     direction = 'up' if new_version > old_version else 'down' 
     if old_version not in migrations: 
      migrations[old_version] = {} 
     migrations[old_version][direction] = f 
     return f 
    return decorator 

@migrate(1, 2) 
def upgrade(): 
    pass # migration script here 

@migrate(2, 1) 
def downgrade(): 
    pass # migration script here 

@migrate(2, 3) 
def upgrade(): 
    pass # migration script here 
# etc 

print(migrations) 

對於其輸出是一樣的東西:

{1: {'up': <function upgrade at 0x02BE4588>}, 2: {'down': <function downgrade at 0x02BE4618>, 'up': <function upgrade at 0x02BE4540>}} 

裝修是負責更新migrations字典,但這樣的功能可以使用任何名稱或者重複使用相同的名稱,或者可以在其他模塊中(例如,對於版本1到2以及回滾以及對於2到3以及回滾有一個文件)。

0

爲此,您需要使用lambda:

>>> function_dictionary = {'capitalize': lambda text: text.capitalize()} 
>>> function_dictionary['capitalize']('word') 
'Word' 
+0

但正如我在我的問題中所描述的:據我所知,你不能用兩行代碼運行lambda函數。我的許多移植函數都包含兩行代碼。 – kramer65

0

您可以使用lambda: addSomeColumn() and recordChange()提供您的函數將返回True