以编程方式创建函数规范 [英] Programmatically create function specification

查看:48
本文介绍了以编程方式创建函数规范的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了我自己的娱乐,我想知道如何实现以下目标:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆