以编程方式创建函数规范 [英] Programmatically create function specification
问题描述
为了我自己的娱乐,我想知道如何实现以下目标:
functionA = make_fun(['paramA', 'paramB'])functionB = make_fun(['arg1', 'arg2', 'arg3'])
相当于
def functionA(paramA, paramB):打印(参数A)打印(参数B)def 函数 B(arg1, arg2, arg3):打印(arg1)打印(arg2)打印(arg3)
这意味着需要以下行为:
functionA(3, paramB=1) # 有效functionA(3, 2, 1) # 失败functionB(0) # 失败
问题的重点是变量 argspec - 我很乐意使用通常的装饰器技术创建函数体.
对于那些感兴趣的人,我正在尝试以编程方式创建如下类.同样,困难在于生成带有编程参数的 __init__
方法 - 使用装饰器或元类,类的其余部分看起来很简单.
class MyClass:def __init__(self, paramA=None, paramB=None):self._attr = ['paramA', 'paramB']for a in self._attr:self.__setattr__(a, None)def __str__(self):return str({k:v for (k,v) in self.__dict__.items() if k in self._attributes})
您可以使用 exec
从包含 Python 代码的字符串构造函数对象:
def make_fun(参数):exec("def f_make_fun({}): pass".format(', '.join(parameters)))返回当地人()['f_make_fun']
示例:
<预><代码>>>>f = make_fun(['a', 'b'])>>>进口检验>>>打印(检查.签名(f).参数)OrderedDict([('a', <参数在 0x1024297e0 'a'>), ('b', <参数在 0x102429948 'b'>)])如果您想要更多功能(例如,默认参数值),只需调整包含代码的字符串并让它代表所需的函数签名即可.
免责声明:如下所述,验证parameters
的内容并且生成的Python 代码字符串可以安全地传递给exec
非常重要.您应该自己构建参数
或设置限制以防止用户为参数
构建恶意值.
For my own entertainment, I was wondering how to achieve the following:
functionA = make_fun(['paramA', 'paramB'])
functionB = make_fun(['arg1', 'arg2', 'arg3'])
equivalent to
def functionA(paramA, paramB):
print(paramA)
print(paramB)
def functionB(arg1, arg2, arg3):
print(arg1)
print(arg2)
print(arg3)
This means the following behaviour is required:
functionA(3, paramB=1) # Works
functionA(3, 2, 1) # Fails
functionB(0) # Fails
The focus of the question is on the variable argspec - I comfortable creating the function body using the usual decorator techniques.
For those that are interested, I was playing around with trying to programmatically create classes like the following. Again the difficulty is in generating the __init__
method with programmatic parameters - the rest of the class appears straightforward using a decorator or maybe a metaclass.
class MyClass:
def __init__(self, paramA=None, paramB=None):
self._attr = ['paramA', 'paramB']
for a in self._attr:
self.__setattr__(a, None)
def __str__(self):
return str({k:v for (k,v) in self.__dict__.items() if k in self._attributes})
You can use exec
to construct the function object from a string containing Python code:
def make_fun(parameters):
exec("def f_make_fun({}): pass".format(', '.join(parameters)))
return locals()['f_make_fun']
Example:
>>> f = make_fun(['a', 'b'])
>>> import inspect
>>> print(inspect.signature(f).parameters)
OrderedDict([('a', <Parameter at 0x1024297e0 'a'>), ('b', <Parameter at 0x102429948 'b'>)])
If you want more functionality (e.g., default argument values), it's a matter of adapting the string that contains the code and having it represent the desired function signature.
Disclaimer: as pointed out below it's important that you verify the contents of parameters
and that the resulting Python code string is safe to pass to exec
. You should construct parameters
yourself or put restrictions in place to prevent the user from constructing a malicious value for parameters
.
这篇关于以编程方式创建函数规范的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!