我有一个带有命名参数的函数
def sample(a=None, b=None, c=None)
pass
如何在调用函数后得到这些参数的顺序?
sample(b=1, a=1, c=1)
out: ['b', 'a', 'c']
sample(c=1, a=1)
out: ['c', 'a']
sample(a=1, b=1)
out: ['a', 'b']
sample(b=1, a=1)
out: ['b', 'a']
sample(a=1, b=1, c=1)
out: ['a', 'b', 'c']
也许这可以使用装饰器或其他方式完成?
更新
我想为sqlalchemy过滤方式创建弹性搜索过滤器的包装器,但是通过命名参数
class ESQuery(object):
def __init__(self, url, index):
pass
def filter(self, _bool=None, _range=None, _not=None, _and=None, _or=None, _type=None, exists=None, query=None):
return self.query_body
调用该函数后,我需要获得正确的查询顺序,例如http://www.elastic.co/guide/en/elasticsearch/reference/1.5/query-dsl-and-filter.html
我无法构建查询以便保持严格的命令
es = Someclass(url, index)
es.filter()
我想使用命名参数来做,人们觉得它很方便用作工具提示
更新2:
我想找到另一种方式,一条线路还不够,因为可以长时间通话
from api.search_api import ESQuery
es = ESQuery(index='lot', place='etsy_spider', match_all=True)
print es.\
filter(query='{ "tweet": "full text search" }').\
filter(_range='{ "created": { "gte": "now - 1d / d" }}').\
filter(should='{ "term": { "featured": true }},')
可能有一些关于如何在elasticsearch中简化长查询的想法?
答案 0 :(得分:1)
我想不出它为什么会有用的原因。话虽这么说,您可以使用inspect
模块(https://docs.python.org/2/library/inspect.html):
import inspect
def f(a=2, b=3):
call_string = inspect.stack()[1][4] ## returns a list with the string that represents how the function was called.
print call_string
args, kwargs = get_function_args(call_string[0]) ## to return what you want
...
f(b=3, a=1) # prints [u'f(b=3, a=1)\n']
然后,您将使用正则表达式解析call_string
。
请注意,此方法仅适用于单线呼叫。
这是一个简单的正则表达式解析器,它将按照外观顺序返回参数列表和关键字参数。请注意,这是非常基本的,不适用于包含“,”的字符串。
import re
VALID_VAR = "([_A-Za-z][_a-zA-Z0-9]*)"
LEFT_PAR = '\('
RIGHT_PAR = '\)'
def get_function_args(line):
args = []
keywords = []
res = re.search(VALID_VAR+LEFT_PAR+'(.*?)'+RIGHT_PAR+'$', line)
if res:
allargs = res.group(2)
allargs = allargs.split(',') ## does not work if you have strings with ","
for arg in allargs:
## Arguments
res2 = re.search('^{0}$'.format(VALID_VAR), arg.strip())
if res2:
args.append(res2.group(1))
## Optional arguments
res2 = re.search('^{0} *= *(.*)$'.format(VALID_VAR), arg.strip())
if res2:
keywords.append(res2.group(1))
return args, keywords
答案 1 :(得分:-2)
是的,可以这样做 - 继续阅读。
如何在调用函数后得到这些参数的顺序?
命名参数作为字典传递,其.items()
定义在arbitrary order中:
# this...
def foo(a=None, b=None, c=None):
...
# .... is the equivalent of:
def foo(**kwargs):
a = kwargs.get('a')
b = kwargs.get('b')
c = kwargs.get('c')
...
如何在调用函数后得到这些参数的顺序?
无论上述情况如何,您都可以使用OrderedDict
:
from collections import OrderedDict
def bar(sorted_kwargs):
for k in sorted_kwargs.keys():
print 'index of %s => %s' % (k, sorted_kwargs.keys().index(k))
bar(OrderedDict((('c', 1), ('a', 2), ('b', 3))))
# results
index of c => 0
index of a => 1
index of b => 2
也许这可以使用装饰器或其他方式完成?
参数的顺序是调用者决定的东西 - 装饰者不能改变它。
顺便说一下。关于此
的草案PEP