Python - деконструктор не удаляет экземпляр объекта - PullRequest
0 голосов
/ 28 июня 2018

У меня следующая проблема, я любитель сценариев Python. Я создал следующий класс

 roof_height = 3.5 #m
 E = 30000*(10^3) #kN/m^2

 class Brace():
     _registry = []


     def __init__(self,name,coord,b,d, h = roof_height):
          print('Brace created.')
          Brace._registry.append(self)
          self.name  = name 
          self.coord = coord              # pass tuple in the form of (x,y)
          self.b     = b                  # //x global
          self.d     = d                  # //y global
          self.h     = h

      def __del__(self):
          print('Destructor called, Brace deleted.')
          Brace._registry.remove(self)


      def properties(self):
          print("properties of " + self.name + " calculated")
          As = self.b*self.d
          Iy = self.b*(self.d**3)*(1/12)
          Iz = (self.b**3)*(self.d)*(1/12)
          self.Iy =  Iy
          self.Iz =  Iz
          self.As =  As

    def stiffness(self):
        print("stiffnesses of " + self.name + " calculated")
        Kx = 12*E*self.Iy/self.h
        Ky = 12*E*self.Iz/self.h

        self.Kx = Kx
        self.Ky = Ky

Я создал общее свойство _registry класса, чтобы можно было перебирать объекты, что прекрасно работает. Проблемы, с которыми я сталкиваюсь, следующие: 1. Когда я создаю объект, распечатка

 'Brace created'

отображается, но когда я удаляю это сообщение

 'Destructor called, Brace deleted.'

не отображается, пока объект удаляется, также список _registry остается тем же без удаления объекта. Длина списка, очевидно, остается неизменной.

  1. Как я могу избежать создания одного и того же экземпляра дважды с одним и тем же именем, я имею в виду, как я могу проверить дубликаты экземпляров (одно и то же имя объекта и значения атрибута) Нужно ли писать код для него или есть встроенная функция, которую я могу использовать?

1 Ответ

0 голосов
/ 28 июня 2018

1: __del __ () может не вызываться по ряду причин, связанных с сборкой мусора. Из документации :

Обратите внимание, что del x напрямую не вызывает x .__ del __ () - прежние декременты счетчик ссылок для х на единицу, и последний вызывается только когда Счетчик ссылок x reaches достигает нуля. Некоторые общие ситуации, которые могут предотвратить счетчик ссылок объекта до нуля включают в себя: циклические ссылки между объектами (например, двусвязный список или древовидная структура данных с родительскими и дочерними указателями); ссылка на объект в кадре стека функции, которая перехватила исключение (трассировка, сохраненная в sys.exc_info () [2], сохраняет кадр стека в живых); или ссылка на объект в кадре стека, который поднял необработанное исключение в интерактивном режиме (трассировка сохраняется в sys.last_traceback поддерживает фрейм стека). Первая ситуация может быть исправлено только путем явного разрыва циклов; вторая банка быть решена путем освобождения ссылки на объект трассировки, когда он больше не является полезным, и третий может быть решен путем сохранения None в sys.last_traceback. Циркулярные ссылки, которые являются мусором обнаружены и очищается, когда включен циклический сборщик мусора (включен по умолчанию). Обратитесь к документации для модуля gc для получения дополнительной информации. информация по этой теме.

Вместо того, чтобы полагаться на встроенную функцию управления памятью, возможно, вы могли бы реализовать специальную функцию для освобождения ресурсов, когда объект больше не нужен?

2: чтобы избежать двух экземпляров с одинаковыми именами, используйте фабричный шаблон .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...