在Python中调用时是否有更好的方法来指定命名参数

时间:2010-10-18 05:38:33

标签: python

template.render(current_user=current_user, thread=thread, messages=messages)

是否有一种不重复自己的方式来whatever=whatever?就像一个魔术符号,可以在变量名前加上~whatever, ~something, ~etc或类似的东西?

5 个答案:

答案 0 :(得分:3)

不,没有。

对于它的价值,您可以使用您的参数创建一个字典并将其传递给:

template.render(**parameters)

注意:你应该总是喜欢可读性!

答案 1 :(得分:1)

如果你的template.render()方法接受任何关键字参数,并且你不介意传递它不会使用的额外参数,那么使用:

template.render(**locals())

这将以自己的名义传递每个局部变量。

请记住,很多人会反对这个解决方案中隐含的邋。。

答案 2 :(得分:0)

如果需要,您可以从字典中传递关键字参数。

def a(b, c, d):
    pass

someArgs = {"b" : 1, "c" : 2, "d" : 3}
a(**someArgs)

如果要在变量名前加上一些内容,可以更改字典键:

a(**dict(("prefix_" + k, v) for k, v in someArgs.items()))

另外,您知道您不能在源代码中指定名为“~arg”的参数吗?!

答案 3 :(得分:0)

我有点像aaronasterling的想法,但显然它不是很短。假设您有局部变量的命名约定。将传递给调用的变量具有一种命名样式,其他所有变量都遵循不同的约定。例如,假设您只是说'私人'本地人的主要角色以下划线开头。因此:

def localargs (kwargs):
    return dict((k, v) for (k, v) in kwargs.iteritems() if k[0] != '_')

def somefunction(public_arg, _private_arg):
    public_local = "foo"
    _private_local = "bar"
    ...
    template.render(**localargs(locals()))

但是这很可怕,不要这样做。

答案 4 :(得分:0)

这是一个装饰者,在某种程度上受到标题为Keyword Argument Injection with Python Decorators的食谱中的那个的启发,可能有所帮助。它肯定会减少重复,也许太多了。

import sys

def injectlocalargs(inFunction):

    def outFunction(*args, **kwargs):
        # get decorated function's argument names
        func_argnames = inFunction.func_code.co_varnames

        # caller's local namespace
        namespace = sys._getframe(1).f_locals

        # add values of any arguments named in caller's namespace
        kwargs.update([(name,namespace[name]) for name in func_argnames if name in namespace])

        # call decorated function and return its result    
        return inFunction(*args, **kwargs)

    return outFunction

##### testbed #####

class template_class:
    @injectlocalargs
    def render(self, extra_stuff, current_user, thread, messages):
        print 'render() args'
        print '  extra_stuff:%s, current_user:%s, thread:%s, messages:%s' % (extra_stuff, current_user, thread, messages)

def test():
    current_user = 'joe'
    thread = 42
    messages = ['greetings',"how's it going?"]
    template = template_class()

    template.render('extra_stuff')

test()

输出:

render() args
  extra_stuff:extra_stuff, current_user:joe, thread:42, messages:['greetings', "how's it going?"]