Python等同于define_method

时间:2016-06-27 18:26:57

标签: python ruby

我在ruby中有这段代码:

class Package

def initialize(name)
    @name = name
    @elements = []
end

[:type, :block].each do |bindtype|
    define_method "get_#{bindtype}_by_name" do |name|
        get_by_name(name, bindtype)
    end
end

def get_by_name(name, bindtype=nil)
    @elements.each do |element|
        return if element.name == name
    end
    return nil
end

我已经阅读了这个问题about define_method in python,我想用Python代码在Python中实现相同的东西:

bindtypes = {"type", "block"}

class Package:

    def __init__(self, name):
        self.name = name
        self.elements = list()

    def get_by_name(self, name, bindtype=None):
        for element in self.elements:
            if element.name == name:
                return element
        return None

for bindtype in bindtypes:
    def _in_bindtype(self, bindtype, bindtype):
        Package.get_by_name(bindtype, bindtype)
    setattr(Package, "get_"+bindtype+"_by_name", _in_bindtype

我这样称呼函数:

package = Package("package")    
block = Block("blockName")
package.elements.append(block)
blockFound = package.get_block_by_name(block.name, block.bindtype)

但显然这不起作用,因为我没有恢复我正在搜索的元素的名称。有人可以帮助我更好地理解这个python define_method如何与我的代码一起工作吗?

1 个答案:

答案 0 :(得分:2)

你几乎在那里;绑定bindtype值作为函数参数的默认值,并且您想在get_by_name()上调用self

for bindtype in bindtypes:
    def _in_bindtype(self, name, bindtype=bindtype):
        self.get_by_name(name, bindtype)
    setattr(Package, "get_{}_by_name".format(bindtype), _in_bindtype)

我冒昧地使用str.format()格式化方法名称而不是使用+连接,我发现它更具可读性。

或者,在Python 3中,您只需创建functools.partialmethod() objects

from functools import partialmethod

for bindtype in bindtypes:
    setattr(Package, "get_{}_by_name".format(bindtype),
            partialmethod(Package.get_by_name, bindtype=bindtype))