[Tutor] Strange issue w/ Python shell 3.0.0.

Steven D'Aprano steve at pearwood.info
Sun Nov 24 02:09:58 CET 2013


On Sat, Nov 23, 2013 at 07:51:59PM +0100, Rafael Knuth wrote:
> > Oh, wait, I see you are using Python 3.0. Don't. Python 3.0 is not
> > supported because it is buggy. You should use 3.1, or better still, 3.3.
> > Python 3.3 is much better than 3.1 or 3.2, and 3.0 is buggy and slow.
> 
> What I was trying to say is that sometimes I get runtime errors even
> if nothing's wrong with my code.

> I had those issues with Python 3.3.0 ... I wrote a program and when I
> executed it, and a runtime error occured.
> I then copy and pasted that into a new window, I saved it and -
> surprise, surprise - it ran without any issues. Although I didn't
> modify my program in any ways.

Are you perhaps using IDLE? 

Without seeing exactly what you mean, I'm not sure, but I *think* what 
is happening is something like this example.


In Window #1, you have something like this:


py> class Test:
...     attr = 23
...     def test():  # oops a bug
...             print(self.attr)
...
py> x = Test()
py> x.test()  # failure!
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: test() takes no arguments (1 given)
py>
py> # edit the Test class
... class Test:
...     attr = 23
...     def test(self):  # Fixed!
...             print(self.attr)
...
py> x.test()  # but the error doesn't go away!
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: test() takes no arguments (1 given)



So then you copy and paste the Test class into Window #2, where it works 
perfectly:

py> class Test:
...     attr = 23
...     def test(self):  # Fixed!
...             print(self.attr)
...
py> y = Test()
py> y.test()
23


What's going on?

It's not that Python has a cache, well, I suppose in a vague sense it 
does, but that *you* inadvertently have a cache. The problem is back in 
Window #1, where you have x = Test() with the buggy version of the 
method (missing the "self" argument). I must admit I kinda lied in the 
comment to this bit:

py> # edit the Test class
... class Test:
...     attr = 23
...     def test(self):  # Fixed!
...             print(self.attr)


I didn't "edit the Test class" at all, although it looks like it. I 
actually created a NEW Test class, that looks the same except for the 
fixed bug. But x still belongs to the OLD Test class, so it still 
experiences the same bug, since as far as it is concerned, nothing has 
changed.


What's going on here may be a little more clear if we avoid classes and 
just look at simple values:

py> s = "Hello Wolrd!"  # Oops a typo!
py> motd = "The message of the day is: " + s
py> print(motd)  # oops, this is buggy
The message of the day is: Hello Wolrd!
py> s = "Hello World!"  # Edit s to fix the typo.
py> print(motd)  # but motd has no way of knowing that
The message of the day is: Hello Wolrd!


Again, the same lie: I haven't actually edited s, and even if I had, it 
wouldn't effect motd. I've created a new s, which replaces the old one, 
but anything which was created from the old one will see no change.

I can't tell if this is the problem you're experiencing, but from my 
experience as a beginner, it seems a reasonable chance.


So, what to do about it? While the Python interactive interpreter is 
mighty powerful, it does have some limitations, and this is one of them. 
You just have to get used to the fact that it is not well-suited for 
editing large blocks of code. It is excellent for trying out small 
snippets, or for running blocks of code that don't have to change, but 
not for editing and running at the same time (at least not until you're 
experienced enough to deal with errors like this one).



-- 
Steven


More information about the Tutor mailing list