Как добавить метод с помощью метакласса
Вопрос
Как добавить метод экземпляра в класс с помощью метакласса (да, мне нужно использовать метакласс)?Следующий тип работает, но имя_функции по-прежнему будет «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 и позже не может найти метод bar экземпляра Foo.Я мог бы сделать:
dict["foobar"] = types.FunctionType(bar.func_code, {}, "foobar")
Существует также типы.MethodType, но мне нужен экземпляр, которого еще не существует, чтобы его использовать.Я что-то упускаю здесь?
Решение
Попробуйте динамически расширить базы таким образом, чтобы вы могли воспользоваться преимуществами 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
Другие советы
Я думаю, что вы хотите сделать следующее:
>>> 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 и выше.