FAQ
Hi list,

I've just been writing a small script to parse some xml files and output tab
separated values into a separate file.

I was surprised to see that my function "processXML(fpart)" was failing with
an error along the lines of "processXML not defined"

I looked over my code (all 41 lines!) and couldn't find anything, then on a
hunch i moved the def statement _above_ the rest of my code and hey presto
it worked.

I vaguely understand why this is happening, but can someone explain it to
me.

If this makes no sense then tell me that too :-)

cheers,

nibudh.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.python.org/pipermail/tutor/attachments/20070725/5fd770cd/attachment.htm

Search Discussions

  • Alan Gauld at Jul 25, 2007 at 8:37 am
    "nibudh" <nibudh at gmail.com> wrote
    I looked over my code (all 41 lines!) and couldn't find anything,
    then on a
    hunch i moved the def statement _above_ the rest of my code and hey
    presto
    it worked.

    I vaguely understand why this is happening, but can someone explain
    it to
    me.
    Its pretty simple.
    Python processes the file top to bottom. If it comes upon
    a name that it doesn't recofgnise it generates an error.
    Thus:


    #############

    print foo(42)

    def foo(x):
    return x * 2

    ##############

    will generate an error because at the point where the print
    statement tries to execute foo(42), foo does not exist!

    This is one good reason to avoid putting executable code in the
    main body of a file but to always wrap it in a function like so:

    ##############

    def main()
    print foo(42)

    def foo(x):
    return x * 2

    if __name__ == "__main__": main()

    ###############

    Now the code doesn't get executed until the last line of the file
    by which time all definitions have been executed and the
    program will work correctly.

    This also makes the module inherently more reusable since it
    can be imported without the main code being executed (the purpose
    of the if expression.)

    HTH,

    --
    Alan Gauld
    Author of the Learn to Program web site
    http://www.freenetpages.co.uk/hp/alan.gauld
  • Kent Johnson at Jul 25, 2007 at 11:27 am

    Alan Gauld wrote:
    "nibudh" <nibudh at gmail.com> wrote
    I looked over my code (all 41 lines!) and couldn't find anything,
    then on a
    hunch i moved the def statement _above_ the rest of my code and hey
    presto
    it worked.

    I vaguely understand why this is happening, but can someone explain
    it to
    me.
    Its pretty simple.
    Python processes the file top to bottom. If it comes upon
    a name that it doesn't recofgnise it generates an error.
    A key concept to understand is that def (and class and import) are
    executable statements that have no effect until they are actually
    executed. The effect of executing a def is to create a function object
    and bind it to the name given in the def. Before the def is executed,
    the name is not bound to anything and can't be used.

    This is a shift from less-dynamic languages such as Java and C, where
    functions exist from the time a module is loaded.

    One consequence of executable def is that you can, for example, have
    conditional defs:
    if has_foo:
    def bar():
    # Implementation of bar using foo
    else:
    def bar():
    # Implementation of bar without using foo

    Similar techniques can be used with imports. This can be handy for
    writing code that is backwards compatible. For example here is some code
    that tries to import ElementTree from its Python 2.5 library package and
    from the effbot distribution:

    try:
    import xml.etree.ElementTree as ET # in python >=2.5
    except ImportError:
    try:
    import elementtree.ElementTree as ET # effbot's pure Python module
    except ImportError:
    raise ImportError("Can't import ElementTree")

    If this code successfully executes, the ElementTree module will be
    available as ET.

    Kent
  • Nibudh at Jul 25, 2007 at 2:05 pm
    Hi Kent and Alan,

    Thanks for the responses. It really got me thinking!

    To test what i thought i knew, i wrote a "hello world" script in perl and
    python.

    in perl this works:

    #!/usr/bin/env perl
    hello("World");

    sub hello {
    print "Hello ". $_[0] . "\n";
    }

    but in python:

    #!/usr/bin/env python
    hello('World')

    def hello(name):
    print "Hello" + name

    That doesn't.

    I have a vague recollection that ASP works in a similar way to python hence
    the "hunch" i had earlier but i could be wrong. It's been a while since i've
    done programming.

    I can see how the property of being executable (defs and imports) could be
    handy, but right now I'm still getting to grips with the language proper.

    Thanks again for the explanations and I'll keep them in mind as i experiment
    some more with python.

    nibudh.
    -------------- next part --------------
    An HTML attachment was scrubbed...
    URL: http://mail.python.org/pipermail/tutor/attachments/20070726/d5135979/attachment.htm
  • Alan Gauld at Jul 25, 2007 at 2:49 pm
    "nibudh" <nibudh at gmail.com> wrote
    in perl this works:

    #!/usr/bin/env perl
    hello("World");

    sub hello {
    print "Hello ". $_[0] . "\n";
    }

    Perl executes differently to Python in that it does a compilation
    stage
    before executing. Therefore Perl knows about all the function
    definitions
    prior to executing any code. Python compiles modules which it imports
    but not scripts which it executes.
    I have a vague recollection that ASP works in a similar way to
    python hence
    the "hunch" i had earlier but i could be wrong. It's been a while
    since i've
    done programming.
    Most interpreted languages work this way.
    Even the original versions of C worked that way although I thiunk more
    recent (ANSI/ISO compliant?) versions no longer need the strict
    ordering,
    and Pascal also does it that way even though they are pure compiled
    languages. In the case of Pascal it is because Pascal is designed to
    be a single pass comilation language - which is why Borland's Object
    Pascal comiles so quickly in Delphi!

    --
    Alan Gauld
    Author of the Learn to Program web site
    http://www.freenetpages.co.uk/hp/alan.gauld
  • Kent Johnson at Jul 25, 2007 at 3:59 pm

    Alan Gauld wrote:
    "nibudh" <nibudh at gmail.com> wrote
    in perl this works:

    #!/usr/bin/env perl
    hello("World");

    sub hello {
    print "Hello ". $_[0] . "\n";
    }

    Perl executes differently to Python in that it does a compilation
    stage
    before executing. Therefore Perl knows about all the function
    definitions
    prior to executing any code. Python compiles modules which it imports
    but not scripts which it executes.
    Python compiles all scripts to bytecode. For imported modules it saves
    the compiled bytecode in a .pyc file, but not for directly-executed
    scripts. However this has no bearing on the current thread; for both
    imported modules and executed scripts, a function must be defined before
    it can be called.

    Kent
  • Alan Gauld at Jul 25, 2007 at 5:21 pm
    "Kent Johnson" <kent37 at tds.net> wrote
    Perl executes differently to Python in that it does a compilation
    stage before executing. Therefore Perl knows about all the function
    definitions prior to executing any code. Python compiles modules
    which it imports
    but not scripts which it executes.
    Python compiles all scripts to bytecode.
    Doh! Yes of course it does, stoopid me.
    scripts. However this has no bearing on the current thread; for both
    imported modules and executed scripts, a function must be defined
    before
    it can be called.
    Yes, the bearing is in the way that Perl compiles its code.
    Perl builds a name tree from the entire file before executing
    so it doesn't rely on the order of definition, Python seems
    to compile and execute code in a sequential manner and
    therefore relies on the sequence being right.

    I'm not sure if the undefined name errors come from the compilation
    or from the execution - does anyone else. I confess i've never looked
    deeply into how Python actually does its complile/execute cycle.

    Alan G.
  • Kent Johnson at Jul 25, 2007 at 6:14 pm

    Alan Gauld wrote:
    "Kent Johnson" <kent37 at tds.net> wrote
    scripts. However this has no bearing on the current thread; for both
    imported modules and executed scripts, a function must be defined
    before
    it can be called.
    Yes, the bearing is in the way that Perl compiles its code.
    Perl builds a name tree from the entire file before executing
    so it doesn't rely on the order of definition, Python seems
    to compile and execute code in a sequential manner and
    therefore relies on the sequence being right.
    It executes code in a sequential manner, and names are bound during
    execution, not compilation. That is the key difference. I guess you
    could say that the compiler doesn't forward any names to the execution
    phase; when a module starts executing, the only names in the module
    namespace are
    ['__builtins__', '__doc__', '__file__', '__name__']

    You can see this if you import a module whose contents are just
    print dir()

    Any other names must be bound by executing code.
    I'm not sure if the undefined name errors come from the compilation
    or from the execution - does anyone else. I confess i've never looked
    deeply into how Python actually does its complile/execute cycle.
    They come from execution. See my separate post about def, etc. being
    executable statements.

    Kent
  • Bob Gailer at Jul 25, 2007 at 6:35 pm

    Alan Gauld wrote:
    "Kent Johnson" <kent37 at tds.net> wrote

    Perl executes differently to Python in that it does a compilation
    stage before executing. Therefore Perl knows about all the function
    definitions prior to executing any code. Python compiles modules
    which it imports
    but not scripts which it executes.
    Python compiles all scripts to bytecode.
    Doh! Yes of course it does, stoopid me.

    scripts. However this has no bearing on the current thread; for both
    imported modules and executed scripts, a function must be defined
    before
    it can be called.
    Yes, the bearing is in the way that Perl compiles its code.
    Perl builds a name tree from the entire file before executing
    so it doesn't rely on the order of definition, Python seems
    to compile and execute code in a sequential manner and
    therefore relies on the sequence being right.

    I'm not sure if the undefined name errors come from the compilation
    or from the execution - does anyone else. I confess i've never looked
    deeply into how Python actually does its complile/execute cycle.
    Compiling to bytecode raises syntax, deprecation and indentation errors.
    All others AKAIK are raised during execution
    Alan G.


    _______________________________________________
    Tutor maillist - Tutor at python.org
    http://mail.python.org/mailman/listinfo/tutor

    --
    Bob Gailer
    510-978-4454 Oakland, CA
    919-636-4239 Chapel Hill, NC
  • Dave Kuhlman at Jul 25, 2007 at 6:35 pm

    On Wed, Jul 25, 2007 at 06:21:08PM +0100, Alan Gauld wrote:
    I'm not sure if the undefined name errors come from the compilation
    or from the execution - does anyone else. I confess i've never looked
    deeply into how Python actually does its complile/execute cycle.
    A couple of points that might help:

    1. In python it's all execution. Yes, Kent is right that Python is
    compiled to byte code. But, Alan is right to ignore that in
    trying to understand what happens. In particular, "class" and
    "def" statements execute, and when they do they bind a name to a
    class or function object in the local namespace.

    2. It's all about look-up. Every variable reference causes Python
    to do a look-up in the current namespace (and enclosing
    namespaces, which is another subject). So, you need to ask
    whether at that time a given name has been created in the
    current namespace.

    Some examples ...

    The following works because func2 is not called (looked up) until
    func1 is executed, which is after func2 is defined:

    # Test 1

    def func1():
    func2()

    def func2():
    print 'hello'

    func1()

    The following does *not* work, because func1 executes *before*
    func2 is defined, which means that func2 is needed before it is
    defined:

    # Test 2

    def func1():
    func2()

    func1()

    def func2():
    print 'hello'

    And, (admittedly a rare case), the following does *not* work
    because when the statement "class A(B)" executes, B is not yet
    defined and is needed. This is an example of a name (B) being
    needed when another object (A) is defined (when the "class A(B)" is
    executed):

    # Test 3

    class A(B):
    pass

    class B(object):
    pass

    By the way, this is an important and fundamental subject about
    Python. When I teach classes on Python, I always need to explain
    Python's execution model, and I always struggle with it. So,
    anything you can tell me that would help me teach this will be much
    appreciated.

    Dave
  • Tonu Mikk at Jul 25, 2007 at 8:48 pm
    Hello, I am at a very beginning on trying to learn Python. So far I
    have read first few chapters of Alan Gauld tutorials, and completed all
    the exercises of Guido van Robot (http://gvr.sourceforge.net/). I also
    began reading and coding the Livewires course exercises
    (http://www.livewires.org.uk/python/). I have gotten through the first
    4 exercise, but got stuck with the last one where we build a robot
    game. The Livewires coding exercise uses modules that can be downloaded
    from their website. Would anyone be willing to install Livewires
    modules on their computer and assist me with the coding? I have
    specific questions, but the code could be difficult to read because it
    takes advantage of the imported modules.

    Thank you,
    Tonu
  • Kent Johnson at Jul 25, 2007 at 9:21 pm

    Tonu Mikk wrote:
    I also
    began reading and coding the Livewires course exercises
    (http://www.livewires.org.uk/python/). I have gotten through the first
    4 exercise, but got stuck with the last one where we build a robot
    game. The Livewires coding exercise uses modules that can be downloaded
    from their website. Would anyone be willing to install Livewires
    modules on their computer and assist me with the coding? I have
    specific questions, but the code could be difficult to read because it
    takes advantage of the imported modules.
    Go ahead and post your questions. I have tried LiveWires (long ago!) and
    there may be others on the list.

    Kent
  • Luke Paireepinart at Jul 25, 2007 at 11:10 pm

    Kent Johnson wrote:
    Tonu Mikk wrote:
    I also
    began reading and coding the Livewires course exercises
    (http://www.livewires.org.uk/python/). I have gotten through the first
    4 exercise, but got stuck with the last one where we build a robot
    game. The Livewires coding exercise uses modules that can be downloaded
    from their website. Would anyone be willing to install Livewires
    modules on their computer and assist me with the coding? I have
    specific questions, but the code could be difficult to read because it
    takes advantage of the imported modules.
    Go ahead and post your questions. I have tried LiveWires (long ago!) and
    there may be others on the list.
    Yes, but please next time you start a thread don't do it as a reply to
    another thread.
    My e-mail client threw your e-mail in with the 'function declaration
    problems' thread,
    which, if I had decided I didn't need to watch that thread anymore,
    would've resulted in your question getting overlooked.
    So overall your questions get less exposure that way, as well as
    breaking the threading of some mail clients.

    Let us know what specific questions you have.
    -Luke
  • Tiger12506 at Jul 25, 2007 at 10:33 pm

    By the way, this is an important and fundamental subject about
    Python. When I teach classes on Python, I always need to explain
    Python's execution model, and I always struggle with it. So,
    anything you can tell me that would help me teach this will be much
    appreciated.

    Dave
    The way I keep it clear is simple. If python needs the value of the name (it
    has to look it up) then it had better be defined. Otherwise ~ It doesn't
    matter!

    Think of it like assignment.
    x = 1

    Does python need to know the current value of x? No. Then x does not have to
    be previously defined.

    f()

    Does python need to know the current value of f? Yes. It has to know that f
    is a function, and where the address is, etc.

    def f1():
    f()

    Does python need to know the current value of f? No. Not until f1 is
    executed.

    Does this help? Only one rule to remember. ;-) ~Does python need to know the
    value of _this_ variable?~

    JS
  • Bob Gailer at Jul 25, 2007 at 4:19 pm

    Alan Gauld wrote:
    "nibudh" <nibudh at gmail.com> wrote

    in perl this works:

    #!/usr/bin/env perl
    hello("World");

    sub hello {
    print "Hello ". $_[0] . "\n";
    }

    Perl executes differently to Python in that it does a compilation
    stage
    before executing. Therefore Perl knows about all the function
    definitions
    prior to executing any code. Python compiles modules which it imports
    but not scripts which it executes.
    Not exactly. When Python imports a module that is new* it "compiles" it
    into bytecode. No recognition of names or objects takes place in this
    step. The bytecode is saved in a file with extension .pyc. Then Python
    executes the bytecode. Any function definitions that get executed create
    function objects that are available to subsequently executed code.

    Running a script does exactly the same thing, except the bytecode is not
    saved in a file.

    The bottom line is: a function definition must be executed before the
    function can be used. This is true of ANY Python object.

    *new means that no .pyc file exists or the modification time of the .py
    is more recent than that of the .pyc.
    I have a vague recollection that ASP works in a similar way to
    python hence
    the "hunch" i had earlier but i could be wrong. It's been a while
    since i've
    done programming.
    Most interpreted languages work this way.
    Even the original versions of C worked that way although I thiunk more
    recent (ANSI/ISO compliant?) versions no longer need the strict
    ordering,
    and Pascal also does it that way even though they are pure compiled
    languages. In the case of Pascal it is because Pascal is designed to
    be a single pass comilation language - which is why Borland's Object
    Pascal comiles so quickly in Delphi!

    --
    Bob Gailer
    510-978-4454 Oakland, CA
    919-636-4239 Chapel Hill, NC

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouptutor @
categoriespython
postedJul 25, '07 at 7:27a
activeJul 25, '07 at 11:10p
posts15
users8
websitepython.org

People

Translate

site design / logo © 2022 Grokbase