[Tutor] Class Inheritance

Alan Gauld alan.gauld at btinternet.com
Fri Apr 23 09:42:51 CEST 2010

"David Hutto" <smokefloat at gmail.com> wrote 

> While experimenting with Tkinter(python2.6), when from Tkinter import*
> is used I came across the following error:
> ************
>  File "C:\Python26\lib\lib-tk\Tkinter.py", line 44, in <module>
>    from turtle import *

Huh? Why is Tkinter.py importing from turtle?
It doesn't in my Python 2.5 version.

>  File "C:\Python26\lib\lib-tk\turtle.py", line 374, in <module>
>    class ScrolledCanvas(Tkinter.Frame):
> AttributeError: 'module' object has no attribute 'Frame'

Which is also odd since turtle.py imports Tkinter as TK 
so why would it be referring to Tkinter? Something is 
broken in your standard modules!

> Which stems from the below in turtle.py:
> class ScrolledCanvas(TK.Frame)
> I know that ScrolledCanvas is trying to use class TK.Frame as it's base
> class to build from, and the class Frame is what is trying to be called
> from the Tkinter module.

Yes, TK is an alias for Tkinter. So why is your error showing 
Tkinter when the module imports it as TK?

> So I tried to alter the turtle.py. When I try to just 'from Tkinter
> import *, such as:

Don't ever modify the standard modules! There lies chaos. 
If you want to try changing something make a copy and work 
on that. Then you know you can go back to something that 
has been tested and proven to work.

> from Tkinter import *
> class ScrolledCanvas(Tkinter.Frame):
> I get:
> *****************
>    class ScrolledCanvas(Tkinter.Frame):
> NameError: name 'Tkinter' is not defined

Thats right, when you import * you import all the names 
inside the module but not the module itself. So any references 
to the module will generate this error.

> I know pretty much what is going on there. But when I try to use:
> import Tkinter
> from Tkinter import *

Don't mix these two styles. It is very common for modules to 
contain objects of the same name as the module so the second 
import often hides the module name. And if you do it the other 
way round the module name hides the internal object. 
Its just confusing. Use one or the other and preferrably don't 
use import * except for experimenting at the >>> prompt.

> class ScrolledCanvas(Tkinter.Frame):
> It takes me back to the first error. Which means
> in both instances both directly called by me, and
> when called from the original turtle.py call,
> it's not finding the Frame class.

Because by messing about with the imports you have confused 
things to the point where Python doesn't know where to look for it.
Go back to the standard modules and work with them as-is. 
They work.

> for example, when the base class is defined in another module:
> class DerivedClassName(modname.BaseClassName)
> "
> So why does the above, from turtle.py, a standard module,
> not allow this, 

It does and in its original form

import Tkinter as TK
class ScrolledCanvas(TK.Frame)

It works just fine!

> the module writer got wrong, or more likely, that I'm not
> understanding about what it's doing?

You don't understand how Python module imports and namespaces 
work. Try reading the "Modules and Function" topic in my tutorial 
followed by "Whats in a name"?

> As a sidenote, I ended up removing the from turtle import *
> line from Tkinter which resolved the problem(the example I was using
> didn't have a canvas, and I'm pretty sure Tkinter was defaulting
> to the ScrolledCanvas).

How did it get there in the first place? Did you add it?
Why would Tkinter import turtle? turtle is built using Tkinter 
not the other way around. Do not change the standard library 
modules - they work just fine as they are. And because they 
are used by other modules beeaking one is likely to cause 
an avalanche effect. 

If you really think you can improve on them make a copy 
with a new name and change it.


Alan Gauld
Author of the Learn to Program web site

More information about the Tutor mailing list