我正在尝试在构造函数中的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)
我已经检查了this,但我没有看到我能按照我的目的调整它的方式。
感谢。
答案 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程序员使用。