scopes of local and global variable

James Stroud jstroud at mbi.ucla.edu
Fri Dec 22 20:02:45 EST 2006


Pyenos wrote:
> Fredrik Lundh <fredrik at pythonware.com> writes:
> 
> 
>>Pyenos wrote:
>>
>>
>>>#############################CODE##############################
>>>t_len=0
>>>class WORK:
>>>    def getwork(self):
>>>        def formattable(table_to_process,type):
>>>TYPE=["p","t","T","s","i"] #list of types to format
>>>            if type==TYPE[1]:
>>>                def format_t():
>>>                    row=[]
>>>                    for col in table_to_process:
>>>                        #######################
>>>                        # ERROR PRONE PART    #
>>>                        #######################
>>>                        if len(str(col))>t_len:
>>>                            t_len=len(str(col))
>>>                        #######################
>>># Error message says:                                                   #
>>># UnboundLocalError: local variable 't_len' referenced before assignment#
>>>                        row+=col
>>>                        if (table_to_process.index(col)+1)%7==0:
>>>                            t_temp.append(row)
>>>                            row=[]
>>>                format_t()
>>>#################################################################
>>
>>wow.
>>
>>
>>>Interpreter says that t_len is local variable although i have
>>>specified t_len=0 in line 1. Also, although i've stated t_len=0 in
>>>line 1, it says that t_len is referenced before assignment.
>>
>>each function introduces a new scope.
>>
>></f>
> 
> 
> does class WORK inherit t_len=0 from line1?
> 
> does def getwork() inherit t_len=0 from line1?
> 
> does def formattable(table_to_process,type) inherit t_len=0 from line1?
> 
> does def format_t() inherit t_len=0 from line1?
> 
> thanks.
> 

Yes and no, depending.

The rule of thumb I use is that if you assign in a function, the name is 
not taken from the enclosing  scope. For example, compare:

# example 1
def doit():
   t_len = 42
   def nested():
     print t_len
   nested()

doit()  # will print 42


# example 2
def doit():
   t_len = 42
   def nested():
     if t_len > 0:
       print t_len
     else:
       t_len = 1
   nested()

doit()  # will get "referenced before assignment" error


You could make use of your WORK class here, depending on whether t_len 
makes sense as a member of the WORK class:


class WORK:
     t_len = 0
     def getwork(self):
         def formattable(table_to_process,type):
           # etc., etc.
                  WORK.t_len = len(str(col))

James
-- 
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/



More information about the Python-list mailing list