[FAQTS] Python Knowledge Base Update -- May 31st, 2000

Fiona Czuczman fiona at sitegnome.com
Wed May 31 09:16:09 EDT 2000


Hi!

Below are the entries I've entered into http://python.faqts.com tonight.

Request: As a newbie to Python I'm not confident that I am arranging the 
content into FAQTs as well as I could.  If anyone could suggest a more 
appropriate folder structure or jump into FAQTs and help create it (or 
move questions into more appropriate folders) I'd be eternally grateful 
:-)

Cheers, Fiona Czuczman


## New Entries #################################################


-------------------------------------------------------------
Why are there no operators equivalent to C's ++, --, +=, etc.?
http://www.faqts.com/knowledge-base/view.phtml/aid/3378
-------------------------------------------------------------
Fiona Czuczman
Fredrik Lundh, Peter Schneider-Kamp, Michael Hudson

if you write things like "var = var + 1" a lot, you might be missing 
some important python idioms...

here are a few, in no specific order:

    for item in sequence:
        ...

    sequence = map(operation, sequence)

    sequence.append(item)

    for index in range(size):
        ...

    for item1, item2 in map(None, sequence1, sequence):
        ...

    for index in range(start, stop, step):
        ...

    n = sequence.count(item)

    for index in range(len(sequence)):
        ...

    sequence.remove(item)

    for index in range(len(sequence)-1, -1, -1):
        ...

(also note that most basic types are *immutable*, so it's not entirely 
clear how things like ++ and += should work.

Michael Hudson wrote a patch for the +=, -=, *=, /= and some other
of these operators.

A patch can be found at:

http://starship.python.net/crew/mwh/aug-patch.html
http://www-jcsu.jesus.cam.ac.uk/~mwh21/aug-patch.html


-------------------------------------------------------------
How come the global declaration works when I define it from within the interpreter, but not from within a file that I import?
http://www.faqts.com/knowledge-base/view.phtml/aid/3381
-------------------------------------------------------------
Fiona Czuczman
Curtis Jensen, Emile van Sebille, David Goodger

Example:

file: foo_bar.py:
def foo(i):
  x = i

def bar(i):
  global y
  y = i

Python interpreter:
>>> from foo_bar import *
>>> bar(0)
>>> print y
Traceback (innermost last):
  File "<stdin>", line 1, in ?
NameError: y
>>> def other(i):
...   global z
...   z = i
...
>>> other(5)
>>> print z
5
>>> ^D

Solution:

Your 'y' variable exists at the module level in foo_bar.

See section 4.1 in the Python Refernce Manual the explains namespaces.

Also, from import * can be dangerous as it replaces references in the
current namespace.  

>>> bar(3)
>>> foo_bar.y
3
>>> 

----------

Because global means "global at the module level". There is no sharing 
of globals between modules (if there were, what chaos that would 
create!). When you're working in the interactive interpreter, you are 
actually in the "__main__" module's namespace. When you import a module 
(regardless of whether you use "import x" or "from x import *"; the 
latter just copies all of x's names into the current namespace), you 
create a new namespace for that module. Any global variables created by 
that module are global within that module's namespace. For example, 
assume file mytest.py contains:

    def spam(i):
        global x
        x = i

So "x" will be global in mytest's namespace, rather than just local to 
the spam() function.

Now let's test it:

    >>> from mytest import *
    >>> spam(5)
    >>> x
    Traceback (innermost last):
      File "<input>", line 1, in ?
    NameError: x

This is as you saw. Now, let's "import sys". "sys.modules" is a 
dictionary contining all imported modules, indexed by name:

    >>> import sys
    >>> sys.modules["mytest"]
    <module 'mytest' ...>
    >>> sys.modules["mytest"].x
    5

So x *was* changed, in mytest's global namespace, but not __main__'s.

When you define a function in the interpreter:

    >>> def eggs(i):
    ...     global z
    ...     z = i
    >>> eggs(5)
    >>> z
    5

The function "eggs()" is defined in the "__main__" module, in __main__'s
namespace, therefore "global z" makes z a global variable in __main__'s
namespace.


-------------------------------------------------------------
Walking recursivly through a directory-structure, I've been looking at os.path.walk for this, but I'm not sure how to implement it.
http://www.faqts.com/knowledge-base/view.phtml/aid/3380
-------------------------------------------------------------
Fiona Czuczman
bragib, François Pinard, Alex

You are on the right track... Just use os.path.walk(path, visit, arg)
You should write the visit function yourself.  Calls the function visit
with arguments (arg, dirname, names) for each directory in the directory
tree rooted at path (including path itself, if it is a directory).

So for instance if you would had a directory tree like this
/home/bragi/tmp2/
    /home/bragi/tmp2/file1.dat
    /home/bragi/tmp2/file2.dat
    /home/bragi/tmp2/file3.dat
      /home/brag/tmp2/dir2/file1.dat
      /home/bragi/tmp2/dir2/file2.dat

and you want to make a dictionary keyed by the directory name and the
dictionary values being the files in that dictionary.

import os, posixpath
dirContents = {}
def visit(arg, dirname, names):
    files = []
    for name in names:
        if os.path.isfile(name): # keep if file
            files.append(name)
    dirContents[dirname] = files
arg1 = 'Hello'
arg2 = 'World'
os.path.walk('/home/bragi/tmp2', visit, (arg1, arg2))
print dirContents

Your output would be:
{'/home/bragi/tmp2': ['file2.dat', 'file3.dat', 'file1.dat'],
'/home/bragi/tmp2/dir2': ['file2.dat', 'file1.dat']}

------

I'm sure examples abound. Like:

   http://www.iro.umontreal.ca/contrib/recode/lib/distroweb.py

Just look for occurrences of the `walk' or `walker' strings.

------

I wanted to learn to use os.path.walk, too, so I wrote a little function
that takes a directory and makes a graph out of all the files and
sub-directories below it:

import os

class Directory:

    def __init__ (self, path):
        self.path = path
        self.directory = {self.path: {}}
        self.directory_pointers = {self.path: self.directory[self.path]}
        os.path.walk (self.path, self.walk_callback, None)

    def walk_callback (self, args, directory, files):
        directory_list = self.directory_pointers[directory]
        self.directory_pointers[directory] = directory_list
        for file in files:
            file = os.path.join (directory, file)
            directory_list[file] = {}
            if os.path.isdir (file):
                self.directory_pointers[file] = directory_list[file]
                
if __name__ == '__main__':
    t = Directory ('/afs/athena.mit.edu/user/a/l/alex_c/mail')
    import pprint
    pprint.pprint (t.directory)







More information about the Python-list mailing list