Как удалить объект python
Перейти к содержимому

Как удалить объект python

  • автор:

Как удалить объект python

Рассмотрим пример с редактированием и удалением объектов модели на примере модели Person:

from django.db import models class Person(models.Model): name = models.CharField(max_length=20) age = models.IntegerField()

Обновление

save()

Для обновления объекта также применяется метод save() :

bob = Person.objects.get(id=2) bob.name = "Bob" bob.save()

В этом случае Django полностью обновляет объект, все его свойства, даже если мы их не изменяли. Чтобы указать, что нам надо обновить только определенные поля, следует использовать параметр update_fields :

from .models import Person bob = Person.objects.get(id=1) bob.name = "Robert" bob.save(update_fields=["name"])

Это позволит повысить производительность.

update()

Другой способ обновления объектов представляет метод update() (и его асинхронная версия aupdate() ) в сочетании с методом filter , которые вместе выполняют один запрос к базе данных:

from .models import Person number = Person.objects.filter(id=1).update(name="Mike") print(result) # количество обновленных строк

В данном случае у объектов с устанавливаем для поля name значение «Mike». Метод возвращает количество обновленных строк.

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

Также можно установить и большое количество полей:

Person.objects.filter(id=1).update(name="Mike", age = 33)

Иногда бывает необходимо изменить значение столбца в бд на основании уже имеющегося значения. В этом случае мы можем использовать функцию F() :

from .models import Person from django.db.models import F Person.objects.all(id=2).update(age = F("age") + 1)

В данном случае полю age присваивается уже имеющееся значение, увеличенное на единицу.

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

Если надо обновить вообще все записи, вне зависимости от условия, то необходимо комбинировать метод update с методом all() :

from .models import Person from django.db.models import F Person.objects.all().update(name="Mike") Person.objects.all().update(age = F("age") + 1)
update_or_create()

Метод update_or_create (и его асинхронная версия aupdate_or_create() ) обновляет запись, а если ее нет, то добавляет ее в таблицу:

values_for_update= bob, created = Person.objects.update_or_create(id=2, defaults = values_for_update)

Метод update_or_create() принимает два параметра. Первый параметр представляет критерий выборки объектов, которые будут обновляться. Второй параметр представляет объект со значениями, которые получат выбранные объекты. Если критерию не соответствует никаких объектов, то в таблицу добавляется новый объект, а переменная created будет равна True.

bulk_update()

Метод bulk_update() (и его асинхронная версия abulk_update() ) позволяет обновить за один раз набор объектов.

bulk_update(objs, fields, batch_size=None)

Первый параметр — obj указывает на обновляемые объекты, а второй параметр — fields представляет обновляемые поля с новыми значениями. Последний параметр — batch_size указывает, сколько объектов обновляется в одном запросе (по умолчанию обновляются все объекты)

from .models import Person first_person = Person.objects.get(id=1) first_person.name = "Tomas" second_person = Person.objects.get(id=2) second_person.age = 29 number = Person.objects.bulk_update([first_person, second_person], ["name", "age"]) print(number) # 2

В данном случае у первого объекта обновляется значение поля «name», а у второго — значение поля «age». Поэтому в качестве второго параметра передается список с данными полями. Результатом метода является количество обновленных объектов.

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

Удаление

Для удаления мы можем вызвать метод delete() (либо его асинхронную версию adelete() ) у удаляемого объекта:

person = Person.objects.get(id=2) person.delete()

Если не требуется получение отдельного объекта из базы данных, тогда можно удалить объект с помощью комбинации методов filter() и delete() :

Person.objects.filter(id=4).delete()

Удаление всех данных из таблицы:

Person.objects.all().delete()

Как удалять объекты в canvas python?

Задача следующая: на экране генерируются в разных местах цифры. При клике на них они должны исчезать.

canv.create_text(x1, y1, anchor=W, font=("Purisa", size), text = 1, tag=1) canv.create_text(x1, y1, anchor=W, font=("Purisa", size), text = 2, tag=2) canv.create_text(x1, y1, anchor=W, font=("Purisa", size), text = 3, tag=3) canv.tag_bind(. '', click)

Как сформировать несколько бинтов? и как потом понимать на какую цифру нажали и ее удалить?

  • Вопрос задан более трёх лет назад
  • 4805 просмотров

Комментировать
Решения вопроса 0
Ответы на вопрос 1

SuckMyPython

SuckMyPython @SuckMyPython
matrix.polling(none_stop=True)

# -*- coding: utf8 -*- from tkinter import* import tkinter.ttk as ttk root = Tk() canv = Canvas(root, width=120, height=50) canv.pack() def click1(self): canv.delete(z1) def click2(self): canv.delete(z2) def click3(self): canv.delete(z3) z1 = canv.create_text(20, 20, anchor=W, font=("Purisa", 20), text = 1, tag=1) z2 = canv.create_text(50, 20, anchor=W, font=("Purisa", 20), text = 2, tag=2) z3 = canv.create_text(80, 20, anchor=W, font=("Purisa", 20), text = 3, tag=3) canv.tag_bind(z1, '', click1) canv.tag_bind(z2, '', click2) canv.tag_bind(z3, '', click3) root.mainloop()

Но, если вам нужно что-то вроде игры на основе рандома то вот:

# -*- coding: utf8 -*- from tkinter import* import tkinter.ttk as ttk import random root = Tk() root.geometry("500x500") def z0(): btn.destroy() canv = Canvas(root, width=500, height=500) canv.pack() def click(self): global rin global num canv.delete(num) dbrin = rin print(dbrin) z1() def z1(): global rin global num rin = random.SystemRandom().choice(["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]) xy = random.SystemRandom().choice(["50", "100", "150", "200", "250", "300", "350", "400", "450"]) yx = random.SystemRandom().choice(["450", "400", "350", "300", "250", "200", "150", "100", "50"]) x1 = xy y1 = yx num = canv.create_text(x1, y1, anchor=W, font=("Purisa", 20), text = rin) canv.tag_bind(num, '', click) z1() btn = Button(root, text="START", width=10, height=5, fg="black", command=z0) btn.pack() root.mainloop()

Как удалить объект из словаря python по номеру?

Кратко:Удаление из словаря по номеру записи. При удалении пследовательность должна подстраиваться под новый список. Проблемма в том, чтобы связать новый номер из последовательности к нужной записи в словаре. Подробности ниже.
Выводятся все записи в словаре из json файла. Понимаю, что в словарях нет индекса, но нужно, чтобы выводилось примерно так:
1.Запись№1
2.Запись№2
3Записть№3
4.
Вводится номер из клавиатуры в соответствии с тем что выше.
Удаляется запись под тем номером который выбрали. Я это реализовал, но если повторно запросить удаление по списку, то:
допустим сначала мы удалили №2, тогда в файле останутся объекты под номерами 1,3, 4,5.
Когда мы выведем словарь в следующий раз мы не получим правильную последовательность которая будет соответствовать записям в словаре. Как быть в таком случае? Очень нужна помощь. Вот функция которая отвечает за удаление, а ниже полный код.
К сожалению есть только украинский язык.

def menu_4(): print('За якими ознаками видалити запис?', '1. По номеру в списку', '2. По наявності гарантії', sep='\n') with open('zamov_f.json', 'r') as zamov_f: zamov_f = json.load(open('zamov_f.json')) if input() == '1': for g1 in range(1, len(zamov_f) + 1): pib_n2 = 'pib' + str(g1) print(g1, zamov_f[pib_n2]['ПІБ']) delet = input() pib_n2 = 'pib' + delet del zamov_f[pib_n2] #print(tabulate(zamov_f[pib_n2].items(), headers=['Пункт', 'Параметр'], tablefmt="grid")) with open('zamov_f.json', 'w') as zamov_f1: json.dump(zamov_f, zamov_f1, indent=1, ensure_ascii=False) elif input() =='2': for g1 in range(1, len(zamov_f) + 1): . Весь код: import json import os from tabulate import tabulate def menu_1(): a1 = 1 with open('zamov_f.json', 'w') as zamov_f: json.dump(a1, zamov_f, indent=2, ensure_ascii=False) print('Файл створено') menu() def menu_2(): with open('zamov_f.json', 'r') as zamov_f: zamov_f = json.load(open('zamov_f.json')) if os.stat('zamov_f.json').st_size == 1: print('Файл пустий') else: for g in range(1, len(zamov_f) + 1): pib_n2 = 'pib' + str(g) print(tabulate(zamov_f[pib_n2].items(), headers=['Пункт', 'Параметр'], tablefmt="grid")) menu() def menu(): print('Виберіть пункт з меню:') print('1. Створення нового файлу замовлень на фарбування авто') print('2. Перегляд існуючого файлу') print('3. Додавання замовлень на фарбування') print('4. Видалення записів з файлу') print('5. Редагування записів') print('6. Сортування записів') print('7. Обслуговування запитів') otvet = input() if otvet == '1': menu_1() elif otvet == '2': menu_2() elif otvet == '3': menu_3() elif otvet == '4': menu_4() elif otvet == '5': menu_5() elif otvet == '6': menu_6() elif otvet == '7': menu_7() else: print('Введені дані некоректні або не вірні!') menu() def menu_3(): o = 1 zamov_s = <> while True: while True: print("Введіть Ім'я Прізвище замовника") pib = input() pib = pib.strip() pib = pib.title() pib = " ".join(pib.split()) pib2 = pib.split() pib = pib2[0] + pib2[1] if pib.isalpha() == True: pib = pib2[0] + ' ' + pib2[1] break else: print('''У вказаних даних неможна використовувати цифри та спеціальні символи, а тільки букви та пробіли. ''') print('Виберіть тип фарби: ') print('1. Металік', '2. Блиск', '3. Вініл', sep='\n') tip = input() if tip != '1' and tip != '2' and tip != '3': print('Введені дані некоректні або не вірні!') print('Виберіть клас фаби: ') print('1. Економ', '2. Середній', '3. Преміум', sep='\n') klas = input() if klas != '1' and klas != '2' and klas != '3': print('Введені дані некоректні або не вірні!') print('Виберіть колір фарби: ') print('1. Red', '2. Green', '3. Brown', '4. Black', '5. White', sep='\n') color = input() if color != '1' and color != '2' and color != '3' and color != '4' and color != '5': print('Введені дані некоректні або не вірні!') termin = int(input('Введіть термін роботи: ')) garant = input('Чи потрібна гарантія? (+/-) ') if garant != '+' and garant != '-': print('Введені дані некоректні або не вірні!') if tip == '1': tip = "Metalik" elif tip == '2': tip = "Blisk" elif tip == '3': tip = "Vinil" if klas == '1': klas = 'Ekonom' elif klas == '2': klas = 'Midl' elif klas == '3': klas = 'Premium' if color == '1': color = 'Red' elif color == '2': color = 'Green' elif color == '3': color = 'Brown' elif color == '4': color = 'Black' elif color == '5': color = 'White' with open('baza_farb.json', 'r') as baza_f: baza_f = json.load(open('baza_farb.json')) prise = baza_f[tip][klas][color] if 3 o = o + 1 with open('zamov_f.json', 'w') as zamov_s2: json.dump(zamov_s, zamov_s2, indent=2, ensure_ascii=False) print('Ввести наступне замовлення?(-/+)') if input() == '-': menu() break def menu_4(): print('За якими ознаками видалити запис?', '1. По номеру в списку', '2. По наявності гарантії', sep='\n') with open('zamov_f.json', 'r') as zamov_f: zamov_f = json.load(open('zamov_f.json')) if input() == '1': for g1 in range(1, len(zamov_f) + 1): pib_n2 = 'pib' + str(g1) print(g1, zamov_f[pib_n2]['ПІБ']) delet = input() pib_n2 = 'pib' + delet del zamov_f[pib_n2] #print(tabulate(zamov_f[pib_n2].items(), headers=['Пункт', 'Параметр'], tablefmt="grid")) with open('zamov_f.json', 'w') as zamov_f1: json.dump(zamov_f, zamov_f1, indent=1, ensure_ascii=False) elif input() =='2': for g1 in range(1, len(zamov_f) + 1): . menu()
  • Вопрос задан более года назад
  • 95 просмотров

2 комментария

Средний 2 комментария

Удаление объекта

Здравствуйте, господа.
Больно в гугле велики расхождения ответов на данный вопрос, потому переадресовываю его вам: можно ли как-либо удалить в питоне экземпляр объекта так, что бы все ссылки на него (которых может быть сотни из разных кусков проекта) стали None (и он сам в памяти пропал, что бы gc собрал его компоненты, на которые больше никто не ссылался)

Лучшие ответы ( 1 )
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:

Удаление объекта класса в конструкторе
Приветствую, форумчане! Мне необходимо при определённых условиях возвращать из конструктора None.

Удаление объекта класса
Подскажите пожалуйста какую команду и как использовать в python для выполнения следующих действий.

Произойдёт ли удаление объекта без вызова term?
from django.db import models import datetime from django.utils import timezone class.

Удаление объектов из списка и удаление самого объекта
Здраствуйте! Возник такой вопрос, допустим имеется структура данных (неважно, будь то словарь или.

Удаление объекта
Добрый вечер! Я бы хотел уточнить. Если у нас есть такая структура, class A< private.

Эксперт Python

5416 / 3840 / 1214
Регистрация: 28.10.2013
Сообщений: 9,554
Записей в блоге: 1

ЦитатаСообщение от Nordicus666 Посмотреть сообщение

которых может быть сотни

Каким образом вы считали?
Существует два способа это сделать: просто предположить и использовать специальную функцию для подсчета.
Почему вы думаете что их нужно удалить?
Если объект никем не используется и его счетчик ссылок достиг нуля — будет произведено удаление по decref.
Если на объект существует циклическая ссылка и на него нет внешних ссылок (только внутренние) — gc разрулит это сам с помощью cycle finder. В крайнем случае объект уйдет в garbage контейнер.
Если объект используется, а вы все-таки хотите его удалить — вы хотите странного.

Инструменты очистки памяти для тяжелых случаев плохо написанного кода:
1) gc.collect()
2) слабые ссылки (weakref)
3) увеличение порогового значения (sys.set_threshold) для объектов нулевого поколения: чтобы gc срабатывал чаще.

Регистрация: 05.04.2016
Сообщений: 410

у меня крупный проект, а именно: 3д движок по мотивам юнити (похожая структура), следовательно, допустим, имеется объект в мировом пространстве, а на него есть десяток ссылок из каких-либо скриптов в других объектах, а так же одна ссылка как минимум из списка объектов мира, так вот в одном из скриптов мне нужно его удалить, при том удалить так, что бы удалилась не ссылка из того скрипта на него, а сам объект пропал и ВСЕ ссылки на него у всех стали None
Мультипроцессорности у меня нет, так что в процессе удаления объект не может использоваться

562 / 302 / 189
Регистрация: 20.05.2016
Сообщений: 592

Питон так устроен, что вы не можете удалить непосредственно объект, или обнулить счетчик ссылок на него (исключая, возможно, один очень нехороший способ). Если счетчик ссылок не равен нулю, значит объект используется, и его неожиданное исчезновение повлечет за собой неприятные последствия вроде проброса (произвольного) исключения.

Можно попытаться подменить объект мягкоссылочной проксей — weakref.proxy / weakref.ref, однако, есть неудобные побочные эффекты, вроде необходимости писательства скобок всюду, где используется ref, или проброса исключения ReferenceError, если объект на который ссылается proxy больше не существует.

пример weakref

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
import weakref import sys def callback(weakproxy): print("CALLBACK") class O: pass oo = O() print('refcount', sys.getrefcount(oo) - 1) po = weakref.proxy(oo, callback) ro = weakref.ref(oo) # далее вместо oo везде используем po или ro print('refcount', sys.getrefcount(oo) - 1) print(ro()) print(po) del oo print(ro()) print(po)

Или Вы, возможно, что-то иное подразумевете под ссылками, и мы вас не понимаем.

Регистрация: 05.04.2016
Сообщений: 410

Что такое ссылка я вполне понимаю и ничего уникального не подразумеваю
Что ж, всё таки оказались верны те ответы гугла, которые говорили, что так сделать в питоне невозможно.. печально, значит будет ненадёжное удаление..
а про weakref’ы почитаю для профилактики, просто не вариант переписывать мой проект под подобную структуру, когда завтра дедлайн)

Эксперт Python

5416 / 3840 / 1214
Регистрация: 28.10.2013
Сообщений: 9,554
Записей в блоге: 1

ЦитатаСообщение от Nordicus666 Посмотреть сообщение

печально, значит будет ненадёжное удаление.

То есть вы все-таки хотите странного?
Python не СИ — он все делает за ВАС в плане управления памятью.
Если объект в какой-то момент выполнения кода вам становится не нужным — вы просто делаете del объект и все: привязка объекта к имени переменной удаляется из данного namespace, а счетчик ссылок на объект уменьшается на единицу, при нулевом числе ссылок память занимаемая объектом автоматически деаллоцируется.

Регистрация: 05.04.2016
Сообщений: 410

Да эти вещи я и так понимаю, я искал способ обойти механику питона и именно удалить объект, т.е. что бы все ссылки на него занулились

Эксперт Python

5416 / 3840 / 1214
Регистрация: 28.10.2013
Сообщений: 9,554
Записей в блоге: 1

Механику Python не нужно обходить — нужно просто писать python way код и делать грамотную архитектуру проекта.
Все остальное python сделает за вас.
Для удаления объектов (с удалением привязки к имени) существует единственный нормальный способ: del obj.
То что хотите вы — даже в СИ не делается, поскольку ручное управление подразумевает немедленную деаллокацию ненужной переменной самим программистом в том месте, где она была определена.

Регистрация: 23.05.2022
Сообщений: 2

Лучший ответ

Сообщение было отмечено Notrum666 как решение

Решение

То, что в python нельзя гарантировано удалить экземпляр объекта вручную мне кажется не совсем правда. Да, сборщик мусора будет тупить пока существуют ссылки на экземпляр объекта, но кто сказал, что нельзя занулить сам экземпляр и тогда ссылки на него исчезнут.
Пример рабочего кода:

#!/usr/bin/python2.7 import threading import time import sys class f(): num = 0 stop = 0 threads = [] def __init__(self, _num): self.num = _num print(str(self.num)," created") self.threads.append(threading.Thread(target=self.listen, name="audio", args=())) self.threads.append(threading.Thread(target=self.listen, name="video", args=())) def listen(self): while stop == 0: print (self.num) time.sleep(2) def stop(self): self.stop = 1 stop_flag = len(self.threads) print(str(self.num)," closing. ") while stop_flag > 0: for th in self.threads: if not th.is_alive(): stop_flag -= 1 del th else: print(str(self.num)," thread named " + th.getName() + " still alive!") self.threads.clear() self.threads = None del self def __del__(self): print("Avaible links to this object: " + str(sys.getrefcount(self))) print("Object destroyed") pipes = [] for i in range(0,5): pipes.append(f(i)) print("Deleting objects. ") for x in range(len(pipes)-1, -1, -1): pipes[x].stop() del pipes[x] print ("Now pipes: ", len(pipes)) print("2 seconds to terminate. ") for i in range(0,2): time.sleep(1) print ("Now pipes: ", len(pipes))

Тут мы создаем сложные экземпляры объектов, которые тормозят собственное удаление рабочими потоками. Однако, если запустить код можно увидеть, что они удаляются не по причине завершения скрипта, а по нашему вызову, что соответствует нашей задаче.
Profit, please!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *