Importing from a file to use contained variables

Bengt Richter bokr at oz.net
Sat Nov 29 22:04:25 CET 2003


On Sat, 29 Nov 2003 03:39:34 GMT, Jeff Wagner <JWagner at hotmail.com> wrote:

>I am importing a file which contains a persons name (firstName, middleName, etc). If I define a
>function to do this, how can I use the variables outside of that function?
Does the file only contain ONE person's info, or does the pattern of 5 lines repeat for more?
If it's only one person, as you have it here, you can just split on line endings, like

    def getName(): return map(str.lower, file('enterName.txt').read().splitlines())

to return a list of the lower case strings you want, which you can then do
an unpacking assignment with, e.g.,

    fName, mName, lName, nName, pName = getName()

But that's sure a special-purpose routine, being locked into just using the first five lines
of a particular file with a fixed file name.

If you have other possible files of the same format, and possibly with more than one
person's info (i.e., repeating groups of 5 lines), I'd suggest a generator that you
can pass a file name to, and which will return the info in successive lists of 5.

E.g., the following looks like a function, but the 'yield' makes it a generator-maker

====< JeffWagner.py >====================================
def mkgen_GetName(fileOrPath):
    if isinstance(fileOrPath, str):
        fileOrPath = file(fileOrPath) # use open file or open by name
    lineCount = 0
    for line in fileOrPath:
        if lineCount%5==0: nameList = []
        nameList.append(line.strip().lower()) # strips white space incl newline if any
        lineCount += 1
        if lineCount%5==0: yield nameList

def test():
    from StringIO import StringIO
    siofile = StringIO("""\
John
Q
Public
JQ
Johnny
Alice
B
Choklas
Allie
Chok
""")
    for fName, mName, lName, nName, pName in mkgen_GetName(siofile):
        # do whatever with each successive person-info set ...
        print ('%10s'*5)%(fName, mName, lName, nName, pName)

if __name__ == '__main__':
    test()
=========================================================

if you run this, you get:

[13:00] C:\pywk\clp>jeffwagner.py
      john         q    public        jq    johnny
     alice         b   choklas     allie      chok

It also has the advantage that it doesn't put the whole file in memory, just what it needs
as it goes.


>
>Here is the code:
>
>import string
Are you still using 1.5.2? You really ought to upgrade to 2.3.2 ;-)

>
>def getName():
>
>    data = open("enterName.txt")
            ^^^^  ^^^^^^^^^^^^^-- do you really want this as a fixed name in your function?
              |
              +-- deprecated in favor of 'file'
     
>    allNames = data.readlines()
                     ^^^^^^^^^^^-- reads the whole file into memory. Not so good for big files.
>    data.close()
     ^^^^^^^^^^^^ good practice, but not necessary if you are using cPython.
>
>    fName = string.lower(allNames[0])
     fName = allNames[0].lower()       # current way to spell previous line
                                       # (hence importing string is not necessary)

>    mName = string.lower(allNames[1])
>    lName = string.lower(allNames[2])
>    nName = string.lower(allNames[3])
>    pName = string.lower(allNames[4])
>
>I need to use these variables in another function (routine) to calculate the associated numbers.
>Since these are local to the function, how is this done? Can I make them global or something?
'or something' is preferred ;-)

BTW, if you don't want to use a loop to sequence through the data, you can get it one set
at a time from the generator's .next method, e.g.,

 >>> from JeffWagner import mkgen_GetName
 >>> if 1: # so I can copy/paste from the source file
 ...     from StringIO import StringIO
 ...     siofile = StringIO("""\
 ... John
 ... Q
 ... Public
 ... JQ
 ... Johnny
 ... Alice
 ... B
 ... Choklas
 ... Allie
 ... Chok
 ... """)
 ...
 >>> gen = mkgen_GetName(siofile)
 >>> gen.next()
 ['john', 'q', 'public', 'jq', 'johnny']
 >>> a,b,c,d,e = gen.next()
 >>> a,b,c
 ('alice', 'b', 'choklas')
 >>> d,e
 ('allie', 'chok')
 >>> gen.next() # expecting the StopIteration exception here
 Traceback (most recent call last):
  File "<stdin>", line 1, in ?
 StopIteration
 >>> # so you will have to catch that to use .next() cleanly

BTW, what does pName stand for?

Regards,
Bengt Richter




More information about the Python-list mailing list