![]() |
|
|
|||||||
![]() |
Python - RE: [path-PEP] Path inherits from basestring again |
|
|
Thread Tools | Search this Thread |
|
|
#1 |
|
> 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 |
|
|
|
|
#2 |
|
Posts: n/a
|
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 |
|
|
|
#3 |
|
Posts: n/a
|
[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 |
|
|
|
#4 |
|
Posts: n/a
|
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 |
|
|
|
#5 |
|
Posts: n/a
|
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 |
|
|
|
#6 |
|
Posts: n/a
|
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 |
|
|
|
#7 |
|
Posts: n/a
|
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 |
|
|
|
#8 |
|
Posts: n/a
|
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 |
|
|
|
#9 |
|
Posts: n/a
|
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 |
|
|
|
#10 |
|
Posts: n/a
|
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 |
|