更新 - 2012/12/13
只是为了澄清一下-我对如何向类添加方法的方式不太感兴趣-正如您在下面我的问题和人们的回答中所看到的那样,有不止一种方法可以做到这一点(面颊上的舌头和帽子提示我的 Perl 自我)。
我感兴趣的是了解使用不同方法向类添加方法的根本区别是什么,而真正的大问题是为什么我需要使用元类。例如A Primer on Python Metaclass Programming指出:
元类最常见的用法可能是 [...]:为生成的类中定义的方法添加、删除、重命名或替换方法。
而且由于有更多方法可以做到这一点,我很困惑并寻找解释。
谢谢!
原创 - 2012/12/12
我需要动态地将方法添加到一个类(以及基于该类的新生成的类)。我想出了两种方法,一种涉及元类,另一种不涉及元类。除了后者不涉及“黑魔法”元类之外,我看不出这两种方法给我的任何区别;)
使用元类的方法#1 :
class Meta(type):
def __init__(cls, *args, **kwargs):
setattr(cls, "foo", lambda self: "foo@%s(class %s)" % (self,
cls.__name__))
class Y(object):
__metaclass__ = Meta
y = Y()
y.foo() # Gives 'foo@<__main__.Y object at 0x10e4afd10>(class Y)'
没有元类的方法#2 :
class Z(object):
def __init__(self):
setattr(self.__class__, "foo",
lambda self: "foo@%s(class %s)" %
(self, self.__class__.__name__))
z = Z()
z.foo() # Gives 'foo@<__main__.Z object at 0x10c865dd0>(class Z)'
据我所知,这两种方法都给了我相同的结果和“表现力”。即使我尝试使用创建新类,type("NewClassY", (Y, ), {})
或者type("NewClassZ", (Z, ), {})
我得到相同的预期结果,这两种方法之间没有区别。
所以,我想知道这些方法是否真的存在任何“潜在”差异,或者如果我使用#1或#2或者它只是一种语法糖,以后是否有任何东西会“咬”我?
PS:是的,我确实在这里阅读了其他关于 Python 和 pythonic 数据模型中的元类的线程。