[Python-au] strange pre-acting bug

PeterL pacqa100 at yahoo.com.au
Wed May 19 00:34:14 UTC 2010


Passing parameters is probably the best way.
You can also resolve the scope using the global keyword.
----
def fn():
     global x
     print x    # Prints 5
     x = 7
     print x    # Prints 7

x = 5
print x    # Prints 5
fn()
print x    # Prints 7
-------------
Some consider global a 'kludge' that leads to poor programming style. 
I'm one of them.

Yes, a function is 'compiled' in it's entirety before it gets used, so 
there is a bit of 'oh this happens later' happening.
Pete

-- 
Peter Lovett
----------------------------------------------------------------------
Plus Plus Pty Ltd
training + consulting + development
C + C++ + C# + Perl + Python + Java + VB/VBA/ASP + SQL + HTML + XML
Unix&  Shell scripting
Microsoft&  Adobe products

http://www.plusplus.com.au/
http://www.pythontraining.com.au/

Everything should be made as simple as possible, but not simpler.
-- Einstein
----------------------------------------------------------------------


On 19/05/2010 10:07 AM, Garry Trethewey wrote:
> Aah thanks.
> Yes. This function is essentially the same as others that get vName, 
> vDate, vSite, etc etc but for them I've just read (but not changed) 
> the variable. So that's the difference.
>
> I assume the answer is to feed in vPage as a parameter, which I've 
> done and it works. Is that the best way?
>
> def fn_get_page_num(vPage):
> <stuff deleted>
>
>   print 'vPage = ', vPage          #vPage read here no prob
>   raw_input('press enter')
>
>   if vPage.isdigit():
>     vPage = str(int(vPage) + 1)     #vPage changed here
>
>   print 'vPage = ', vPage
>   raw_input('press enter')
>
>
> Still leaves the question of why a line affects a previous line. The 
> hint seems to be your
> > "An 'UnboundLocalError' means that you
> > are using a mainline variable inside a function _before you change 
> it_."
>
> Looks like the interpreter does a pre check of the whole function 
> before it actually runs it, finds the fact that the var will change, 
> and then when it runs, hits the first instance of the variable and 
> says wrongly that the problem is there.
>
> Sounds right?
>
> thanks Garry
>
>
>
>
>
>
>
> PeterL wrote:
>> Interesting. This is a common mis-understanding on the scoping rules 
>> of Python functions. I might do a lightning talk on it at PyCon.
>> You need to be clear on the error. An 'UnboundLocalError' means that 
>> you are using a mainline variable inside a function before you change 
>> it.
>>
>> In Python, a function *can* _read_ a mainline's variable with no 
>> problem.
>> If a function goes to change a mainline's variable, then it become 
>> 'bound local', which means you must give it a value before you use it.
>> Hope this helps
>>
>> Compare:
>> -----------
>> # Mainline variable available to a fn
>> def fn():
>>     print x    # Prints 5
>>
>> x = 5
>> fn()
>> ----------
>> # Mainline variables can be localised inside a fn
>> def fn():
>>     x = 7
>>     print x    # Prints 7
>>     # Throw the localised value of x away
>>
>> x = 5
>> print x   # Prints 5
>> fn()
>> print x   # Prints 5
>> ----------
>> # Local bound variables must be set before they're used
>> def fn():
>>     print x    # Error - UnboundLocalError - mainline variables that 
>> are localised must be set before used
>>     x = 7     # Localise x
>>     print x    # Never reaches here
>>
>> x = 5
>> fn()
>> ------------
>>
>>





More information about the python-au mailing list