2012-06-07 4 views
4

Есть ли способ получить обратное значение от inspect.getcallargs(func) до пары *args, **kw, которая фактически может использоваться для вызова func?Есть ли обратная операция в Python inspect.getcallargs в стандартной библиотеке?

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

@fix_x 
def a(x): 
    print x 

@fix_x 
def b(**q): 
    print q['x'] 

def fix_x(func): 
    def wrapper(*args, **kw): 
     argspec = inspect.getargspec(func) 
     callargs = inspect.getcallargs(func, *args, **kw) 
     if 'x' in callargs: 
      callargs['x'] += 5 
     elif 'x' in callargs[argspec.keywords]: 
      callargs[argspec.keywords]['x'] += 5 
     # ...and now I'd like a simple way to call func with callargs...? 

(я на самом деле делать что-то более сложное с callargs между строить их и желая, чтобы сделать звонок с ними, но это должно дать представление о том, что я 'm looking for.)

ответ

3

Нет, в настоящее время нет хорошего способа сделать это, однако это работает в Python 3.3!

См. PEP 362 -- Function Signature Object, как эта новая функция будет работать.

0

Я написал свой собственный код для (более или менее) этого. Он находится в ArgSpec.make_call_args в https://github.com/codemage/wmpy

Семантика немного отличается; а именно, он все равно будет просто шунтировать любые неизвестные аргументы в ** kw вместо того, чтобы принимать отдельный идентификатор записи, названный в честь параметра ** kw, но это достаточно легко изменить, если мне когда-либо понадобится.

С небольшим усилием это, вероятно, может быть превращено в довольно полный «backport» (в кавычках, поскольку он явно не разделяет код) PEP 362 на Python 2.7. Он не выполняет параметры только для ключевого слова, но они вообще не существуют в 2.x, так что это не повлияет на полноту API, а модуль проверки предоставляет все другие нетривиальные механизмы.

Смежные вопросы