5

Why does the example below only work if the useless _ variable is created?

The _ variable is assigned and never used. I would assume a good compiler would optimize and not even create it, instead it does make a difference.

If I remove _ = and leave just Test(), then the window is created, but it flickers and disappears immediately, and python hangs forever.

Here is the code:

import sys
from PyQt4 import QtGui

class Test(QtGui.QWidget):
    def __init__(self):
        super().__init__()
        self.show()

app = QtGui.QApplication(sys.argv)
_ = Test()
sys.exit(app.exec_())
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
stenci
  • 8,290
  • 14
  • 64
  • 104
  • 5
    You mean `Test()` instead of `Example()`? – OneCricketeer Aug 15 '16 at 20:41
  • 4
    If a Python object isn't referenced, it is garbage collected, which would explain why the window flickers then disappears. – juanpa.arrivillaga Aug 15 '16 at 20:47
  • 1
    So a variable that your program won't work without is "useless"? – kindall Aug 15 '16 at 20:49
  • `I would assume a good compiler would optimize and not even create it` - python is not compiled and doesn't have a compiler. It will do exactly what you tell it. Also, function calls and object creation can have arbitrary side effects, for example `class Evil(object): def __init__(self): import os; os.rmdir('/')` – Daenyth Aug 15 '16 at 20:56
  • Re: "assume a good compiler would optimize and not even create it" -- any module-scoped assignment has side effects, inasmuch as it's... well... *creating a variable in the module*. That variable can be dynamically searched for by code that doesn't exist yet, potentially code outside the module. – Charles Duffy Aug 15 '16 at 20:56
  • ...if this were C, then you'd be creating a variable that could be linked to by other object files, so the compiler couldn't optimize it away -- which is to say that there's no implicit `static` for module-scoped variables. – Charles Duffy Aug 15 '16 at 20:57

2 Answers2

3

That's a very good question and I've faced a lot of weird problems in the past because of this fact with my PyQt widgets and plugins, basically that happens thanks to the python garbage collector.

When you assign your instance to that _ dummy variable before entering the Qt's main loop, there will be a living reference that will avoid to be collected by the garbage collector, therefore the widget won't be destroyed.

Community
  • 1
  • 1
BPL
  • 9,632
  • 9
  • 59
  • 117
  • Does that mean that if I want to create the window inside a method of a non-global object, then the window would be destroyed as soon as the object goes out of scope? And if I wanted to (I don't know for what reason) I would need to assign it to a global variable? – stenci Aug 15 '16 at 20:55
  • Yes, that's exactly what it means. – Charles Duffy Aug 15 '16 at 20:59
0

@BPL is correct, but I wanted to add that you don't have to assign it to _. You can assign it to whatever variable you like. You just need a variable referencing to the object you created, otherwise it's collected by the garbage collector after being created.

Israel Unterman
  • 13,158
  • 4
  • 28
  • 35