Pull to refresh

Comments 6

А где примеры хулиганства, рассказ хотя бы про monkey-patching и возможности, которые он открывает? Рассказать про то, как это все используется в тестировании и так далее? Как сделать пользовательский класс, которому нельзя назначить атрибут?

Вся статья ужимается до фразы «В питоне можно назначать атрибуты, но не всегда»

Или даже так: "В питоне всё — объекты"

Да и вообще такой нестандартный хак требует подробной документации, потому что объекты А() вроде ничего ниоткуда явно не получают, а тем не менее откуда-то в курсе.

Магия, ага. Так вы и не создаете объекта А(). А вот объект A создается сразу после определения и сразу с атрибутом класса some_variable. А вот конструктор А() вызывается при создании b = B(). Не понимаю почему это "нестандартный хак".
Вас тут спасает, что объект B() не имеет атрибута self.some_variable, поэтому при доступе через b.some_variable возвращается B.some_variable, унаследованный от A.
А вот если сделать b.some_variable = 'bar' проверка не пройдёт, но assert B.some_variable == A.some_variable все еще будет работать. Но и это решается через доступ непосредственно к атрибутам класса. assert b.class.somevariable == A.some_variable Это задокументированное поведение объектов и классов, а не "хак".


Но, да, все это метапрограммирование в питоне требует внимательного изучения и аккуратного применения.

Да, на самом деле всё запоминается легко: питон ищет атрибут у самого объекта, потом у класса, а потом идет вверх по иеархии в соответствии с mro.

О чём статья, вообще не понял. Выглядит недописанной, обрывается как-то внезапно.


Напомнило. Когда-то мне надо было сделать свойства (property) для классов (не для экземпляров).


class BarProperties(type):
    _foo = 0

    @property
    def foo(cls):
        print('get foo')
        return cls._foo

    @foo.setter
    def foo(cls, value):
        print('set foo')
        cls._foo = value

class Bar(metaclass=BarProperties):
    pass

>>>Bar.foo
get foo
0
>>>Bar.foo = 1
set foo
>>>Bar().foo
AttributeError: 'Bar' object has no attribute 'foo'

Такая вот дикость… Но лучше так никогда не делать :)

рано или позно может оказаться, что текущий синглетон нужно выкинуть и подставить на его место новый


На лицо ошибка в архитектуре ПО. И статья о том, как подпереть падающую конструкцию костылём.
Sign up to leave a comment.

Articles