Python 3.x 如何动态修改函数的签名

Python 3.x 如何动态修改函数的签名,python-3.x,arguments,abstract-syntax-tree,python-internals,Python 3.x,Arguments,Abstract Syntax Tree,Python Internals,我正在用Python编写一个框架。当用户声明函数时,他们会执行以下操作: def foo(row, fetch=stuff, query=otherStuff) def bar(row, query=stuff) def bar2(row) 当后端看到query=value时,它会根据value执行带有query参数的函数。通过这种方式,函数可以访问后端在其作用域内执行的操作的结果 目前,我每次都通过检查query、fetch和其他项是否为None来构建参数,并使用一组与用户要求完全匹配的

我正在用Python编写一个框架。当用户声明函数时,他们会执行以下操作:

def foo(row, fetch=stuff, query=otherStuff)

def bar(row, query=stuff)

def bar2(row)
当后端看到query=value时,它会根据value执行带有query参数的函数。通过这种方式,函数可以访问后端在其作用域内执行的操作的结果

目前,我每次都通过检查query、fetch和其他项是否为None来构建参数,并使用一组与用户要求完全匹配的参数启动它。否则,我得到了一个意外的关键字参数错误。这是后端中的代码:

#fetch and query is something computed by the backend
if fetch= None and query==None:
    userfunction(row)
elif fetch==None:
    userunction (row, query=query)
elif query == None:
    userfunction (row, fetch=fetch)
else:
    userfunction (row,fetch=fetch,query=query)

这不好,;对于后端提供的每一项附加服务,我都需要编写与先前服务的所有组合

与此相反,我希望在执行该函数之前,首先获取该函数并手动添加一个命名参数,删除所有执行这些检查的不必要代码。然后用户就会使用它真正想要的东西

我不希望用户必须通过添加它不想要的东西来修改函数,也不希望他们每次都指定一个kwarg

如果可行的话,我想举一个例子,一个函数addNamedVarname,一个将变量名添加到函数中的函数


我想这样做,因为用户函数被调用了很多次,这意味着它会触发我,例如,使用inspect创建函数命名变量的dict,然后使用**dict。我真的希望只修改函数一次,以避免任何开销。

这在AST中确实可行,这就是我要做的,因为此解决方案更适合我的用例。但是,您可以通过像我展示的代码片段那样的函数克隆方法更简单地完成我要求的任务。请注意,此代码返回具有不同默认值的相同函数。您可以使用此代码作为示例来做任何您想做的事情。 这适用于python3

def copyTransformf,名称,**参数: signature=inspect.signaturef params=listsignature.parameters numberOfParam=lenparams numberOfDefault=lenf.\uu默认值__ listTuple=listf.\uu默认值__ 对于args.items中的键、val: toChangeIndex=params.indexkey,numberOfDefault 如果要更改索引: listTuple[toChangeIndex-numberOfDefault]=val newTuple=tuplelistTuple oldCode=f.\u代码__ newCode=types.CodeType oldCode.co_argcount,整数 oldCode.co_kwonlyargcount,整数 oldCode.co_nlocals,整数 oldCode.co\u堆栈大小,整数 oldCode.co_标志,整数 oldCode.co_代码,字节 oldCode.co_常量,元组 oldCode.co_名称,元组 oldCode.co_变量名,元组 oldCode.co_文件名,字符串 名称、字符串 oldCode.co_firstlineno,整数 oldCode.co_lnotab,字节 oldCode.co_freevars,元组 oldCode.co_cellvars元组 newFunction=types.FunctionTypenewCode,f._全局变量__,名称,新元组,f.__闭包__ newFunction.\uuuuqualname\uuuuu=序列化也需要名称
如果你想修改你的克隆函数,你需要在名称上做一些奇怪的事情。

你能解释一下为什么使用-1吗?经过一些搜索,我认为使用ast模块可能是可行的。修改functionDef节点。我不太确定。