[Tutor] inserting path to open a file from a variable

Felix Dietrich felix.dietrich at sperrhaken.name
Thu May 28 21:01:27 CEST 2015


richard kappler <richkappler at gmail.com> writes:

> Now I've been tasked to change the script so that the script doesn't need
> to be in the same directory as the log file, which makes perfect sense.
> Furthermore, the path can't be hard coded into the script, but rather
> should read the installer should be able to edit a text file to specify the
> paths to the read file (log from which we're extracting data) and the write
> file (file to which we're send the extracted data). I thought this would be
> a trivial exercise, but I'm stuck.

An alternative way to configurate execution parameters is to pass the
filenames as arguments to your program which you can access via
/sys.argv/ (modules to consider: /getopt/, /optparser/):

    import sys
    print sys.argv[0] # the first element is the script's name
    print sys.argv[1] # second element first argument (e.g. rd)
    print sys.argv[2] # third element second argument (e.g. wd)

If you have these lines in a file "argv_test.py" try:

    python argv_test.py read_filename write_filename


Another good alternative for filters is to simply read from stdin and
output the results to stdout; then use the shell to redirect those
from/to the respective files:

    python filter.py <rdfile >wdfile
    # < redirects stdin
    # > redirects stdout
    # or with a pipe and cat
    cat rdfile | python filter.py > wdfile

Within python stdin can be read via sys.stdin:

    import sys
    for l in sys.stdin:
        print l


The /ConfigParser/-Module provides a way to read and write configuration
files.

> # read the config file to get file locations for a script
> conf = open('fileMonitor.conf', 'r')
> read_it = conf.read()
> 
> for line in read_it.splitlines():
>     if line.startswith('rdfile:'):
>         rd = line
>     elif line.startswith('wrtfile:'):
>         wrt = line

Instead of reading all the content of a file into memory one can simply
iterate it and retrieve the contents line my line (I believe this way is
also considered more "pythonic"):

    conf = open('fileMonitor.conf', 'r')
    for line in conf:
        ...

One more "pythonic" thing to do is to wrap the interaction with a file
in a /with/-block: that way file closing is ensured after one is done
with the file:

    with open('fileMonitor.conf', 'r') as conf:
        for line in conf:
            ...


> At the moment, I am, for example, opening the file to be read from with a
> simple
>
>     file = open('log.txt', 'r')
>
> but I need to replace 'log.txt' with rd1 (path and file name to log.txt).
>
> And I'm stumped. rd1 and wrt1 exist, I can print them, and I get what I
> expect (path/filename) for example print rd1 gives
> me Documents/MyScripts/fileMonitor/log.txt
>
> But how in the heck do I get that into the open() statement?
>
> What I've tried (none worked):
>
>     file = open(rd1, 'r')
>     file = open('rd1', 'r')

What do you mean by "none worked"?  Did python respond with an error?
How did you figure that the calls to /open/ failed?

Also: The first line opens a file having the path of the string the
variable /rd1/ currently holds (presumably
"Documents/MyScripts/fileMonitor/log.txt").  The second calls /open/
with the string "rd1" causing /open/ to try and open a file with the
name rd1.

'r' will fail when the file does not exist.

--
Felix Dietrich


More information about the Tutor mailing list