LINUX.ORG.RU

[python] циклические зависимости?


0

0

Есть такой код:

class Ancestor:
    def __init__(self):
        self.hello()

    def hello(self):
        print("hello!")

    def __del__(self):
        print("destructor")


class Child(Ancestor):
    def __init__(self):
        self.hello = self.myhello
        Ancestor.__init__(self)

    def myhello(self):
        print("this is my hello")


child = Child()
print("deleting instance")
del child

Так вот надписи «destructor» мы не увидим. Почему такая трава происходит? Как лечить?(делать del self.hello ?).

Re: [python] циклические зависимости?

на ваш код интерпретатор выдал

Traceback (most recent call last):
  File "destruction.py", line 38, in <module>
    child = Child()
  File "destruction.py", line 35, in __init__
    self.hello = self.myhello
AttributeError: Child instance has no attribute 'myhello'
destructor

stave ★★★★★ ()

Re: [python] циклические зависимости?

Как вариант можно в Child назвать метод hello или использовать weakref.

Но почему такое происходит я не понимаю.

Davidov ★★★★ ()

Re: [python] циклические зависимости?

В Питоне нет деструкторов. Умники, которые рассчитывают на Си++-поведение, напршиваются на неприятности.

> Как лечить?

Прогера? Мануальной терапией.

tailgunner ★★★★★ ()
Ответ на: Re: [python] циклические зависимости? от true_admin

Re: [python] циклические зависимости?

> Ок, смотри сюда:

Смотри сюда: "на Си++-поведение".

> http://docs.python.org/3.0/reference/datamodel.html?highlight=__del__#object... .

И вот сюда тоже посмотри: "del x doesn’t directly call x.__del__() — the former decrements the reference count for x by one, and the latter is only called when x‘s reference count reaches zero.

...

Circular references which are garbage are detected when the option cycle detector is enabled (it’s on by default), but can only be cleaned up if there are no Python- level __del__() methods involved."

P.S. А tp_dealloc там просто нет.

tailgunner ★★★★★ ()
Ответ на: Re: [python] циклические зависимости? от tailgunner

Re: [python] циклические зависимости?

Да я вообще не знаю про C++ ничего, мне не это нужно. Мне нужно чтобы память освобождалась. У меня демон на питоне, я хочу понять в каких местах можно накосячить. Я вот одно уже нашёл.

> if there are no Python- level __del__() methods involved.

Мде, получается что нельзя свои __del__ пихать? Я щас проверил, проблема не наблюдается если убрать свой __del__. Проверил путём export PYTHONDUMPREFS=1.

> P.S. А tp_dealloc там просто нет.

это ты к чему? Раз нету и и фиг с ним, про него в другом разделе пишут. Я вообще про внутренности PyObject и PyTypeObject начал говорить потому что по ним очень легко понять что на самом деле твориться в питоне. Пусть это конкретная реализация, но это реализация стандарта.

true_admin ★★★★★ ()
Ответ на: Re: [python] циклические зависимости? от true_admin

Re: [python] циклические зависимости?

> Я щас проверил, проблема не наблюдается если убрать свой __del__.

Афигеть, поведение соответствует документации %) Что же тебя не устраивает?

>> P.S. А tp_dealloc там просто нет.

> это ты к чему?

Ну ты зачем-то помянул его.

> Я вообще про внутренности PyObject и PyTypeObject начал говорить потому что по ним очень легко понять что на самом деле твориться в питоне.

Это детали реализации, на которые нельзя полагаться.

tailgunner ★★★★★ ()
Ответ на: Re: [python] циклические зависимости? от tailgunner

Re: [python] циклические зависимости?

> Афигеть, поведение соответствует документации %) Что же тебя не устраивает?

Поведение.
Я хочу деструктор. Конструктор-то есть, почему бы и деструктор нормальный не сделать.

true_admin ★★★★★ ()
Ответ на: Re: [python] циклические зависимости? от true_admin

Re: [python] циклические зависимости?

> почему бы и деструктор нормальный не сделать.

Спроси об этом на python-dev.

А если тебе и правда нужен деструктор, разбивай циклы руками (как и сказано в доке).

tailgunner ★★★★★ ()
Ответ на: Re: [python] циклические зависимости? от tailgunner

Re: [python] циклические зависимости?

всё, нашёл описание всего этого безобразия.

У gc.garbage написано что к чему.

Блин, что-то питон в последние пол года меня тока разочаровывает...

true_admin ★★★★★ ()
Ответ на: Re: [python] циклические зависимости? от smh

Re: [python] циклические зависимости?

ты выдрал мою фразу из контента. Тут речь идёт о том что gc не работает если в классе есть метод __del__.

В общем, программирование под питон сильно отличается от того что я о нём думал.

true_admin ★★★★★ ()
Ответ на: Re: [python] циклические зависимости? от true_admin

Re: [python] циклические зависимости?

>Я хочу деструктор.

От деструкторов одни проблемы. Даже к канонiчному С++ они привинчены криво: ошибку оттуда вернуть нельзя, экзепшен сконвертируется в terminate().

Absurd ★★★ ()
Ответ на: Re: [python] циклические зависимости? от true_admin

Re: [python] циклические зависимости?

> ты выдрал мою фразу из контента. Тут речь идёт о том что gc не работает если в классе есть метод __del__.

Он работает. Просто вызовется этот метод только тогда, когда ссылок на объект больше не будет.

smh ★★★ ()
Ответ на: Re: [python] циклические зависимости? от smh

Re: [python] циклические зависимости?

>Просто вызовется этот метод только тогда, когда ссылок на объект больше не будет.

А по выходу из программы вызовется? Просто Жаба оставляет память as-is и finalize() не вызывает, например.

Absurd ★★★ ()

Re: [python] циклические зависимости?

hizel@night:~$ cat lor2.py
class Ancestor:
    def __init__(self):
        self.hello()

    def hello(self):
        print("hello!")

    def __del__(self):
        print("destructor")


class Child(Ancestor):
    def __init__(self):
        self.hello = self.myhello
        Ancestor.__init__(self)

    def myhello(self):
        print("this is my hello")


child = Child()
print("deleting instance")
del child.hello
del child

hizel@night:~$ python lor2.py 
this is my hello
deleting instance
destructor

-----

да и почему не написать так?

hizel@night:~$ cat lor2.py
class Ancestor:
    def __init__(self):
        self.hello()

    def hello(self):
        print("hello!")

    def __del__(self):
        print("destructor")


class Child(Ancestor):
    def __init__(self):
        Ancestor.__init__(self)

    def hello(self):
        print("this is my hello")


child = Child()
print("deleting instance")
del child

hizel@night:~$ python lor2.py 
this is my hello
deleting instance
destructor

hizel ★★★★★ ()
Ответ на: Re: [python] циклические зависимости? от Absurd

Re: [python] циклические зависимости?

>Даже к канонiчному С++ они привинчены криво: ошибку оттуда вернуть нельзя, экзепшен сконвертируется в terminate().

Бедные нещасные питоноиды. Им даже в C++ деструкторами нельзя пользоваться. А я вот юзаю их и даже исключения из деструкторов кидаю и успешно ловлю.

legolegs ★★★★★ ()
Ответ на: Re: [python] циклические зависимости? от legolegs

Re: [python] циклические зависимости?

>> Даже при раскрутке стека?

> Нет.

Ну так побереги свою жалость.

> Может надо к проектированию иначе подходить?

А... так ты _это_ проектированием считаешь, прикольно.

tailgunner ★★★★★ ()
Ответ на: Re: [python] циклические зависимости? от legolegs

Re: [python] циклические зависимости?

> А я вот юзаю их и даже исключения из деструкторов кидаю и успешно ловлю.

Можно на пальцах объяснить, где такие исключения уместны?

З.Ы. А неплохо бы компилятору статически проверять, что эти исключения не проявятся при раскрутке стэка.

www_linux_org_ru ★★★★★ ()
Ответ на: Re: [python] циклические зависимости? от hizel

Re: [python] циклические зависимости?

hizel, я про это и писал. Не нравится мне это потому что у меня на самом деле задача совсем другая, я пишу tcp-сервер. Мне бы хотелось чтобы в деструкторе закрывалось соединение и в разные моменты метод on_recv указывал то на do_handshake, то на read_request(), то на terminate_connection().

Самое обидное то что модуль написан на C и я это ограничение GC даже не увижу т.к. tp_free/tp_dealloc будут всё равно вызваны.

PS 2excelion: изыди, плесень.

true_admin ★★★★★ ()
Ответ на: Re: [python] циклические зависимости? от tailgunner

Re: [python] циклические зависимости?

> При том, что на практике ты ими не пользовался.

Твоя оценка м.б. полезна читающим ветку, но не мне.

Ты лучше скажи, какова твоя оценка отступов.

www_linux_org_ru ★★★★★ ()
Ответ на: Re: [python] циклические зависимости? от www_linux_org_ru

Re: [python] циклические зависимости?

>Можно на пальцах объяснить, где такие исключения уместны?

Исключения в деструкторах? Везде, где деструкторы выполняют полезную работу (т.е. делают что-то интереснее delete и записи в логи). Доверять ли деструктору полезную работу? Надо ответить на два вопроса: имеет ли смысл в случае сбоя пытаться проделать действие ещё раз? Насколько ужасно, если программист забудет вызвать отдельный метод (конструктор вызовется обязательно)?

>З.Ы. А неплохо бы компилятору статически проверять, что эти исключения не проявятся при раскрутке стэка.

Полагаю, его сообщение будет столь же малополезно, как и -Wunreachable-code: много и почти всегда не по делу. Например, iostream можно заставить генерировать исключения, а при размотке стека он попадётся с большой вероятностью.

legolegs ★★★★★ ()
Ответ на: Re: [python] циклические зависимости? от legolegs

Re: [python] циклические зависимости?

> Надо ответить на два вопроса: имеет ли смысл в случае сбоя пытаться проделать действие ещё раз? Насколько ужасно, если программист забудет вызвать отдельный метод (конструктор вызовется обязательно)?

Хотелось бы именно *пример*, когда это уместно или хотя бы просто хочется сделать (без кода, только постановка задачи).

www_linux_org_ru ★★★★★ ()
Ответ на: Re: [python] циклические зависимости? от legolegs

Re: [python] циклические зависимости?

> А я вот юзаю их и даже исключения из деструкторов кидаю и успешно ловлю.

Можно с этого места подробнее? Что ты имеешь ввиду? Есть непроложное правило: ни деструктор, ни функция swap не могут генерировать исключений (Герб Саттер). Иначе ломается C++, например, при работе с массивами...

dave ★★★★★ ()
Ответ на: Re: [python] циклические зависимости? от tailgunner

Re: [python] циклические зависимости?

> Еще раз повторю - в Питоне нет деструкторов.

ну ок, нету. Тогда по твоей логике программист никак не управляет теми объектами которые он порождает. Т.е. он не может быть уверен что он сможет нормально убить объект когда тот ему будет не нужен, так что ли?

true_admin ★★★★★ ()
Ответ на: Re: [python] циклические зависимости? от true_admin

Re: [python] циклические зависимости?

> Тогда по твоей логике программист никак не управляет теми объектами которые он порождает.

Это не моя логика, не логика вообще, и просто не соответствует реальности.

> Т.е. он не может быть уверен что он сможет нормально убить объект когда тот ему будет не нужен, так что ли?

Примерно так. Практическое следствие для тебя - освобождать системные ресурсы нужно явным образом, не надеясь на сборщик мусора.

tailgunner ★★★★★ ()
Ответ на: Re: [python] циклические зависимости? от tailgunner

Re: [python] циклические зависимости?

> Практическое следствие для тебя - освобождать системные ресурсы нужно явным образом, не надеясь на сборщик мусора.

Вот я весь топик и пытаюсь про это узнать. Как это сделать? :).

true_admin ★★★★★ ()
Ответ на: Re: [python] циклические зависимости? от true_admin

Re: [python] циклические зависимости?

>> Практическое следствие для тебя - освобождать системные ресурсы нужно явным образом, не надеясь на сборщик мусора.

> Вот я весь топик и пытаюсь про это узнать.

Да? O_o

> Как это сделать? :)

Ты даже задачу не сформулировал. Наверняка в твоем сервере есть момент, когда описатель клиента удаляется из массива активных клиентов - там и закрывай сокет (или что у тебя там).

tailgunner ★★★★★ ()
Ответ на: Re: [python] циклические зависимости? от tailgunner

Re: [python] циклические зависимости?

Сформулирую вопрос по-другому.

Я не хочу чтобы сервер тёк памятью. Поэтому я должен уничтожать все объекты что я породил. Ты согласен с этим?

true_admin ★★★★★ ()
Ответ на: Re: [python] циклические зависимости? от true_admin

Re: [python] циклические зависимости?

> Я не хочу чтобы сервер тёк памятью. Поэтому я должен уничтожать все объекты что я породил. Ты согласен с этим?

Нет. Ты должен их "забывать", убирая ссылки на них из долгоживущих структур.

tailgunner ★★★★★ ()
Ответ на: Re: [python] циклические зависимости? от true_admin

Re: [python] циклические зависимости?

> Почему бы мне не использовать __del__ для закрытия сокета?

Потому что момент вызова __del__ определен довольно туманно, и тебе придется самому следить за вещами типа циклических ссылок.

tailgunner ★★★★★ ()
Ответ на: Re: [python] циклические зависимости? от dave

Re: [python] циклические зависимости?

>Есть непроложное правило: ни деструктор, ни функция swap не могут генерировать исключений (Герб Саттер). Иначе ломается C++

Непреложные правила все записаны в стандарте языка и такого там нет.

legolegs ★★★★★ ()
Ответ на: Re: [python] циклические зависимости? от tailgunner

Re: [python] циклические зависимости?

так мне же полюбому надо следить за тем чтобы объекты удалялись, иначе память вся выжрется.

В общем, я тебя давно понял :). Ты как бы намекаешь что не стоит надеяться что будет вызван __del__. Только мне приходится заботится чтобы объекты таки уничтожались. А значит я могу его использовать при условии что я слежу за всеми ссылками на объект. Я правильно рассуждаю? :).

В реальности у меня есть метод self.on_close() в который я могу запихнуть код деструктора. Вернее, я def __del__() переименовал в def on_close().

true_admin ★★★★★ ()
Ответ на: Re: [python] циклические зависимости? от true_admin

Re: [python] циклические зависимости?

> так мне же полюбому надо следить за тем чтобы объекты удалялись, иначе память вся выжрется.

Нет. Тебе надо следить, чтобы ссылки на объекты не зависали в долгоживущих (глобальных) структурах.

> А значит я могу его использовать при условии что я слежу за всеми ссылками на объект. Я правильно рассуждаю? :).

Формально да. Но формально, можно бегать и по полю с граблями. Тем более, что особого обращения только объекты, существующие за пределами процесса.

tailgunner ★★★★★ ()
Ответ на: Re: [python] циклические зависимости? от true_admin

Re: [python] циклические зависимости?

>так мне же полюбому надо следить за тем чтобы объекты удалялись, иначе память вся выжрется.

Не выжрется, если не сохраняешь ссылку на объект ассоциированный с клиентом в долговременной структуре. Мне такое понадобилось только для асинхронного интерфейса работы с БД где по исходящему RPC слался запрос, а потом через входящий RPC получался ответ. Пришлось заводить отдельный тред который инициировал ошибку у неполучивших ответ вовремя и удалял их из постоянной структуры.

Absurd ★★★ ()
Ответ на: Re: [python] циклические зависимости? от legolegs

Re: [python] циклические зависимости?

>Есть непроложное правило: ни деструктор, ни функция swap не могут генерировать исключений (Герб Саттер). Иначе ломается C++

> Непреложные правила все записаны в стандарте языка и такого там нет.

Это неявно предполагается при обработке исключительных ситуаций в конструкторах при выделении как одиночных объектов, так и массивов. Смело можно считать непреложной истиной :)

А ты читал Саттера?

dave ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.