Hier ist ein etwas hacky Weg, es zu tun Das erstellt zuerst eine neue Funktion aus einer bestehenden mit der Änderung und ersetzt dann den Code des Originals damit. Es ist in erster Linie, weil der Aufruf types.CodeType()
so viele Argumente hat. Die Python 3-Version (nicht abgebildet), die ich ebenfalls implementiert habe, ist etwas anders, da eine Anzahl der function.func_code
-Attribute umbenannt wurde und die Aufrufsequenz von types.CodeType()
leicht geändert wurde.
Ich habe die Idee von this answer von @Aaronasterling (wer sagt, er hat die Idee von Michael Foord Voidspace Blog mit dem Titel Selfless Python).Es könnte leicht zu einem Dekorateur gemacht werden, aber ich sehe das nicht als hilfreich an, basierend auf dem, was Sie uns über den beabsichtigten Gebrauch gesagt haben.
import types
def change_func_args(function, new_args):
""" Create a new function with its arguments renamed to new_args. """
code_obj = function.func_code
assert(0 <= len(new_args) <= code_obj.co_argcount)
# the arguments are just the first co_argcount co_varnames
# replace them with the new argument names in new_args
new_varnames = tuple(list(new_args[:code_obj.co_argcount]) +
list(code_obj.co_varnames[code_obj.co_argcount:]))
# type help(types.CodeType) at the interpreter prompt for information
new_code_obj = types.CodeType(code_obj.co_argcount,
code_obj.co_nlocals,
code_obj.co_stacksize,
code_obj.co_flags,
code_obj.co_code,
code_obj.co_consts,
code_obj.co_names,
new_varnames,
code_obj.co_filename,
code_obj.co_name,
code_obj.co_firstlineno,
code_obj.co_lnotab,
code_obj.co_freevars,
code_obj.co_cellvars)
modified = types.FunctionType(new_code_obj, function.func_globals)
function.__code__ = modified.__code__ # replace code portion of original
if __name__ == '__main__':
import inspect
def f(x, y):
return x+y
def g(a, b):
return f(a, b)
print('Before:')
print('inspect.getargspec(g).args: {}'.format(inspect.getargspec(g).args))
print('g(1, 2): {}'.format(g(1, 2)))
change_func_args(g, ['p', 'q'])
print('')
print('After:')
print('inspect.getargspec(g).args: {}'.format(inspect.getargspec(g).args))
print('g(1, 2): {}'.format(g(1, 2)))
Ausgang:
Before:
inspect.getargspec(g).args: ['a', 'b']
g(1, 2): 3
After:
inspect.getargspec(g).args: ['p', 'q']
g(1, 2): 3
nicht sicher, ob ich die Frage verstanden. Ich nehme an, Sie könnten das 'Lambda' mit einer 'eval'-Anweisung erstellen ... Können Sie ein Beispiel für eine Funktion geben, die zur Laufzeit erstellt wurde? –
Sie können 'FunctionType' und' CodeType' verwenden, um das Objekt zu konstruieren, aber ich bin mir nicht sicher, ob ich den Punkt sehe. – DSM
Das klingt wie ein XY-Problem - In der gleichen war wie dynamisch benannt _Variablen_ normalerweise bedeutet der Fragesteller will eine Liste, das fühlt sich an wie der falsche Weg, um ein Problem zu lösen – Eric