0

I want to add a 'stack' to a class, with methods like this:

class MyClass:

  class Extras:
    # defs...

  def __init__( self ):
    # .. other init code
    self.extras_stack = []

  def push_extras( self, vars ):
    self.extras_stack.append( Extras( vars ) if vars else None )

  def pop_extras( self ):
    extras = self.extras_stack.pop()
    del extras

Now, this seems to work OK, but what is going on when 'del' sees 'None'? I assume it just ignores 'None', but I cannot see that in the python documentation.

Also, why can't I write:

del self.extas_stack.pop()

Since pop() returns an Extras() object (or None), it seems that that ought to work?

EDIT

Sorry again for incorrect/misleading title.

I now understand the source of my misapprehension. The reason is that 'del None' looks like a null-pointer delete in C/C++. That was why it felt wrong to me. The 'Also' part of my question was actually relevant too: The point about del is that it reduces the usage count for an object, you need the variable (which acts as a smart pointer I guess) return to do that. That's why you can't just write 'del self.extras_stack.pop()'.

I also now understand that you can't guarantee for del to be called when 'del x' occurs, which means I can't use it here.

I am sorry if this question is felt to be a duplicate, but I at least feel I have learned something here.

PatB
  • 415
  • 1
  • 5
  • 13
  • The title contradicts the question. Which one to answer? – ivan_pozdeev Apr 09 '18 at 17:00
  • 5
    The `del` statement deletes a _variable_, not the _value_ of the variable. – Aran-Fey Apr 09 '18 at 17:01
  • Reproducible via: `a = None` and `del a` and `print a`. – BlackVegetable Apr 09 '18 at 17:01
  • @ivan_pozdeev Why do you say that? The question is about what happens when `extras = self.extras_stack.pop()` assigns `None` to the variable and then does `del extras`. – Barmar Apr 09 '18 at 17:02
  • Yeah, I'm not seeing this as an exact duplicate. – BlackVegetable Apr 09 '18 at 17:03
  • @Barmar the title asks "What does `del None` do?" The question asks "Can I write `del self.extas_stack.pop()`?" – ivan_pozdeev Apr 09 '18 at 17:03
  • @ivan_pozdeev That's not the main question, he prefixed it with "Also". – Barmar Apr 09 '18 at 17:04
  • Although the answer to the main question also explains why it doesn't work. The parameter has to be a variable, and a function call isn't a variable. – Barmar Apr 09 '18 at 17:05
  • @BlackVegetable Why not? What's wrong with the dupe? – Aran-Fey Apr 09 '18 at 17:05
  • I'm sorry, but I don't believe that that other question tells me what 'del None' does. It says 'The del statement, as you saw, removes the binding of your variable' - but None is not a variable, is it? So what does 'del None' do? Just nothing? Also, 'The del statement deletes a variable, not the value of a variable' seems wrong to me, what I want to happen (and what does happen) is for the __del__ method to be called on the Extras class for this object. The 'Also' part of my initial question asks why a variable is even required to mediate this operation. – PatB Apr 09 '18 at 17:12
  • @PatB If you try it, you'll see that `del None` throws a syntax error, because `None` is not a variable. And the only reason why the `__del__` method on your class is called is because you've deleted all variables that referenced your object, so it got garbage collected. If you have multiple variables pointing to the same object, `del variable_1` won't call your `__del__`. – Aran-Fey Apr 09 '18 at 17:15
  • the other question is not very direct in addressing the distinction between deleting the variable and the value. Frankly it looks like it is asking multiple questions. I think this one should stay open as not exactly a duplicate. – BlackVegetable Apr 09 '18 at 17:20
  • 1
    @Aran-Fey Okay thanks, so my title should have been "What does 'x=None; del x' do". But I need the __del__ method to have been called before returning from pop_extras(), I can't wait for garbage collection. From re-reading the documentation for __del__, it looks as though I should probably avoid it altogether. – PatB Apr 09 '18 at 17:22
  • 1
    Yes, relying on `__del__` to be called is not a good idea. The usual solution is to make your class work as a context manager. – Aran-Fey Apr 09 '18 at 17:36
  • See also:https://stackoverflow.com/questions/6146963/when-is-del-useful-in-python (or in a nutshell: using del all over the place really feels like a code smell ... are you sure you can't just pop the item and let GC handle it?) – Foon Apr 10 '18 at 23:58
  • @Foon no I can't do that: the enclosing class defines variables which are used all over the application. The 'Extras' class adds some extra variables which are only in-scope for a short time. By the time pop_extras() exits it is required that the extra variables have been removed from the MyClass instance. Other than this one case I only use del to remove things from dicts. – PatB Apr 11 '18 at 10:12
  • Perhaps 'unscope' would be a less ambiguous keyword than 'del'! Though very ugly. – PatB Apr 11 '18 at 10:15

0 Answers0