Python-сообщество
- Начало
- » Python для новичков
- » Удаление объекта из функции
#1 Сен. 18, 2012 12:44:52
serj Зарегистрирован: 2012-06-19 Сообщения: 14 Репутация: 0 Профиль Отправить e-mail
Удаление объекта из функции
Подскажите как удалить экземпляр объекта как в примере.
Т.к. в функции создаются копии, то и удаляются копии, мне надо удалить исходные объекты.
Вот код примера:
class ttest(): def __init__(self): self.a = 100 def __del__(self): self.a = 0 def del_obj(*args): for obj in args: if obj: try: print 'del %s' % obj del(obj) except: pass a,b = ttest(), ttest() print a.a,b.a del_obj(a,b) print a.a,b.a
#2 Сен. 18, 2012 14:32:47
fata1ex От: Зарегистрирован: 2009-07-11 Сообщения: 732 Репутация: 52 Профиль Отправить e-mail
Удаление объекта из функции
Почитайте, что такое метод __del__ и зачем он нужен. Зачем вам вообще удалять объекты? Сомневаетесь в сборщике мусора или не хотите добавить метод типа flush или teardown?
#3 Сен. 18, 2012 14:57:29
serj Зарегистрирован: 2012-06-19 Сообщения: 14 Репутация: 0 Профиль Отправить e-mail
Удаление объекта из функции
fata1ex
Почитайте, что такое метод __del__ и зачем он нужен. Зачем вам вообще удалять объекты? Сомневаетесь в сборщике мусора или не хотите добавить метод типа flush или teardown?
У меня есть несколько своих классов, один работает с БД и закрывает соединение в __del__ и другой, который тоже завершает соединение с портами..
Все это работает в консольном приложении, которое обрабатывает свое закрытие и надо закрыть все коннекты и тд.
Признаюсь о flush и teardown не знал.. почитаю.
Но все равно вопрос открыт, как все же обработать в функции не ссылки или копии объекта а сам объект без глобальных переменных
#4 Сен. 18, 2012 16:07:14
EBFE Зарегистрирован: 2012-07-03 Сообщения: 99 Репутация: 20 Профиль Отправить e-mail
Удаление объекта из функции
Т.к. в функции создаются копии, то и удаляются копии
Не копии. Просто del не вызывает сразу __del__ метод:
class ttest(object): def __init__(self): self.a=100 print id(self) def __del__(self): print "dying :(", id(self) self.a=0 def del_obj(*args): for obj in args: if obj: try: print type(obj),'del',id(obj) del(obj) except: pass a,b = ttest(), ttest() print a.a,b.a del_obj(a,b) print a.a,b.a del([a,b])
>>> a,b = ttest(), ttest()
63513880
63513936
>>> print a.a,b.a
100 100
>>> del_obj(a,b)
del 63513880
del 63513936
>>> print a.a,b.a
100 100
>>> del([a,b])
dying :( 63513880
dying :( 63513936
Отредактировано EBFE (Сен. 18, 2012 16:17:58)
#5 Сен. 18, 2012 16:18:36
serj Зарегистрирован: 2012-06-19 Сообщения: 14 Репутация: 0 Профиль Отправить e-mail
Удаление объекта из функции
Т.к. в функции создаются копии, то и удаляются копии
Не копии. Просто del не вызывает сразу __del__ метод:
class ttest(object): def __init__(self): self.a=100 print id(self) def __del__(self): print "dying :(", id(self) self.a=0 def del_obj(*args): for obj in args: if obj: try: print type(obj),'del',id(obj) del(obj) except: pass a,b = ttest(), ttest() print a.a,b.a del_obj(a,b) print a.a,b.a del([a,b]) >>> a,b = ttest(), ttest() 63512704 63513376 >>> print a.a,b.a 100 100 >>> del_obj(a,b) class '__main__.ttest'> del 63512704 class '__main__.ttest'> del 63513376 >>> print a.a,b.a 100 100 >>> del([a,b]) dying :( 63514048 dying :( 63513488
Спасибо что просветили про del() !
#6 Сен. 18, 2012 16:32:53
EBFE Зарегистрирован: 2012-07-03 Сообщения: 99 Репутация: 20 Профиль Отправить e-mail
Удаление объекта из функции
А что вам вообще нужно? В смысле: закрыть соединения сразу (и несмотря на возможные исключения)? => можно использовать with: http://preshing.com/20110920/the-python-with-statement-by-example
закрыть все при завершении? => atexit http://docs.python.org/library/atexit.html
И.т.д — наверняка найдется подходящий шаблон или готовое решение (например Pooling http://pypi.python.org/pypi?%3Aaction=search&term=pool&submit=search )
Отредактировано EBFE (Сен. 18, 2012 16:34:36)
#7 Сен. 18, 2012 16:55:06
serj Зарегистрирован: 2012-06-19 Сообщения: 14 Репутация: 0 Профиль Отправить e-mail
Удаление объекта из функции
EBFE
А что вам вообще нужно? В смысле: закрыть соединения сразу (и несмотря на возможные исключения)? => можно использовать with: http://preshing.com/20110920/the-python-with-statement-by-example
закрыть все при завершении? => atexit http://docs.python.org/library/atexit.html
И.т.д — наверняка найдется подходящий шаблон или готовое решение (например Pooling http://pypi.python.org/pypi?%3Aaction=search&term=pool&submit=search )
Смысл в том, что бы при закрытии/падении приложения, другое приложение контролировало это (некий супервизор) и запускало процесс снова.
Все так и происходит, только при закрытии/падении не обрабатывается отключение от БД, закрытие соединение с gsm-модемов и видимо не успевают освободится ресурсы как запускается новый процесс. Если с БД не беда, то с модулем (платный, на №е кол модемов) беда, ругается что превышено кол-во подключений и т.п. Если при краше приложения вручную не освободить, то при закрытии можно.
#8 Сен. 19, 2012 11:34:08
fata1ex От: Зарегистрирован: 2009-07-11 Сообщения: 732 Репутация: 52 Профиль Отправить e-mail
Удаление объекта из функции
Вы пытаетесь решать не ту задачу. Надо понять, почему падает/закрывается приложение, и добавить аналог finally, который всегда бы закрывал соединение.
fata1ex
Почитайте, что такое метод __del__
EBFE
Note del x doesn’t directly call x.__del__() — the former decrements the reference count for x by one
Как удалить экземпляр класса java
Но можно установить этот экземпляр класса в значение null , чтобы позволить сборщику мусора удалить объект, на который ссылается переменная.
// создание объекта класса MyClass MyClass myObj = new MyClass(); // удаление ссылки на объект myObj = null;
В этом примере переменная myObj ссылается на объект класса MyClass . После установки значения null переменная больше не ссылается на объект, что позволяет сборщику мусора удалить объект.
Как удалить экземпляр класса Python в списке?
Делаю задачку «адресная книга». Создаю экземпляры класса Contact, добавляя их в список, и записываю список в файл, потом при запуске считываю. Все почти работает, но при удалении не вызывается метод __del__ (деструктор) из-за того, как я полагаю, что удаляется не сам объект, а лишь элемент списка. Как мне можно удалить объект?
import pickle class Contact: def __init__(self, name, number): self.name = name self.number = number def info(self): print(f': ') def __del__(self): print(f'Контакт : удален!') try: with open('contacts', 'rb') as f: list_contacts = pickle.load(f) except EOFError: list_contacts = [] while (True): action = input("Возможные действия:\n добавить - 1\n удалить - 2\n все контакты - 3\n выход - q\n> ") if action == '1': list_contacts.append(Contact(input("Имя: "), input("Номер: "))) elif action == '2': for i, j in enumerate(list_contacts, start=1): print(i, end=') ') j.info() select_for_del = int(input("Введите номер удаляемого контакта: ")) del list_contacts[select_for_del - 1] elif action == '3': print('=' * 20) for x in list_contacts: x.info() print('=' * 20) elif action == 'q': with open('contacts', 'wb') as f: pickle.dump(list_contacts, f) break
Отслеживать
47.8k 17 17 золотых знаков 56 56 серебряных знаков 100 100 бронзовых знаков
задан 27 фев 2021 в 17:36
1 1 1 бронзовый знак
Если вопрос в том, чтобы выводилось сообщение — выводите его сами после del. Если вопрос в технических деталях — пока объект привязан хоть к одной переменной (например к переменной j в цикле выше удаления), он не будет удален. Да и то сборщик мусора может быть реализован ленивым и удалять объекты не сразу.
27 фев 2021 в 17:58
так чтобы его самому не выводить, я и прописал «принт» в теле класса
27 фев 2021 в 18:00
Ну, не делайте так) Вообще, потенциальный пользователь будет очень удивлен, когда при выходе из программы получит кучу сообщений, что все его драгоценные контакты удалены (просто потому что при выходе вся память при выходе из программы освобождается) Я думаю, это не очень полезное поведение) Лучше уж вручную выводить сообщение)
27 фев 2021 в 18:02
@insolor, не высвобождается память, как вы предполагаете, я протестил прогу.
27 фев 2021 в 18:08
да, об этом я не подумал, что все объекты будут удалены при выходе 😀
27 фев 2021 в 19:33
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Я немного улучшил ваш код:
import pickle class Contact: def __init__(self, name, number): self.name = name self.number = number def info(self): print(f': ') def _del(self): print(f'Контакт : удален!') try: with open('contacts', 'rb') as f: list_contacts = pickle.load(f) except: list_contacts = <> while (True): action = input("Возможные действия:\n добавить - 1\n удалить - 2\n все контакты - 3\n выход - q\n> ") if action == '1': name = input('Имя: ') number = int(input("Номер: ")) list_contacts[number] = Contact(name, number) elif action == '2': for i in list_contacts.values(): i.info() select_for_del = int(input("Введите номер удаляемого контакта: ")) list_contacts[select_for_del]._del() del list_contacts[select_for_del] elif action == '3': print('=' * 20) for x in list_contacts: x.info() print('=' * 20) elif action == 'q': with open('contacts', 'wb') as f: pickle.dump(list_contacts, f) break
Я поэкспериментировал с выполнением кода, и вот что обнаружилось: сообщение о том что удалено либо появлялось на несколько пунктов дальше, либо не появлялось вообще. Дело в том что как и сказал @insolor в комментарии к вопросу, сборщик мусора был либо ленивый, либо скорее всего объекты и реально привязывались к j .
Я преобразовал список в словарь, так удобнее хранить номера. И просто вызываю .__del() . Потому что .__del__() для другого сделан.
Как удалить экземпляр класса в классе в Python?

Как думаете, если бы это было возможно, чем бы стала равна переменная person2 после удаления объекта?
Решения вопроса 3

Как это — вы хотите из экземпляра класса удалить его же самого?
Задача решается добавлением property класса is_dead и проверкой этого состояния извне. По обнаружению этого факта можно, но только если оч хочется, сделать person2 = None — вот и удаление.
Ответ написан более трёх лет назад
Комментировать
Нравится 4 Комментировать
Andrey_Dolg @Andrey_Dolg
Поддержу человека выше. Вы должны обнулить счетчик ссылок на объект и видимо для этого нужен доступ к переменой person2 вне класса.
Ответ написан более трёх лет назад
Комментировать
Нравится 1 Комментировать
Создайте список в который будете добавлять указатели на обьекты
например:
all_objects = []
person1 = Hero()
person2 = Hero()
all_objects.append(person1)
all_objects.append(person2)
и потом просто проходитесь циклом по этому списку и проверяйте значения health обьекта, если меньше ноля удаляйте
Ответ написан более трёх лет назад
Нравится 1 2 комментария
brain_stem @brain_stem
Если количество персонажей невелико, то окей. А если там огромное количество объектов и высокая динамика ? Каждый раз вызывать метод O(n) — такая себе затея.
brain_stem, разбей список на более мелкие, используй систему графов, кто тебе мешает?
Я привел пример общего назначения, тебе решать как его использовать и(или) как его дополнить. Никто не заставляет тебя использовать код точь-в-точь как в примере.
