Это на самом деле можно, не изменяя класс, основанный на этом answer Алекс Мартелли:
class A(object):
def __init__(self, words):
self.words = words
def get_words(self):
return self.words
a = A("I am a")
b = A("I am b")
def make_meth(inst, _cls, meth, lm):
inst.__class__ = type(_cls.__name__, (_cls,), {meth: lm})
make_meth(a, A, "__len__", lambda self: 12)
make_meth(b, A, "__len__", lambda self: 44)
print(len(b))
print(len(a))
print(a.get_words())
print(b.get_words())
Если мы запустим код:
In [15]: a = A("I am a")
In [16]: b = A("I am b")
In [17]: make_meth(a, A, "__len__", lambda self: 12)
In [18]: make_meth(b, A, "__len__", lambda self: 44)
In [19]: print(len(b))
44
In [20]: print(len(a))
12
In [21]: print(a.get_words())
I am a
In [22]: print(b.get_words())
I an b
Согласно последней части последней части связанный ответ, вы можете добавлять любые методы в каждом конкретном случае, используя inst.specialmethod
после того, как вы использовали inst.__class__ = type(...
:
In [34]: b.__class__.__str__ = lambda self: "In b"
In [35]: print(str(a))
<__main__.A object at 0x7f37390ae128>
In [36]: print(str(b))
In b
Вашей проблемой является ** **, когда вы определяете '__len__', попробуйте определив его как реальный метод на классе вместо атрибут экземпляра. – jesseroberts
@PadraicCunningham Смотрите мой измененный вопрос. Это не позволяет использовать разные методы '__len__' для разных экземпляров' A'. – ARF
@ARF, я полагаю, вы не можете изменить класс? –