Python's equivalent for define

I have this code in 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

I've read this question about define_method in python and I wanted to implement the same thing in Python with my Ruby code:

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

I call the function like this:

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

But obviously this doesn't work because I don't recover the name of the element that I'm searching. Can someone help me understand better how this python define_method works with my code?


You were almost there; bind the bindtype value as a default value for the function argument, and you want to call get_by_name() on 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)

I took the liberty of using str.format() to format the method name rather than use + concatenation, it is more readable I find.

Alternatively, in Python 3 you could just create 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))
链接地址: http://www.djcxy.com/p/31700.html

上一篇: py3.x中list()和[]的实现有什么区别?

下一篇: Python与define相当