2008-09-15 4 views
8

Как добавить метод экземпляра в класс с использованием метакласса (да, мне нужно использовать метакласс)? Следующий вид работ, но func_name все равно будет «Foo»:Как добавить метод с использованием метакласса

def bar(self): 
    print "bar" 

class MetaFoo(type): 
    def __new__(cls, name, bases, dict): 
     dict["foobar"] = bar 
     return type(name, bases, dict) 

class Foo(object): 
    __metaclass__ = MetaFoo 

>>> f = Foo() 
>>> f.foobar() 
bar 
>>> f.foobar.func_name 
'bar' 

Моя проблема заключается в том, что некоторые библиотеки кода на самом деле использует FUNC_NAME, а затем не может найти метод «бар» экземпляра Foo. Я мог бы сделать:

dict["foobar"] = types.FunctionType(bar.func_code, {}, "foobar") 

Существует также types.MethodType, но мне нужен экземпляр, который does'nt существует еще использовать. Разве я здесь не встречаюсь?

+0

Почему вы пытаетесь изменить имя метода? не dict [bar.func_name] = bar выполняет то, что вы хотите? – 2008-09-15 19:03:13

+0

Хороший вопрос ... Я изначально создавал имена методов на основе атрибутов, определенных в dict, но я понимаю, что это бессмысленно, если реализации методов идентичны. – 2008-09-15 19:30:18

ответ

15

Постарайся динамически расширяя основы таким образом, вы можете воспользоваться MRO и методы являются реальными методами:

class Parent(object): 
    def bar(self): 
     print "bar" 

class MetaFoo(type): 
    def __new__(cls, name, bases, dict): 
     return type(name, (Parent,) + bases, dict) 

class Foo(object): 
    __metaclass__ = MetaFoo 

if __name__ == "__main__": 
    f = Foo() 
    f.bar() 
    print f.bar.func_name 
2

Я думаю, что вы хотите сделать это:

>>> class Foo(): 
... def __init__(self, x): 
...  self.x = x 
... 
>>> def bar(self): 
... print 'bar:', self.x 
... 
>>> bar.func_name = 'foobar' 
>>> Foo.foobar = bar 
>>> f = Foo(12) 
>>> f.foobar() 
bar: 12 
>>> f.foobar.func_name 
'foobar' 

Теперь вы можете передать Foo S в библиотеку, которая ожидает Foo экземпляров иметь метод с именем foobar.

К сожалению, (1) Я не знаю, как использовать метаклассы и (2) Я не уверен, что правильно прочитал ваш вопрос, но надеюсь, что это поможет.

Обратите внимание, что func_name присваивается только в Python 2.4 и выше.

 Смежные вопросы

  • Нет связанных вопросов^_^