Re: amazing scope?

2012-11-30 Thread Jean-Michel Pichavant
- Original Message -
 I wrote a script, refactored it and then introducing a bug as below:
 
 def record_things():
 out.write(Hello world)
 
 if __name__ == '__main__':
 with open('output', 'w') as out:
 record_things()
 
 
 but the shocking thing is that it didn't actually stopped working, it
 still works perfectly!
 
 What my explanation might be is that the out is declared at module
 level somehow,
 but that's not really intuitive and looks wrong, and works both on
 Python 2.7 and 3.2..
 --
 http://mail.python.org/mailman/listinfo/python-list
 

From what I understand from the with documentation 
http://docs.python.org/2/reference/compound_stmts.html#with

The with block has nothing to do with scopes. It does not define the target 
within that block, well, actually it does but it defines it for the current 
scope.
The with block only identifies where to call __enter__ and __exit__.

So I would say that with open('output', 'w') as out assignes out at the 
module level.

You may have been mislead by some other languages where a with block purpose is 
to limit the scope of a variable.

JM



-- IMPORTANT NOTICE: 

The contents of this email and any attachments are confidential and may also be 
privileged. If you are not the intended recipient, please notify the sender 
immediately and do not disclose the contents to any other person, use it for 
any purpose, or store or copy the information in any medium. Thank you.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: amazing scope?

2012-11-30 Thread Jean-Michel Pichavant


- Original Message -
 2012/11/30 andrea crotti andrea.crott...@gmail.com:
 
 Already changing it to:
 
 def record_things():
 out.write(Hello world)
 
 def main():
 with open('output', 'w') as out:
 record_things()
 
 if __name__ == '__main__':
 main()
 
 makes it stops working as expected, so it's really just a corner case
 of using the if __name__ == '__main__'
 which I had never encountered before..

You do realize that 

foo = 5 # define at the module level

if __name__ == '__main__':
bar = 6 # also at the module level

if True:
ham = 8 # still at the module level

def func()
# scope has changed, only at the func level
jam = 9

Nothing magic about if __name__ == '__main__'

Cheers,

JM


-- IMPORTANT NOTICE: 

The contents of this email and any attachments are confidential and may also be 
privileged. If you are not the intended recipient, please notify the sender 
immediately and do not disclose the contents to any other person, use it for 
any purpose, or store or copy the information in any medium. Thank you.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: amazing scope?

2012-11-30 Thread Ulrich Eckhardt

Am 30.11.2012 12:11, schrieb andrea crotti:

I wrote a script, refactored it and then introducing a bug as below:

def record_things():
 out.write(Hello world)


This is a function. Since out is not a local variable, it is looked up 
in the surrounding namespace at the time the function is called.




if __name__ == '__main__':
 with open('output', 'w') as out:
 record_things()


This is not in a function, so binding variables affects the containing 
namespace. This includes binding the context manager to out. Note that 
you could have moved the whole code into a function (e.g. one called 
main()) and then you would have gotten the expected failure.




What my explanation might be is that the out is declared at module
level somehow, but that's not really intuitive and looks wrong, and
works both on Python 2.7 and 3.2..


Other than in C/C++/Java and others, indention doesn't introduce a new 
scope, but I understand your intuition. Even simpler, this is how my 
early Python code looked like, in the absence of the C ternary operator 
and the distinction between a variable declaration and an assignment:


 foo = None
 if some_condition:
 foo = 'bar'
 else:
 foo = 'baz'

More idiomatic would have been this:

 if some_condition:
 foo = 'bar'
 else:
 foo = 'baz'


Summary: I'd say that everything is fine. ;)

Uli

--
http://mail.python.org/mailman/listinfo/python-list


Re: amazing scope?

2012-11-30 Thread Chris Angelico
On Sat, Dec 1, 2012 at 3:05 AM, andrea crotti andrea.crott...@gmail.com wrote:
 Well I knew that this works fine, even if I feel a bit guilty to do
 this, and better is:

 foo = 'bar' if some_condition else 'baz'

 Anyway for me the suprise is that something that is defined *later* at
 the module scope is found in a function which is defined *earlier*.

It's assigned to earlier. It's no different from C code like this:

int foo;

void blah()
{
/* do stuff with foo */
}

int main()
{
foo = 1;
}


In Python, the int foo; is implicit, but the scope is the same.

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: amazing scope?

2012-11-30 Thread Jean-Michel Pichavant
- Original Message -
 Well I knew that this works fine, even if I feel a bit guilty to do
 this, and better is:
 
 foo = 'bar' if some_condition else 'baz'
 
 Anyway for me the suprise is that something that is defined *later*
 at
 the module scope is found in a function which is defined *earlier*.
 --
 http://mail.python.org/mailman/listinfo/python-list
 

What really matters for function is when they're executed, not defined (except 
for their parameter default value).

foo = 'I am foo'
bar = 'I am bar'

def funcA(param1=foo):
print param1
print bar

foo = 'I am another foo'
bar = 'I am another bar'

def funcB(param1=foo):
print param1
print bar

funcA()
funcB()

   


I am foo
I am another bar
I am another foo
I am another bar


cheers,

JM


-- IMPORTANT NOTICE: 

The contents of this email and any attachments are confidential and may also be 
privileged. If you are not the intended recipient, please notify the sender 
immediately and do not disclose the contents to any other person, use it for 
any purpose, or store or copy the information in any medium. Thank you.
-- 
http://mail.python.org/mailman/listinfo/python-list


RE: amazing scope?

2012-11-30 Thread Prasad, Ramit
andrea crotti
 
 I wrote a script, refactored it and then introducing a bug as below:
 
 def record_things():
 out.write(Hello world)
 
 if __name__ == '__main__':
 with open('output', 'w') as out:
 record_things()
 
 
 but the shocking thing is that it didn't actually stopped working, it
 still works perfectly!
 
 What my explanation might be is that the out is declared at module
 level somehow,
 but that's not really intuitive and looks wrong, and works both on
 Python 2.7 and 3.2..

Makes sense to me. `out` is declared in an if statement. If statements
have no scope and it is not in a function so it gets added to the 
module's namespace.


~Ramit


This email is confidential and subject to important disclaimers and
conditions including on offers for the purchase or sale of
securities, accuracy and completeness of information, viruses,
confidentiality, legal privilege, and legal entity disclaimers,
available at http://www.jpmorgan.com/pages/disclosures/email.  
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: amazing scope?

2012-11-30 Thread Dave Angel
On 11/30/2012 11:05 AM, andrea crotti wrote:
 Well I knew that this works fine, even if I feel a bit guilty to do
 this, and better is:

 foo = 'bar' if some_condition else 'baz'

 Anyway for me the suprise is that something that is defined *later* at
 the module scope is found in a function which is defined *earlier*.

It would have been nice if you had indicated in your original post just
*what* you considered shocking about the code sample.  The code was
valid, and we all had to guess what about it was puzzling you.  Like
most others, I first guessed you were confused about the definition
being in an if statement.  Then I thought you were confused by the with
statement, since it's not as obvious that as binds the name to the
object in the same way as assignment.

But I never would have guessed that you were confused about the order of
execution in a module.

The source code in a module is executed in order, including function
definitions defined at top level.  However, such a function definition's
execution creates a function object, and assigns a global name (usually)
to that object.  It does not execute the object.  When that function
is executed later, it then looks for global variables for stuff that's
not defined within its own scope.  So by the time the function
references the 'out' name, it's been successfully added to the global
namespace.



-- 

DaveA

-- 
http://mail.python.org/mailman/listinfo/python-list