I am trying to delete an instance of a class when a condition is done. But I am having issues, because it´s being deleted before it enters the condition. I don´t know what´s happening... The code uses wxpython with some buttons for deleting ítems, so I build the buttons correctly on init but when I try to delete an ítem, before it reaches the first conditional, it seems to be deleted by the las conditional, that should be never done before. So I don´t know where the problem comes from... The error I get when i press the button 'deleteitem' for the first time is:
'local variable 'T' referenced before assignment' (in 6th the line:... if T.items>0:)
But if I delete the last line del(T) it doesn´t give any error.
Here goes the basic code:
class Test(object):
def __init__(self):
self.items=8
T=Test()
if button.GetName()=='deleteitem':
if T.items>0:
T.items-=1
if T.items<0:
del(T)
EDITED:
OK, as the example I posted firstly can work, here goes the code that doesn´t work:
import wx
class Test(object):
def __init__(self):
self.items=8
T=Test()
class MyFrame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, -1, title,
pos=(150, 150), size=(350, 200))
self.btn = wx.Button(self, -1, "Press to delete Item, current Items: "+str(T.items))
self.Bind(wx.EVT_BUTTON, self.OnButton, self.btn)
def OnButton(self, evt):
print 'Current Items: '+str(T.items)
self.btn.SetLabel('Press to delete Item, current Items: '+str(T.items))
if T.items>0:
T.items-=1
if T.items==0:
del(T)
class MyApp(wx.App):
def OnInit(self):
frame = MyFrame(None, "Simple wxPython App")
frame.Show(True)
return True
app = MyApp()
app.MainLoop()
FINAL WORKING CODE:
import wx
class Test(object):
def __init__(self):
self.items=8
class MyFrame(wx.Frame):
def __init__(self, parent, title):
self.T=Test()
wx.Frame.__init__(self, parent, -1, title,
pos=(150, 150), size=(350, 200))
self.btn = wx.Button(self, -1, "Press to delete Item, current Items: "+str(self.T.items))
self.Bind(wx.EVT_BUTTON, self.OnButton, self.btn)
def OnButton(self, evt):
if self.T.items>0:
self.T.items-=1
if self.T.items==0:
del(self.T)
self.btn.SetLabel('Deleted instance T')
else:
self.btn.SetLabel('Press to delete Item, current Items: '+str(self.T.items))
print 'current Items: '+str(self.T.items)
class MyApp(wx.App):
def OnInit(self):
frame = MyFrame(None, "Simple wxPython App")
frame.Show(True)
return True
app = MyApp()
app.MainLoop()
You are leaving out some relevant code because this code:
class Test(object):
def __init__(self):
self.items=8
T=Test()
if True:
if T.items>0:
T.items-=1
if T.items<0:
del(T)
executes without error.
In any case, it sounds like your code is some variation of Variable scope in nested functions.
Response to new code:
As far as I can tell, del
localizes a variable:
Example 1:
class Test(object):
def __init__(self):
self.items=8
T = Test()
class Dog(object):
def dostuff(self):
print 'executing dostuff()'
if T.items > 10: #This will never be True
T
Dog().dostuff()
--output:--
executing dostuff()
Example 2:
class Test(object):
def __init__(self):
self.items=8
T = Test()
class Dog(object):
def dostuff(self):
print 'executing dostuff()'
if T.items > 10: #This will never be True
del T
Dog().dostuff()
--output:--
executing dostuff()
Traceback (most recent call last):
File "1.py", line 14, in <module>
Dog().dostuff()
File "1.py", line 10, in dostuff
if T.items > 10:
UnboundLocalError: local variable 'T' referenced before assignment
So it looks like the parser marks T as a local variable inside the dostuff() function--because you can only del
local names (unless you declare T to be global inside dostuff() ). As a result, python won't look outside the dostuff() function for the value of T.
Therefore, another solution(not recommended) would be to do this:
class Test(object):
def __init__(self):
self.items=8
T = Test()
class Dog(object):
def dostuff(self):
global T #<===HERE
print 'executing dostuff()'
if T.items > 10:
del T
Dog().dostuff()
--output:--
executing dostuff()
To solve your problem, I would add the following to the end of your __init__()
function:
self.T = Test()
Or, you could pass T as an argument to __init__()
. It's generally considered terrible program design to have functions inside a class manipulating global variables.