Go Back   Velocity Reviews > Newsgroups > Python
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

Reply

Python - RE: [path-PEP] Path inherits from basestring again

 
Thread Tools Search this Thread
Old 07-29-2005, 03:48 AM   #1
Default RE: [path-PEP] Path inherits from basestring again


> I, herewith, claim to have used it in the past.
>
> But I am indifferent as to if its needed, it just looks natural to me.


So far there seem to have been a few +0s, but no +1s...

> What I use quite often is::
>
> path(__file__).dirname() / "somesiblingfileiknowisthere"
>
> you do not have to think about trailing slashes or absolute vs.
> relative. and its much better than::
>
> from os.path import *
> join(dirname(__file__), "somesiblingfileiknowisthere")


In what way is this "much better"? To me, this is much worse, because it is
not at all clear what it means (a *huge* benefit of using Python is that you
can read the code just like pseudocode). It is immediately clear from the
second example that you are joining two things together. The first one, you
could be joining, or you could be dividing. Compare:

my_directory_string_object / "somesiblingfileiknowisthere"

and

my_directory_path_object / "somesiblingfileiknowisthere"

These look the same, but one will raise a TypeError, and the other will
result in a joined Path. How do I tell which is which when reading source,
without explicitly saying that I'm using a Path object?

> __div__ is actually very convenient to "build" / "a" / "very"
> / "very" / "long" / "path"


Would you really choose this:

p = Path() / "build" / "a" / "very" / "very" / "long" / "path"

Over this:

p = Path(os.path.join("build", "a", "very", "very", "long", "path"))

? A saving of six characters, and the second one is a lot clearer. If
there was a os.path.joinPath (or whatever name) function that returned a
Path object rather than a string, then you'd get:

p = joinPath("build", "a", "very", "very", "long", "path")

Which is better (clearer, more concise) than either of the others, IMO.

=Tony.Meyer



Tony Meyer
  Reply With Quote
Old 07-29-2005, 12:54 PM   #2
Peter Hansen
 
Posts: n/a
Default Re: [path-PEP] Path inherits from basestring again
Tony Meyer wrote:
> Would you really choose this:
> p = Path() / "build" / "a" / "very" / "very" / "long" / "path"
>
> Over this:
> p = Path(os.path.join("build", "a", "very", "very", "long", "path"))


I'd choose neither, because both are contrived examples (who builds
paths out of six literals like that?) and the second one is not
something anyone would want, since it mixes Paths and old-style
os.path.join() calls.

We're talking at this point about how Path should work, not whether it's
preferable to os.path.join, even though that was really the point of
Reinhard's original post. Given that, then, of the following two I
would prefer the first one, slightly:

p = somePath / user.getFolder() / 'archive' / oldPath + '.bak'

p = somePath.joinpath(user.getFolder(), 'archive', oldPath + '.bak')

> ? A saving of six characters, and the second one is a lot clearer.


It's not a question of saving characters, but readability which, as
you've said, is a matter of opinion.

I find the former more readable. Somewhat. Not enough to make a big
deal about it.

I can live with the latter, but as *someone who has used the path module
already* I can only say that you might want to try it for a few months
before condemning the approach using / as being unacceptable.

-Peter


Peter Hansen
  Reply With Quote
Old 07-30-2005, 01:19 AM   #3
NickC
 
Posts: n/a
Default Re: Path inherits from basestring again
[Re: alternatives to overloading '/']

Is there a reason the Path constructor is limited to a single argument?
If it allowed multiple arguments, the following would seem very
straightforward:

p = Path(somePath, user.getFolder(), 'archive', oldPath + ".bak")

I'm usually not much of a purist, but C++ has convinced me that
overloading an operator to mean something entirely unrelated to its
mathematical meaning can be very unwise.

Regards,
Nick C.



NickC
  Reply With Quote
Old 07-30-2005, 04:12 AM   #4
Peter Hansen
 
Posts: n/a
Default Re: Path inherits from basestring again
NickC wrote:
> I'm usually not much of a purist, but C++ has convinced me that
> overloading an operator to mean something entirely unrelated to its
> mathematical meaning can be very unwise.


Me too. In general. I've yet to overload a single operator that way in
years of writing Python code, though I definitely sinned with the rest
of the C++ crowd (in the early days).

In actual usage with path.py, however, I've found the use of "/" to be
quite unsurprising and benign relative to what I had expected. That's
why (to my surprise) I found myself using and appreciating it.

-Peter


Peter Hansen
  Reply With Quote
Old 07-30-2005, 12:55 PM   #5
Reinhold Birkenfeld
 
Posts: n/a
Default Re: Path inherits from basestring again
NickC wrote:
> [Re: alternatives to overloading '/']
>
> Is there a reason the Path constructor is limited to a single argument?
> If it allowed multiple arguments, the following would seem very
> straightforward:
>
> p = Path(somePath, user.getFolder(), 'archive', oldPath + ".bak")


That's a quite good idea. Thanks!

> I'm usually not much of a purist, but C++ has convinced me that
> overloading an operator to mean something entirely unrelated to its
> mathematical meaning can be very unwise.


It's much the same as with @ decorators. Those who have used them much
don't object to the syntax any more.

Reinhold


Reinhold Birkenfeld
  Reply With Quote
Old 07-30-2005, 02:19 PM   #6
phil hunt
 
Posts: n/a
Default Re: [path-PEP] Path inherits from basestring again
On Fri, 29 Jul 2005 14:48:55 +1200, Tony Meyer <t-> wrote:
>
>Would you really choose this:
>
> p = Path() / "build" / "a" / "very" / "very" / "long" / "path"
>
>Over this:
>
> p = Path(os.path.join("build", "a", "very", "very", "long", "path"))


Or have the constructor accept multiple arguments.

>? A saving of six characters, and the second one is a lot clearer. If
>there was a os.path.joinPath (or whatever name) function that returned a
>Path object rather than a string, then you'd get:
>
> p = joinPath("build", "a", "very", "very", "long", "path")


Indeed.

I have a little function I've written called normalizePath(). It
expands users ("~" and "~someuser"), does os.path.join(), then gets
the absolute path (os.path.abspath()) of the result. The code is
trivial:


def normalizePath(p, *pathParts):
""" Normalize a file path, by expanding the user name and getting
the absolute path..
@param p [string] = a path to a file or directory
@param pathParts[list of string] = optional path parts
@return [string] = the same path, normalized
"""
p1 = os.path.abspath(os.path.expanduser(p))
if len(pathParts)>0:
allPathParts = [ p1 ]
allPathParts.extend(pathParts)
p1 = os.path.join(*allPathParts)
p2 = os.path.abspath(p1)
return p2
normalisePath=normalizePath # alternate spelling
join=normalizePath # it works like os.path.join, but better


To be honest I don't see the point of having a Path class. That's
the way Java does it, and I find path handling in Java to be a lot
more of a hassle than in Python. (Actually, most things are more of
a hassle in Java, but that's another story).

--
Email: zen19725 at zen dot co dot uk




phil hunt
  Reply With Quote
Old 07-30-2005, 05:57 PM   #7
Michael Hoffman
 
Posts: n/a
Default Re: Path inherits from basestring again
Reinhold Birkenfeld wrote:

> It's much the same as with @ decorators. Those who have used them much
> don't object to the syntax any more.


I do and I still think they are ugly.
--
Michael Hoffman


Michael Hoffman
  Reply With Quote
Old 07-30-2005, 06:01 PM   #8
Reinhold Birkenfeld
 
Posts: n/a
Default Re: [path-PEP] Path inherits from basestring again
phil hunt wrote:

> def normalizePath(p, *pathParts):
> """ Normalize a file path, by expanding the user name and getting
> the absolute path..
> @param p [string] = a path to a file or directory
> @param pathParts[list of string] = optional path parts
> @return [string] = the same path, normalized
> """
> p1 = os.path.abspath(os.path.expanduser(p))
> if len(pathParts)>0:
> allPathParts = [ p1 ]
> allPathParts.extend(pathParts)
> p1 = os.path.join(*allPathParts)
> p2 = os.path.abspath(p1)
> return p2
> normalisePath=normalizePath # alternate spelling
> join=normalizePath # it works like os.path.join, but better
>
>
> To be honest I don't see the point of having a Path class. That's
> the way Java does it, and I find path handling in Java to be a lot
> more of a hassle than in Python. (Actually, most things are more of
> a hassle in Java, but that's another story).


You see, with the Path class the above function could be written as

def normalizePath(p, *pathParts):
""" Normalize a file path, by expanding the user name and getting
the absolute path..
@param p [Path] = a path to a file or directory
@param pathParts[list of string/Path] = optional path parts
@return [Path] = the same path, normalized
"""
tp = p.expanduser().abspath()
return tp.joinwith(*pathParts).abspath()

That's clearly an improvement, isn't it?

Reinhold


Reinhold Birkenfeld
  Reply With Quote
Old 07-30-2005, 06:13 PM   #9
Reinhold Birkenfeld
 
Posts: n/a
Default Re: Path inherits from basestring again
Michael Hoffman wrote:
> Reinhold Birkenfeld wrote:
>
>> It's much the same as with @ decorators. Those who have used them much
>> don't object to the syntax any more.

>
> I do and I still think they are ugly.


Shouldn't have generalized that. Add "most of" where you like.

Reinhold


Reinhold Birkenfeld
  Reply With Quote
Old 07-31-2005, 05:47 AM   #10
phil hunt
 
Posts: n/a
Default Re: [path-PEP] Path inherits from basestring again
On Sat, 30 Jul 2005 19:01:49 +0200, Reinhold Birkenfeld <reinhold-birkenfeld-> wrote:
>phil hunt wrote:
>
>> def normalizePath(p, *pathParts):
>> """ Normalize a file path, by expanding the user name and getting
>> the absolute path..
>> @param p [string] = a path to a file or directory
>> @param pathParts[list of string] = optional path parts
>> @return [string] = the same path, normalized
>> """
>> p1 = os.path.abspath(os.path.expanduser(p))
>> if len(pathParts)>0:
>> allPathParts = [ p1 ]
>> allPathParts.extend(pathParts)
>> p1 = os.path.join(*allPathParts)
>> p2 = os.path.abspath(p1)
>> return p2
>> normalisePath=normalizePath # alternate spelling
>> join=normalizePath # it works like os.path.join, but better
>>
>>
>> To be honest I don't see the point of having a Path class. That's
>> the way Java does it, and I find path handling in Java to be a lot
>> more of a hassle than in Python. (Actually, most things are more of
>> a hassle in Java, but that's another story).

>
>You see, with the Path class the above function could be written as
>
>def normalizePath(p, *pathParts):
> """ Normalize a file path, by expanding the user name and getting
> the absolute path..
> @param p [Path] = a path to a file or directory
> @param pathParts[list of string/Path] = optional path parts
> @return [Path] = the same path, normalized
> """
> tp = p.expanduser().abspath()
> return tp.joinwith(*pathParts).abspath()
>
>That's clearly an improvement, isn't it?


An improvement to what? To how the class is implemented, or to how
it is used?

If you mean the former, yes is it, due to the os.path module not
providing a function that does this.

If you mean the latter, I disagree, because I would then have to
call it with something like:

pn = normalizePath(Path(p), q)

and then I would have the problem that (pn) isn't a string so
calling a function to write some data into the file at that filename
would no longer work, i.e. this:

writeFile(pn, someData)

would become this:

writeFile(pn.getString(), someData)

I don't see what having a Path type buys me.

--
Email: zen19725 at zen dot co dot uk




phil hunt
  Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off




SEO by vBSEO 3.3.2 ©2009, Crawlability, Inc.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46