[Tutor] Syntax Error? Variable Scope?

Kent Johnson kent37 at tds.net
Fri Nov 3 12:08:29 CET 2006


Chuck Coker wrote:
> Hi Folks,
> 
> I am new to Python, but I have many years experience in software
> development. I have a question about variable scope. I'm having a
> problem that I suspect is merely a syntax error or something of that
> nature.
> 
> I'm not real clear on variable scoping rules, either. I can't figure
> out how to declare a variable containing a file pointer outside a
> class and then access the variable from inside a method inside the
> class. I could be creating errors when trying to use the "global"
> keyword due to not fully understanding the scope rules. The examples
> I found so far in books and on the web are to simplistic for what I
> want to do.

Actually you seem to be using 'global' correctly.
> 
> I am using a load-testing app named The Grinder (version 3, beta 30)
> and Python 2.5.

I think you mean Jython.
> 
> I want my script to open an external CSV (comma-separated values) file
> containing x number of records with people's names, addresses, etc. I
> want the file opened outside the TestRunner class (the main class for
> The Grinder) when the script is first started.
> 
> Then I want each instance of the TestRunner class to read one line
> from the external CSV file. After it gets the line from the file, I
> want to split the line at the commas into components and do the
> processing stuff.
> 
> After the last instance of TestRunner finishes, I want the script to
> close the file and exit nicely.
> 
> My reasoning for opening and closing the CSV file outside the class is
> that I want the file to stay open and have the file cursor maintain
> its location after each read. For example, if I am running 2,000
> threads, the file gets opened, whatever thread gets there first reads
> line 1, the next thread that gets there reads line 2, and so on until
> all 2,000 threads have had a chance to get a different line from the
> file. Then I want the file to close.

This is a very strange design. Why do you want to split the processing 
of the file among 2,000 threads? Why not have a single thread that loops 
over the lines of the file and processes them?

To open the file outside the thread, just open it at global scope as 
Dustin suggested. Additionally you could pass the open file to 
__init__() and not rely on it being global.

More comments inline.
> 
> Here are some code snippets:
> 
> ----------------------------------------------------------------------
> from net.grinder.script import Test
> from net.grinder.script.Grinder import grinder
> from net.grinder.plugin.http import HTTPPluginControl, HTTPRequest
> from HTTPClient import NVPair
> connectionDefaults = HTTPPluginControl.getConnectionDefaults()
> httpUtilities = HTTPPluginControl.getHTTPUtilities()
> 
> [... snip ...]
> 
> fileNewUserInfo = 'new-user-info.csv'
> fileNewUserInfoIsOpen = 0
> 
> [... snip ...]
> 
> class TestRunner:
>   """A TestRunner instance is created for each worker thread."""
> 
>   # The instance initialization method.
>   def __init__(self):
>     print 'We are in TestRunner.__init__()'
>     global infile
>     global fileNewUserInfoIsOpen
>     if (fileNewUserInfoIsOpen == 0):
>       infile = open(fileNewUserInfo, "r")
>       fileNewUserInfoIsOpen += 1;
>       print 'We are inside the open if statement'

If you have multiple TestRunners this is a race condition waiting to 
happen. You need a lock on fileNewUserInfoIsOpen to prevent two threads 
from passing the condition and both opening the file. I would use infile 
itself as the flag though, if you really have to do it this way.

>     #global infile
>     self._userTokenCtx = ''
>     self._userTokenRi = ''
>     self._userInfo = []
> 
>     for line in infile.readlines():
>       self._userInfo.append(string.split((line),','))
>       print line

This processes the entire file at once, it is not processing a single 
line as you described.
> 
>     print self._userInfo
> 
>   def nextMethod(self):
> 
> [... snip ...]
> ----------------------------------------------------------------------
> 
> The script blows up at this line inside the for loop:
> 
>       self._userInfo.append(string.split((line),','))
> 
> with this error message in my error log:
> 
> 11/2/06 7:12:20 PM (thread 0): Aborting thread due to Jython exception
> "NameError: string" whilst creating per-thread test runner object
> 
> NameError: string
>     File "new-user-registration.py", line 356, in __init__
> 
> I've tried using "import string" and it doesn't like that. I'm sure
> I'm missing something very basic here due to my newness with Python.
> Can anyone offer any insights?

import string should work, what error do you get? Though as Dustin 
mentioned, the split() method of line, or the csv module, is 
recommended. He got the spelling wrong, though - you would use 
line.split(',').

Jython doesn't have a csv module but there are some add-on modules that 
work.

Kent

> 
> Thanks,
> Chuck
> 




More information about the Tutor mailing list