如何在Python中动态创建方法(名称+代码)

时间:2015-02-26 01:06:33

标签: python python-3.x

我正在尝试在构造函数中的python中动态添加新方法......

上下文

我用C ++编写了一个Python模块,它与我用C编写的信号处理库交互... 我有通用的方法来访问我的模块(称为过滤器)参数。

例如:

int my_filter_set( void * filter_handle, const char * method_id, void * p_arg );

所以我的cpython就像这样包装:

filter.set(method_id,value)

我可以访问所有方法ID

>>> filter.setters
['SampleRate','...']

目标

我想生成像:

这样的setters
>>> filter.setSampleRate(value)

在派生类中。

class Filter(BaseFilter):
'''
classdocs
'''

def __init__(self, name, library):
    '''
    Constructor
    '''
    BaseFilter.__init__(self,name,library)

    for setter_id in self.setters:
        code = 'self.set(' + setter_id + ',value)'
        # @todo add the method body to a new method called 'set' + method_id (with 'value' as argument)

问题是......

  • 有可能吗?
  • 使用python类型模块?
  • 怎么做?
  

我已经检查了this,但我没有看到我能按照我的目的调整它的方式。

感谢。

3 个答案:

答案 0 :(得分:2)

您可以检查与setters匹配的方法名称,然后将调度动态地检查到set()方法,而不是动态创建方法。这可以通过覆盖__getattribute__()课程中的Filter来实现:

class BaseFilter(object):
    setters = ('SampleRate', 'Gain', 'BitDepth',)

    def set(self, method_id, value):
        print 'BaseFilter.set(): setting {} to {}'.format(method_id, value)

class Filter(BaseFilter):
    def __getattribute__(self, name):
        method_id = name.lstrip('set')
        if name.startswith('set') and method_id in super(Filter, self).setters:
            def _set(value):
                return self.set(method_id, value)
            return _set
        else:
            return super(Filter, self).__getattribute__(name)

此处,对于要分发到BaseFilter.set()的方法,__getattribute__()会返回BaseFilter.set()的包装版本,该版本可以在闭包中访问method_id


>>> f = Filter()
>>> f.setSampleRate(44000)
BaseFilter.set(): setting SampleRate to 44000
>>> f.setBitDepth(16)
BaseFilter.set(): setting BitDepth to 16
>>> f.setGain(100)
BaseFilter.set(): setting Gain to 100

>>> f.setHouseOnFire(999)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 9, in __getattribute__
AttributeError: 'Filter' object has no attribute 'setHouseOnFire'

答案 1 :(得分:0)

我不确定在第一次遇到类定义之前你的setter方法名是否可用,如果是这样,使用元类创建类可能是合适的。如果它们仅在运行时可用,则此答案应指导您找到解决方案的方式:Adding a Method to an Existing Object Instance

答案 2 :(得分:0)

根据您的描述,我无法判断您是在寻找在运行时创建Python函数的方法,还是在寻找provide Python bindings for your existing code base的方法。有许多方法可以让您的代码可供Python程序员使用。