python设置函数_在Python中设置函数签名

Suppose I have a generic function f. I want to programmatically create a function f2 that behaves the same as f, but has a customised signature.

More detail

Given a list l and and dictionary d I want to be able to:

Set the non-keyword arguments of f2 to the strings in l

Set the keyword arguments of f2 to the keys in d and the default values to the values of d

ie. Suppose we have

l=["x", "y"]

d={"opt":None}

def f(*args, **kwargs):

#My code

Then I would want a function with signature:

def f2(x, y, opt=None):

#My code

A specific use case

This is just a simplified version of my specific use case. I am giving this as an example only.

My actual use case (simplified) is as follows. We have a generic initiation function:

def generic_init(self,*args,**kwargs):

"""Function to initiate a generic object"""

for name, arg in zip(self.__init_args__,args):

setattr(self, name, arg)

for name, default in self.__init_kw_args__.items():

if name in kwargs:

setattr(self, name, kwargs[name])

else:

setattr(self, name, default)

We want to use this function in a number of classes. In particular, we want to create a function init that behaves like generic_init, but has the signature defined by some class variables at creation time:

class my_class:

__init_args__=["x", "y"]

__kw_init_args__={"my_opt": None}

__init__=create_initiation_function(my_class, generic_init)

setattr(myclass, "__init__", __init__)

We want create_initiation_function to create a new function with the signature defined using init_args and kw_init_args. Is it possible to writ create_initiation_function?

Please note:

If I just wanted to improve the help, I could set doc.

We want to set the function signature on creation. After that, it doesn't need to be changed.

Instead of creating a function like generic_init, but with a different signature we could create a new function with the desired signature that just calls generic_init

We want to define create_initiation_function. We don't want to manually specify the new function!

Related

Preserving signatures of decorated functions: This is how to preserve a signature when decorating a function. We need to be able to set the signature to an arbitrary value

解决方案

For your usecase, having a docstring in the class/function should work -- that will show up in help() okay, and can be set programmatically (func.__doc__ = "stuff").

I can't see any way of setting the actual signature. I would have thought the functools module would have done it if it was doable, but it doesn't, at least in py2.5 and py2.6.

You can also raise a TypeError exception if you get bad input.

Hmm, if you don't mind being truly vile, you can use compile()/eval() to do it. If your desired signature is specified by arglist=["foo","bar","baz"], and your actual function is f(*args, **kwargs), you can manage:

argstr = ", ".join(arglist)

fakefunc = "def func(%s):\n return real_func(%s)\n" % (argstr, argstr)

fakefunc_code = compile(fakefunc, "fakesource", "exec")

fakeglobals = {}

eval(fakefunc_code, {"real_func": f}, fakeglobals)

f_with_good_sig = fakeglobals["func"]

help(f) # f(*args, **kwargs)

help(f_with_good_sig) # func(foo, bar, baz)

Changing the docstring and func_name should get you a complete solution. But, uh, eww...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值