[Tutor] First step

Yigal Duppen yduppen@xs4all.nl
Thu, 15 Aug 2002 14:13:20 +0200


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

> I just try to define a window and later decide to make it visible:
> Here are the two programs, I can understand the error message generated by
> the first but not the one generated by the second
> What am I missing?

Your problem has to do with the different scopes of names. Basically, there 
are three kinds of scopes.
- - Local scope. These names are defined within a method/function and no longer 
exists when the method/function returns.
- - Instance scope. These names are bound to an instance of an object. Within an 
object they are usually accessed using the 'self.xxx' convention. 
- - Global scope. These names are bound within a module. 

(Note: this distinction is not completely exact, but it's correct enough to 
answer your question)

> from wxPython.wx import *
>
> class MyApp(wxApp):
>     def OnInit(self):
>         frame = wxFrame(NULL, -1, "hello from wxPy")
>         #frame.Show(true)
>         self.SetTopWindow(frame)
>         return true
>
> app = MyApp(0)
> app.frame.Show(true)
> app.MainLoop()
>
> attribute error: MyApp instance has no attribute 'frame'

What happens here is that within the OnInit method, you create a new name 
'frame'. This name is defined within the method and therefore automatically 
gets a local scope. So when OnInit returns, 'frame' is no longer defined.

At the end of your program, you try to extract 'frame' from 'app' by calling 
'app.frame'. You can probably see that this won't work; Python sees this as 
well and raises an AttributeError.

This problem can be solved by changing the first line of OnInit to:
	self.frame = wxFrame(NULL, -1, "hello world")

By prefixing with self, the name 'frame' is bound to the MyApp instance.

> __________________________________________________
>
> from wxPython.wx import *
>
> class MyApp(wxApp):
>     def OnInit(self):
>         frame = wxFrame(NULL, -1, "hello from wxPy")
>         #frame.Show(true)
>         self.SetTopWindow(frame)
>         return true
>
> app = MyApp(0)
> frame.Show(true)
> app.MainLoop()
>
> name error name "frame" is not defined

Here the method is identical, but at the end of the program, you try to access 
frame as if it were in the global scope. 

If you're from a C++ or Java background: in Python there is no implicit 
'this'. Instead, you have to use it explicitly -- that's why you always have 
the 'self' parameter in methods.

Hope this helps; if not, feel free to ask more.

YDD
- -- 
http://www.xs4all.nl/~yduppen
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.7 (GNU/Linux)

iD8DBQE9W5rgLsKMuCf5EdwRAqTXAJ9NJt9thfv9jjCG+ByaadVMn+/I4QCeNNya
VjxlUiSQxAr5ZnJfep/gFuc=
=743L
-----END PGP SIGNATURE-----