Python中与Ruby的define_method等效的方法是什么?

6

是否有Python的等效方法可以像Ruby的define_method一样允许动态生成类方法? (正如在维基百科的Ruby示例代码中所看到的)

4个回答

14

在Python中,函数是一等对象,可以被分配给类或实例的属性。实现与维基百科示例相同的方法之一是:

colours = {"black": "000",
           "red": "f00",
           "green": "0f0",
           "yellow": "ff0",
           "blue": "00f",
           "magenta": "f0f",
           "cyan": "0ff",
           "white": "fff"}

class MyString(str):
    pass

for name, code in colours.iteritems():
    def _in_colour(self, code=code):
        return '<span style="color: %s">%s</span>' % (code, self)
    setattr(MyString, "in_" + name, _in_colour)

这不会按预期工作。code 对于每个方法都是相同的。添加一个虚假的默认参数 code=code,就像 name 一样,可以解决这个问题。 - user395760
请注意内部函数中的code=code,您必须像这样将循环变量传递给函数。 - Jochen Ritzel
@delnan:这是一个错误。我本意是传递code=code而不是name=name - Sven Marnach
请注意,您可以在不向函数添加虚拟参数的情况下完成此操作,但这超出了问题的范围(闭包)。这只是作用域规则的差异。 - Glenn Maynard

2
在Python中,你可以在类上直接设置一个方法:
>>> class Spam:
...     def __init__(self, x):
...         self.value = x
...
>>> Spam.getvalue = lambda self: self.value
>>> ham = Spam('ham')
>>> ham.getvalue()
'ham'

更高级的操作可以使用装饰器实现。请参考Python装饰器

0

你只需要将一个函数分配为类的新属性:

 def replacement_method(self):
     print self.name


 class Foo(object):
     def __init__(self, name):
         self.name = name
     # .... whatever

 setattr(Foo, "printMyName", replacement_method) # assign it
 Foo("Joe").printMyName() # call it

如果您不需要一个可计算的名称(如维基百科示例中的字符串),您可以使其更加简洁:

 Foo.printMyName = replacement_method

-2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接