如何在不运行函数的情况下部分设置参数?

2024-04-28 16:19:10 发布

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

我试图让我的用户生活尽可能简单,同时为他们提供完全的灵活性。我需要编写函数供他们使用,但诀窍是用户需要在运行函数之前选择它。我想做的是:

def standardGenerator(obj,param=8.0):
   # algorithm which generates stuff based on obj and param
   return stuff

opts.usersChoice = standardGenerator

在这个例子中,opts是一个选项容器,它提供给用户来设置他们想要的任何选项。当他们设置完所有选项后,他们将opts传给我。在

现在的问题是obj在我手中opts之后才会知道,但是可能有用户想要params=4.0而不是我的默认值。我的问题是允许用户设置param的最简单方法是什么?在

以下是我的想法:

^{pr2}$

也许lambda是最好的主意,但是我想知道是否有其他方法可以在不需要用户知道lambda函数是什么的情况下做到这一点。。。在


Tags: 方法lambda函数用户objwhichparamdef
3条回答

如果你问我认为你是什么,那么你的答案来自于对论点的解构。在

opts.usersChoice = standardGenerator4
opts.usersArguments = (obj, 4.0)

opts.usersChoice(*opts.usersArguments)

这将调用standardGenerator4(obj,4.0)。在

您也可以将其与列表一起使用,以便在需要时进行构建:

^{pr2}$

会有同样的结果。在

另外一种方法是使用^{}。在

为什么不让它成为一个带有__call__的类呢?在

class standardGenerator(object):
    def __init__(self, param=8.0):
        self.param = param
    def __call__(self, obj):
        # do stuff with obj and self.param

用户代码执行以下操作:

^{pr2}$

那么opts.usersChoice和以前一样是可调用的,只有obj的一个参数。在

编辑:如果您有几个函数,并且不想将它们全部转换为类,则可以创建一个包装类:

class wrapper(object):
    def __init__(self, func, **args):
        self.func, self.args = func, args
    def __call__(self, *args):
        return self.func(*args, **self.kwargs)

然后,您的旧函数可以像以前一样“原始”使用,或者像这样用于用户定义的参数:

^{4}$

我认为第一个解决方案更干净,第二个方案可能开始重复functools.partial,但你明白了。在

编辑:你可以做的另一件事,可以说是邪恶的,就是使用操作符重载:

class _standardGenerator(object):
    def __init__(self, param = 8.0):
        self.param = param
    # overload << to make it look most evil
    def __lshift__(self, other):
        return _standardGenerator(other)
    def __call__(self, obj):
        # do stuff with self.param and obj

standardGenerator = _standardGenerator()

# user code for default
opts.usersChoice = standardGenerator
# user code for nondefault
opts.usersChoice = standardGenerator << 4.0

当然,我认为使用常规类并让用户自己实例化它会更干净,但是如果您不喜欢standardGenerator末尾的括号,那么这样的方法就可以了。在

相关问题 更多 >