Используя отладчик, Created 2 и Destroyed 2 оба отображаются, когда строка x = Test (2); называется. Если мы просто присвоили x объекту 2, почему его деструктор вызывается немедленно? Это следует к следующей части.
blockquote>Строка
x = Test(2);
сначала создаетTest
с аргументом конструктора2
. Это то, что производитCreated 2
. Этот безымянныйTest
затем присваиваетсяx
, что даетx.id
значение 2. Этот безымянныйTest
затем уничтожается в конце выражения, создавая «Уничтожено 2».Во-вторых, поскольку был вызван деструктор для объекта 2, мы можем предположить, что он был уничтожен. Следующий вывод 2, кажется, противоречит этому, поскольку предполагает, что x все еще содержит объект 2 (ожидаемый, но противоречащий вызову его деструктора).
blockquote>Как указано в первой части этого ответа, уничтожается не
x
, а временноTemp
.x.id
все еще действует и выдаст новое значение, 2.Наконец, выводится Destroyed 2. Это имело бы смысл, если бы мы не видели это раньше. Объект 2 хранится в x, поэтому, когда он выходит из области видимости, вызывается деструктор.
blockquote>Это происходит, когда
x
уничтожается в конце функции. Это значениеid
было изменено на 2 предыдущим присваиванием, поэтому оно выдает «Уничтожено 2».1: Почему происходит это странное поведение, и есть ли логическая причина, почему это так?
blockquote>Возможно, это не то поведение, которое вы ожидали, но это не странно. Я надеюсь, что этот ответ поможет вам понять, почему это происходит.
2: приводит ли «переопределение» объекта (например, объекта 1) к другому объекту (объекту 2) посредством присваивания к его деструктору (в данном случае деструктору объекта 1) для вызова или нет? ] blockquote>
Присвоение объекту не разрушает его. Он заменяет его значение новым и в этом смысле «уничтожает» значение , которое ему ранее помогало, но фактический экземпляр объекта не уничтожается, а деструктор не участвует.
Редактировать: Возможно, вас беспокоит утечка ресурсов. Так как
Test
не управляет никакими ресурсами, утечек не будет, и сгенерированные компилятором члены будут вести себя нормально. Если ваш класс действительно управляет ресурсами (обычно в форме динамически выделяемой памяти), то вам нужно будет применить правило 3/5/0 . В частности, вам нужно будет самостоятельно реализовать оператор присваивания, чтобы он очищал любые ранее удерживаемые ресурсы. Недостаточно реализовать только деструктор, поскольку он не участвует в назначении.
Для решения, не включающего выбор модели:
from django.core.validators import MinValueValidator, MaxValueValidator
class Person(models.Model):
year = models.PositiveIntegerField(
validators=[
MinValueValidator(1900),
MaxValueValidator(datetime.now().year)],
help_text="Use the following format: <YYYY>")
Это также создаст заполнитель в поле ввода со значением help_text
.
Кроме того, и это не имеет отношения к вашему случаю, но полезно знать, не используйте datetime.date.today () или datetime.datetime.now () по умолчанию. Это выполняется один раз при запуске сервера.
Намного лучше передать вызываемые объекты в:
date = models.DateField(default=datetime.date.today)
Обратите внимание, вы можете использовать лямбду, чтобы сделать его относительным:
date = models.DateField(default=lambda : datetime.date.today() - datetime.timedelta(days=6210))
Конечно, это наивно, и предполагает, что за последние 17 лет было 5 високосных лет.