如何在Python中创建函数的dict?

kra*_*r65 4 python lambda dictionary structure function

我正在用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},
}
Run Code Online (Sandbox Code Playgroud)

但是每次创建新的迁移时,我都需要编写两个迁移脚本(上下)并将它们放在迁移字典中.由于迁移功能非常小(通常是两行),我想在迁移字典中直接写它们.在Javascript中,这看起来像:

migrations = {
    1: {
        'up': function(){ addSomeColumn(); recordChange(); }, 
        'down': function(){ dropSomeColumn(); recordChange(); }
    },
    2: etc
}
Run Code Online (Sandbox Code Playgroud)

因为迁移函数通常是两行,所以我认为我不能使用lambda函数.有没有人知道在Python中用dict直接编写函数的其他方法?欢迎所有提示!

Dun*_*can 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)
Run Code Online (Sandbox Code Playgroud)

对于哪个输出是这样的:

{1: {'up': <function upgrade at 0x02BE4588>}, 2: {'down': <function downgrade at 0x02BE4618>, 'up': <function upgrade at 0x02BE4540>}}
Run Code Online (Sandbox Code Playgroud)

装饰负责更新migrations字典,但这样函数可以有任何名称或重用相同的名称,或者可以在其他模块中(例如,有一个文件用于版本1到2和回滚,另一个用于2到3)和回滚).