Python: конвертировать аргументы в dict, как компактный PHP? - PullRequest
2 голосов
/ 24 июня 2010

Мне нужна функция, точно такая же, как в PHP compact .

т.е., если я передам список имен переменных:

compact('var1','var2')

возвращает мне ответ:

{'var1':var1, 'var2':var2}

Ответы [ 8 ]

3 голосов
/ 24 июня 2010

Имя переменной, используемой в вызывающей программе, не всегда доступно для вызываемой функции.Вероятно, это возможно сделать с расширенным использованием inspect, но, возможно, было бы лучше переосмыслить, зачем вам нужны имена переменных.

ОБНОВЛЕНИЕ: Теперь, когда я знаю, какова ваша реальная потребность (передать мои переменные в мой шаблон "), ответ прост: используйте locals(): он возвращает словарь, отображающий имена всех ваших локальных переменных в их значения.

ОБНОВЛЕНИЕ 2: Как насчет этого?:

def only(d, *keys):
    """Return the subset of dict `d` whose keys are in `keys`."""
    return dict((k,v) for k,v in d.iteritems() if k in keys)

...

a = 17
b = 23
template_data = only(locals(), "a", "b")
1 голос
/ 24 июня 2010

С помощью Получение имен параметров метода в python , здесь вы найдете решение decorator, чтобы вы могли применить его к любой функции:

def compactor(func):
    import inspect
    def compactor_impl(*args, **kwargs):
        arg_names = inspect.getargspec(func)[0]
        return dict(zip(arg_names, args))
    return compactor_impl

@compactor
def package(var1, var2, var3):
    pass

@compactor
def package2(var1, var2, var3, supervar):
    pass

assert package(1, 2, 3) == {'var1': 1, 'var2': 2, 'var3': 3,}
assert package2(1, 2, 3, 'boh') == {'var1': 1, 'var2': 2, 'var3': 3, 'var3': 3, 'supervar': 'boh'}

Я предположил, что функции ничего не делают, кроме как возвращают пары name-value. Возможно, вы захотите добавить некоторые проверки (утверждения), чтобы гарантировать, что len(args) == len(arg_names) и что kwargs пусто, потому что это не будет проверяться после применения декоратора.

1 голос
/ 24 июня 2010
>>> import inspect
>>> def compact(*args):
...     d = {}
...     for a in args:
...         d[a] = inspect.stack()[1][0].f_locals[a]
...     return d
...
>>> def test():
...     x = 5
...     print compact('x')
...
>>> test()
{'x': 5}
1 голос
/ 24 июня 2010

(1) Python не является PHP. (2) «имя переменной, потерянное при передаче в функцию», является истинным

Не используйте переменные для этого.

Сделай что-нибудь проще . Используйте функцию dict.

>>> dict( var1=1, var2='a', var3=1+3j )
{'var1': 1, 'var3': (1+3j), 'var2': 'a'}

Кажется, это делает то, что вы хотите. Переменные «имена» находятся там точно один раз . Вам не нужно создавать другие локальные временные переменные.

1 голос
/ 24 июня 2010

Функция не видит имен (если таковые имеются! -) своих фактических аргументов - и фактически никаких указаний на то, что эти фактические аргументы являются результатом выражений, которые оказываются единственными переменными, а не константами, вызовами функцийили другие выражения любого рода.

Итак, то, что вам требуется, как вы это указали, просто неосуществимо.

0 голосов
/ 16 января 2015

Просто используйте locals () в начале функции.

def foo(x,y): 
   print x,y

def jar(x,y):
   foo(**locals())

def varjar(x,y):
   print locals()
   args =  locals().copy()
   args['x'] += 1
   args['y'] += 2
   foo(**args)
  • foo (1,2) и jar (1,2) print 1 2
  • varjar (1,2) print {'y': 2, 'x': 1} и 2 4
0 голосов
/ 24 июня 2010

Это неудобно и имеет ограничения, но в остальном работает

def p(*args):
  p = {}
  for i in args:   
     exec 'p["%s"] = %s' % (i, i)
  return p
0 голосов
/ 24 июня 2010

, если у вас есть список с именем args и вы хотите поместить его в словарь с именем kwargs , как в вашем примере:

for k,v in enumerate(args):
    kwargs["var%d"%(k+1)] = v

ключибуквально индекс предметов в аргументах, хотя;это не может быть полезно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...