Would you prefer using del or reassigning to None (garbage collecting)

后端 未结 3 1645
余生分开走
余生分开走 2020-12-18 17:49

Consider following code:

if value and self.fps_display is None:
    self.fps_display = clock.ClockDisplay()
elif not value and self.fps_display is not None:
         


        
相关标签:
3条回答
  • 2020-12-18 18:34

    You have an object with an attribute, fps_display.

    You shouldn't make the attribute weirdly optional or sometimes missing.

    If it's a first-class attribute -- and reasonably visible -- it must be set to None to release any resources. Deleting the attribute is creepy because the object now has optional attributes and raises astonishing exceptions.

    self.fps_display = None
    
    0 讨论(0)
  • 2020-12-18 18:37

    There is no difference for garbage collection — in both cases a reference to object pointed to by self.fps_display will be released. Which one you should use depends on whether you want the name to still exist (albeit now pointing to a different object, None), or not.

    0 讨论(0)
  • 2020-12-18 18:43

    The difference is that self.fps_display = None will free whatever it referenced but keep the name around even though it's just referencing None (which is a type, NoneType).

    On the other hand del self.fps_display will completely remove both the name and what it referenced. If you thereafter try to use self.fps_display an AttributeError will be thrown (or NameError in case of a plain variable).

    So in practice, by assigning None to a name you can still use it in expressions while using del the name is completely removed. In the first case a few bytes is needed to keep the name in memory, while the later completely clears all memory usage.

    Some code to illustrate:

    import sys
    import gc
    
    x = 'Some text here to give the variable a decent size'
    y = 2
    print('x value before deletion: {}'.format(x))
    print('x size before deletion: {} bytes'.format(sys.getsizeof(x)))
    print('y value before deletion: {}'.format(y))
    
    x = None
    del y
    gc.collect() # Not really needed, just to show garbage collection has been done hereafter
    
    print('x value after deletion: {}'.format(x))
    print('x size after deletion: {} bytes'.format(sys.getsizeof(x))) # A few bytes needed to keep symbol name
    print('x type after deletion: {}'.format(type(x)))
    
    if not x:
        print('Can still use x!')
    
    print('y value after deletion: {}'.format(y)) # Will throw NameError (AttributeError in case of class property)
    

    Output:

    x value before deletion: Some text here to give the variable a decent size
    x size before deletion: 98 bytes
    y value before deletion: 2
    x value after deletion: None
    x size after deletion: 16 bytes
    x type after deletion: <class 'NoneType'>
    Can still use x!
    Traceback (most recent call last):
      File "Untitled.py", line 21, in <module>
        print('y value after deletion: {}'.format(y)) # Will throw NameError (AttributeError in case of class property)
    NameError: name 'y' is not defined
    

    Credits

    0 讨论(0)
提交回复
热议问题