Python scope is too complicated

Discussion in 'Python' started by Max, Mar 20, 2005.

  1. Max

    Max Guest

    Yeah, I know. It's the price we pay for forsaking variable declarations.
    But for java programmers like me, Py's scoping is too complicated.
    Please explain what constitutes a block/namespace, and how to refer to
    variables outside of it.
     
    Max, Mar 20, 2005
    #1
    1. Advertisements

  2. I presume you read "4.1 Naming and binding" from Python reference manual.

    "What constitutes a block" is answered in paragraph 2, for example. Please come
    back with confusing / missing information in that chapter giving us a chance to
    improve the documentation.

    Cheers!
     
    Christos TZOTZIOY Georgiou, Mar 20, 2005
    #2
    1. Advertisements

  3. Max

    Dan Bishop Guest

    This isn't true anymore, now that generator comprehensions have been
    added to the language.
    17
     
    Dan Bishop, Mar 20, 2005
    #3
  4. Hi All--

    The equivalent in list comprehensions which currently allows the x to
    leak out into its containing scope is going away soon. Will that be
    another scope? Or are generator and list comprehensions only one scope?

    Metta,
    Ivan
    ----------------------------------------------
    Ivan Van Laningham
    God N Locomotive Works
    http://www.andi-holmes.com/
    http://www.foretec.com/python/workshops/1998-11/proceedings.html
    Army Signal Corps: Cu Chi, Class of '70
    Author: Teach Yourself Python in 24 Hours
     
    Ivan Van Laningham, Mar 20, 2005
    #4
  5. Max

    jfj Guest


    Some may disagree, but for me the easiest way to understand python's
    scopes is this:

    """In Python, there are only two scopes. The global and the local.
    The global scope is a dictionary while the local, in the case of a
    function is extremely fast. There are no other scopes. There are
    no scopes in the nested statements inside code blocks and there are
    no class scopes. As a special case, nested function definitions
    appear to be something like a nested scope, but in reallity this is
    detected at compile-time and a strange feature called 'cell variables'
    is used"""

    In order to write to a global variable from a function, we have
    to use:
    global var

    which notifies the compiler that assignment to 'var' does not make
    a new local variable, but it modifies the global one (OT: wouldn't
    "global.var = 3" be nicer?). On the other hand, if we just want to
    read a global variable we don't have to say "global var" because
    the compiler sees that there is no assignment to 'var' in the function
    code and therefore intelligently concludes that it's about a global
    one.

    Generally, python sees everything as
    exec "code" in global_dictionary, local_dictionary

    In this case it uses the opcode LOAD_NAME which looks first in locals
    and then in globals (and actually, then in __builtins__)

    For functions it uses either LOAD_FAST for locals or LOAD_GLOBAL for
    globals.

    HTH

    jfj
     
    jfj, Mar 20, 2005
    #5
  6. Max

    Terry Reedy Guest

    What is type(foo([1,2,3])) ?
    As I understand it, the object 'x' binds to is immediately used to create
    the generator object. The local name is just a dummy that is not part of
    the result. I believe that the above is equivalent to

    def foo(x):
    def _(z):
    for i in z: yield i
    return _(x)

    although I suspect that the implementation builds the generator more
    directly.

    Terry J. Reedy
     
    Terry Reedy, Mar 21, 2005
    #6
  7. Max

    jfj Guest

    Your example with generator expressions is interesting.
    Even more interesting is:

    def foo(x):
    y= (i for i in x)
    return y

    From the disassembly it seems that the generator is a code object but
    'x' is not a cell variable. WTF? How do I disassemble the generator?
    Must look into this....

    [ list comprehensions are different because they expand to inlined
    bytecode ]

    jf
     
    jfj, Mar 21, 2005
    #7
  8. Max

    Greg Ewing Guest

    That's because x is not assigned to anywhere in the
    body of foo. The bytecode compiler optimizes away the
    creation of a cell in this case, just passing the
    value of x as an implicit parameter to the generator.
    You'd have to get hold of the code object for it
    and disassemble that. There should be a reference to
    it in one of the co_consts slots, I think.
     
    Greg Ewing, Mar 22, 2005
    #8
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.