Need some advice

Francis Avila francisgavila at yahoo.com
Sun Nov 30 07:57:45 CET 2003


Jeff Wagner wrote in message ...
>Bruno, you asked "import the dictionary from a function" ???? Yes, this is
what I tried that isn't
>working:


Hmm...

>def chaldeanValues():
>
>    dateValues = {

...
>        }
>    return dateValues


Ok.  This is roundabout, but you can do it.  (Better simply to put
dateValues in the module's global namespace, and get it by
<modulename>.dateValues directly.)

It's the following I don't get:

>    numberValues = {

...
>        }
>    return numberValues


That's all dead code (i.e., will never, ever be reached by the flow of
execution.)  Once you return once from a function, that's it...

>chaldeanValues()

So all the above line will ever return is dateValues.


I never did much VB, but it either completely destroyed your mind, or you're
approaching Python with the false assumption that it is far more magical and
different than what you're used to. (It *is* magical and different, but it
hasn't redefined the meaning of "function"...)

Don't worry about modules for now; just stick to the basics.




>I have another function called "def nameRoutine():" which calculates the
numerical equivalent of
>each letter in a name and I was going to import that function like this ...
>
>def nameRoutine():
>    from chaldeanValues import dateValues



Ah! Now I understand your confusion.

I just told you not to worry about modules, but I'll break my own advice,
since I see that this misconception is easy to fix.

[There's a little bit of hand-waving in the following, but nothing you'll
need to worry about.]

The "import" statement only imports modules.  Modules are a special type of
object, which containes *names.*  (It is not unique in that respect--every
object in Python contains names.  What's special about modules is that their
code comes from separate files.)  Module objects contain every name defined
in the global space of that module's file.

For example, I write a file, 'MyModule.py':

--- MyModule.py ---
myInt = 1024

def myfunc():
    notglobal = 4021
    return notglobal
--- End ---

I fire up Python:

>>> import MyModule

Now I can access any name in MyModule.  Well, not *anything*:

>>> MyModule.myInt
1024
>>> MyModule.myfunc()
4021
>>> MyModule.myfunc.notglobal
Traceback...
...
AttributeError: function 'myfunc' has no attribute 'notglobal'...

It is this very property of containing names that makes modules handy,
because they act as new global *namespaces*.

A namespace is a collection of names.  There are two kinds: local (which are
used inside of blocks of code, like functions) and global (which are
outside).  When Python encounters a name, it looks for its value in the
namespace.  First it looks in the local namespace (i.e., above that point in
the code, but inside the function) and if it can't find it there, it looks
in the global namespace (i.e., outside the function, but not inside any
other function.)

Modules are neat because they have their own global namespace, which is
global *to themselves*, but not *to the one who imports the module*.  So any
namespace that contains the name of the module, can access the contents of
that module.

You make *your* namespace contain the name of a module, by using 'import
<modulename>', which means, "Put the name of this module in my namespace, so
I can get to its namespace."

Sometimes we don't really want everything in a module, but just one or two
things.  In such cases, we use 'from <modulename> import <nameinthatmodule>'
'Import' here still has the meaning of "put in my namespace", but this time
you're extracting a name directly out of the module and placing it in the
current namepace, instead of placing the whole module in the current
namespace.  Think of it as putting a screwdriver on your desk, instead of
the whole toolbox.

(That said, never use 'from x import y', and especially 'from x import *',
which is like throwing the entire contents of your toolbox onto your desk.
These two contribute to "namespace pollution", and generally lead to
confusion and sloppy programming.)

Let's look at your original lines again.

>def nameRoutine():
>    from chaldeanValues import dateValues

What you're doing here is trying to import a local name from a function.  So
you've done two things wrong: you can only use 'from ... import' or 'import'
statements with modules (which is why they're special), and you can't
ever[1] import local names, only global names.  Local names are only
accessable from the inside, not the outside.

You've also committed a style error of using an import statement in a local
namespace.  Generally speaking, you shouldn't do that, but put all your
imports at the top of a file.

Here's what you should do:

--- chaldeanValues.py --
dateValues = {...}
nameValues = {...}
--- END ---

--- Numerology.py ---
import chaldeanValues
#If that hurts your fingers, use:
#
#import chaldeanValues as cV

def nameRoutine():
    # here, if you need dateValues, get it with
    # the name "chaldeanValues.dateValues".
# ...
--- END ---

If you don't have enough to warrant using a new module, use a class instead:

--- Numerology.py ---
class chaldeanValues:
    dateValues = {..}
    nameValues = {..}

def nameRoutine():
    # Get it with "chaldeanValues.dateValues", as above.
--- END ---

Classes are much more than mini-modules, of course, but you can use them
that way if you need.

An even higher-level concept is a package, which is a collection of modules.
You don't need to know about this right now, but for the details see the
very end of 6.12 in the Python Language Reference (also the url cited
there).  Packages are still module objects, however, even though they
contain module names.

-- Footnotes --
[1] Unless you're using dirty tricks.


>and then check the key of say, December, and find out it equals 12 (for the
birthday) and then check
>the key of say, "o" and find out it equals 7. I guess I do need to go back
and learn more about this
>concept.


You seem to understand dictionaries just fine, and you probably understood
modules, too (just needed it spelled out for you), but you're starting to
run into problems with names and namespaces.  These are fundamental, grand,
all-unifying concepts in Python, so it's good to get aquainted with them.

In the future, when you start asking questions like "Why is this default
list argument of my function being shared by everyone?!", we'll give you the
"Names are not objects; names point to objects" lecture. :)
--
Francis Avila







More information about the Python-list mailing list