是否可以在模块中动态创建函数/变量?

2024-09-28 17:04:06 发布

您现在位置:Python中文网/ 问答频道 /正文

比如说,我有一个通用函数f(input, kind)和一长串kind。我想为列表中的每个kind创建函数f_kind(input)。不是通过f_kind1 = partial(f, kind=kind1)手动创建,而是可以通过列表上的循环(类似于类中的setattr(class_name, method_name, method))更动态地创建它们吗


Tags: 函数name列表input动态手动partialmethod
1条回答
网友
1楼 · 发布于 2024-09-28 17:04:06

你的问题让我想起了我很久以前读到的Guido van Rossum关于用Python实现multimethods的一篇文章,因为在它的核心,这就是你正在做的

它需要进行调整以在类上工作,但我认为它可能是比使用setattr()来实现目标更好的方法

mm.py:

''' MultiMethod module. '''

_registry = {}

class MultiMethod(object):
    def __init__(self, name):
        self.name = name
        self.typemap = {}

    def __call__(self, *args):
        types = tuple(arg.__class__ for arg in args)
        function = self.typemap.get(types)
        if function is None:
            raise TypeError("no match")
        return function(*args)

    def register(self, types, function):
        if types in self.typemap:
            raise TypeError("duplicate registration")
        print('registering: {!r} for args: {}'.format(function.__name__, types))
        self.typemap[types] = function

def multimethod(*types):
    def register(function):
        name = function.__name__
        mm = _registry.get(name)
        if mm is None:
            mm = _registry[name] = MultiMethod(name)
        mm.register(types, function)
        return mm

    return register

示例用法

mm\u测试。py:

from mm import multimethod

@multimethod(int)
def f(input):
    print('f_{}({!r}) called'.format(type(input).__name__, input))


@multimethod(str)
def f(input):
    print('f_{}({!r}) called'.format(type(input).__name__, input))

f('answer')
f(42)

@multimethod(float)
def f(input):
    print('f_{}({!r}) called'.format(type(input).__name__, input))

f(3.141529)

输出:

registering: 'f' for args: (<class 'int'>,)
registering: 'f' for args: (<class 'str'>,)
f_str('answer') called
f_int(42) called
registering: 'f' for args: (<class 'float'>,)
f_float(3.141529) called

相关问题 更多 >