Name of the Script

Paul Moore paul.moore at uk.origin-it.com
Fri Mar 9 05:44:43 EST 2001


[The first bit of this posting is related to my logging example, and not too
generally relevant - mainly because I agree withy most of the points David
makes, and concede tghat my example wasn't a particularly good one. But the
last part contains a much better statement of what I'm really after.]

On Fri, 9 Mar 2001 04:12:23 +0100 , David Bolen <db3l at fitlinxx.com> wrote:

>Paul Moore <paul.moore at uk.origin-it.com> writes:
>
>> The obvious, and most user-friendly, way of doing this is using the
>> script name to generate a logfile name. This means looking at
>> sys.argv[0] from within the module.
>
>By "user-friendly" do you mean the user of the script or the
>developer?

I meant the writer of the script which uses the logging module. But some of
your points below make me wonder whether I am right here...

>If you mean the end user of
>the script, I have to admit that I rare place log files where my
>scripts are - scripts are executable code and logs are data, and I
>like to keep those things separate.

Agreed, and that is a good point. But I spend a lot of time managing a wide
range of customer machines, where directory structures and the like vary
wildly. In that situation, having scripts which depend as little as possible
on hard-coded file locations is important. I have found from experience that
locating all files related to a script in directories relative to the script's
location, is a great advantage from a portability point of view.

And no, I don't keep data and code in the same directory (well, not often :-)
- I usually put logs in <script dir>\..\logs or something similar.

>In terms of implementation, I'd probably (and I do) encapsulate my
>logging functionality in a class

If you have a class, then an initialisation argument isn't a great hardship.
Thinking about this, I can see a number of approaches. But the details are
more logging interface design issues, which wasn't really my point. So I'll
just say that I probably agree with you, although we may differ on details.

>> (Which in turn requires sys and os imports which the main script may
>> otherwise not use).
>
>True, but I wouldn't avoid it for that reason - or rather, needing
>standard library modules shouldn't be a negative.

OK, I apologise. That comment was FUD. I shouldn't have made it.

>> This is a real-life case - I had a (VB Script, sorry!) program which
>> did exactly this. And the initialisation step was a definit pain...
>
>Can you clarify the pain part further?  I see this as normal
>initialization that just makes sense and clarity.

Thinking about it, it's probaby not worth explaining further - it's a VB
clumsiness, rather than a general issue.

[...
 comments on the implementation of sys.argv[0] as an absolute path skipped
...]

These are good points, and I agree with most of them.

But my key point remains: There is no 100% reliable way in Python to refer to
a filename which is relative to the location of the main script. The reason
for needing such a file varies (data files, output files, whatever) but that
is a side issue. I suspect that the area of difficulty is that if the (vague)
examples I have of why such a thing might be needed were looked at on a
case-by-case basis, it would be possible to find alternative approaches for
each one in turn. But that's a change in mindset which I haven't achieved yet.

Actually, thinking some more, one way of doing this would be to have the main
script call a module to do all the work. Locate the script and module in the
same directory, and the module can then locate relative filenames via
__file__.

Example:

--- driver.py ---
import app
app.main()

--- app.py ---

def main():
    # whatever

import os
import os.path

def relative(name):
    """Generate a filename relative to the location of this
       module. Absolute filenames are left unchanged, whereas
       relative filenames are interpreted as if the current
       directory was the module's location"""
    if (os.path.isabs(name)): return name
    return os.path.join(os.path.dirname(__file__), name)

--------

Gaah. I tested this and it doesn't work, because __file__ isn't an absolute
pathname!

How _do_ applications locate their data files without hard-coding directory
names, or making assumptions of the current directory? (Actually, that's a
better statement of my issue...)

Paul.




More information about the Python-list mailing list