template.render(current_user=current_user, thread=thread, messages=messages)
Is there a dont-repeat-yourself compliant way to do whatever=whatever
? Like a magic symbol to prepend the variable name with or something like this ~whatever, 开发者_如何学运维~something, ~etc
?
No, there is not.
For what it's worth, you can create a dictionary with your parameters and pass it with:
template.render(**parameters)
Note: You should always favor readability!
If your template.render()
method accepts any keyword arguments, and you don't mind passing it extra arguments that it won't use, then use:
template.render(**locals())
This will pass every local variable in under its own name.
Keep in mind that many people will object to the sloppiness implicit in this solution.
You can pass keyword arguments from a dictionary if you want.
def a(b, c, d):
pass
someArgs = {"b" : 1, "c" : 2, "d" : 3}
a(**someArgs)
If you want to prepend something to the variable names, you can change the dictionary keys:
a(**dict(("prefix_" + k, v) for k, v in someArgs.items()))
And as an aside, you know that you can't specify arguments called "~arg" in your source code?!
I sort of like aaronasterling's idea, but obviously it's not quite short. suppose you have a naming convention for local variables. variables that will be passed to the call have one naming style and everything else follows a different convention. For instance, suppose you just say that the leading character of 'private' locals begin with an underscore. thus:
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()))
but that's hideous, don't do that.
Here's a decorator, inspired to some degree by the one in a recipe titled Keyword Argument Injection with Python Decorators, that might help. It certainly cuts down on the repetition, maybe too much.
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()
Output:
render() args
extra_stuff:extra_stuff, current_user:joe, thread:42, messages:['greetings', "how's it going?"]
精彩评论