Страницы

Поиск по вопросам

суббота, 28 декабря 2019 г.

Можно ли в Python нарушить инкапсуляцию?

#python #python_3x #инкапсуляция


Вот код:

class mutant():

    def __init__(self,a,b):
        self.a = a
        self.b = b

    def method_(self):
        print(f'i am good&print a={self.a}')

def method_(self):
    print(f'i am MUTANT&print b={self.b}')

z = mutant(3,500)
z.method_()
z.__dict__['method_'] = method_    
z.method_()


ясное дело не работает. 
можно ли как-то его сделать таким, чтобы на выходе было:

i am good&print a=3
i am MUTANT&print b=500


Помнится где-то читал что в Python инкапсуляция "ненастоящая", а примера найти не
могу. Сможем?
    


Ответы

Ответ 1



Отличие только в типе method vs function. Значит, проще всего обернуть: from types import MethodType ... z = mutant(3,500) method_ = MethodType(method_, z) z.method_() # i am good&print a=3 z.__dict__['method_'] = method_ z.method_() # i am MUTANT&print b=500

Ответ 2



Важное примечание: ни один из способов (даже MethodType из соседнего ответа) не даст доступа к приватным атрибутам, начинающимся с двух подчёркиваний (self.__c). Нужно будет использовать что-то вроде self._mutant__c, как и в других аналогичных случаях. Вариант номер раз, без self (функции и так известен объект через переменную z): class mutant(): ... def method_(): print(f'i am MUTANT&print b={z.b}') z = mutant(3,500) z.method_() z.method_ = method_ z.method_() Вариант номер два, если очень хочется self: import functools class mutant(): ... def method_(self): print(f'i am MUTANT&print b={self.b}') z = mutant(3,500) z.method_() z.method_ = functools.partial(method_, z) z.method_() Вариант номер три, с изменением класса, а не экземпляра: class mutant(): ... def method_(self): print(f'i am MUTANT&print b={self.b}') z = mutant(3,500) z.method_() mutant.method_ = method_ z.method_() Вариант номер четыре — MethodType

Комментариев нет:

Отправить комментарий