Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python中动态创建方法(名称和代码)_Python_Python 3.x - Fatal编程技术网

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

如何在Python中动态创建方法(名称和代码),python,python-3.x,Python,Python 3.x,我正在尝试在构造函数中用python动态添加新方法 上下文 我在C++中编写了一个Python模块,它与C语言编写的信号处理库交互。 我有一个通用方法来访问我的模块(称为过滤器)参数 例如: 因此,我的cpython将其包装如下: filter.set(method_id,value) 我可以访问我所有的方法ID 目标 我希望生成如下setter: >>> filter.setSampleRate(value) 在派生类中 class Filter(BaseFilter):

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

上下文

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

例如:

因此,我的cpython将其包装如下:

filter.set(method_id,value)
我可以访问我所有的方法ID

目标 我希望生成如下setter:

>>> 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类型模块
  • 怎么做
我已经检查过了,但我看不出有什么方法可以使它适应我的目的


谢谢。

在第一次遇到类定义之前,我不确定您的setter方法名是否可用,如果是,使用元类创建类可能是合适的。如果它们只在运行时可用,那么这个答案应该可以指导您找到解决方案:

从您的描述中,我无法判断您是在寻找一种在运行时创建Python函数的方法,还是在寻找一种在运行时创建Python函数的方法。Python程序员可以通过多种方式使用代码。

您可以检查与
设置程序匹配的方法名称,然后动态地将其分派到
设置()方法,而不是动态创建方法。这可以通过在
过滤器
类中重写
\uuu getattribute\uuuu()
来实现:

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()
\uuu getattribute\uuuu()
的方法,返回一个包装版本的
BaseFilter.set()
,该版本在闭包中可以访问
方法id


>f=Filter()
>>>f.setSampleRate(44000)
BaseFilter.set():将SampleRate设置为44000
>>>f.1深度(16)
BaseFilter.set():将位深度设置为16
>>>f.设定增益(100)
BaseFilter.set():将增益设置为100
>>>f.setHouseOnFire(999)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“”,第9行,在\uu getattribute中__
AttributeError:“Filter”对象没有属性“SetHouseConfigure”

@GarciaSylvain:太好了。我也很满意!
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)
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)
>>> 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'