Seite 1 von 2

join/join?

Verfasst: Donnerstag 16. April 2009, 08:49
von mzh
Hallo zusammen

Wenn ich

Code: Alles auswählen

from os.path import join
join("C:\Arbeit", "Projekte")
schreibe, funktioniert das ausgezeichnet. Es gibt ja aber auch noch eine string-Funktion "join".

Code: Alles auswählen

" ".join([str(i) for i in range(5)]).
Was ist der Mechanismus dahinter, dass in beiden Fällen die richtige Funktion aufgerufen wird? Bzw. ist das immer so?

Verfasst: Donnerstag 16. April 2009, 08:52
von Barabbas
Naja, im Falle des Strings ist join() eine Methode des String-Objektes. Im Falle von os.path.join() ist es eine Methode des path-Objektes, die du über den Import in den Namensraum deines Modules überträgst (ich hoffe, ich habe das jetzt richtig dargestellt).

Auf alle Fälle ist die Zugehörigkeit im Falle der Strings völlig offensichtlich, da du das dazugehörige Objekt ja vorweg angegeben hast.

brb

Verfasst: Donnerstag 16. April 2009, 09:10
von lutz.horn
Du siehst den Unterschied auch, wenn Du die Methoden nicht ausführst sondern lediglich ihre String-Repräsentation anzeigen lässt.

Code: Alles auswählen

In [38]: import os.path

In [39]: os.path.join
Out[39]: <function join at 0xb7df733c>

In [40]: "".join
Out[40]: <built-in method join of str object at 0xb7dbc098>

Verfasst: Donnerstag 16. April 2009, 09:40
von snafu
Strings sind in Python eigene Klassen. Das zweite `join()` ist halt die Methode der Stringklasse. Du kannst dir das z.B. angucken mit:

Code: Alles auswählen

dir(str)

Verfasst: Donnerstag 16. April 2009, 10:41
von Nocta
Du musst auch beachten _wie_ du die Funktionen aufrufst.

Einmal als string.join womit man immer die Methode join von string meint. Allgemein gesagt: bei objekt.methode bezieht sich methode immer auf objekt und existiert nur in diesem Zusammenhang und hat dann auch nichts mit (vermeintlich - denn der Name ist string.join und nicht nur join) gleichnamigen anderen Funktionen zu tun.
Und beim anderem mal rufst du join(argument) auf, womit du eine Funktion aufrufst, die sich auf kein Objekt bezieht.

(Edit: joint -> join* ;) )

Verfasst: Donnerstag 16. April 2009, 11:46
von Hyperion
Damit es aber noch weniger Verwirrung gibt, importe ich das immer so:

Code: Alles auswählen

from os.path import join as osjoin
Hatte ich hier bei jemandem aus dem Board mal gelesen und gleich für mich übernommen.

Verfasst: Donnerstag 16. April 2009, 12:09
von BlackJack
Eigentlich wäre ja `path_join` ein passenderer Name, es werden ja keine Betriebssysteme verbunden, sondern (Teil)Pfade. ;-)

Allerdings kann man dann auch `from os import path` schreiben und `path.join` zum Aufruf verwenden. Ich benutze in der Regel immer den kompletten Namen `os.path.join` zum Aufrufen. Sooo lang ist das ja nun auch nicht.

Verfasst: Donnerstag 16. April 2009, 12:18
von Dauerbaustelle
Gibt es eigentlich ladezeitmäßig einen Unterschied zwischen `import os.path` und `from os.path import ...`?

Verfasst: Donnerstag 16. April 2009, 12:36
von Hyperion
BlackJack hat geschrieben:Eigentlich wäre ja `path_join` ein passenderer Name, es werden ja keine Betriebssysteme verbunden, sondern (Teil)Pfade. ;-)
Stimmt! :-)

Verfasst: Donnerstag 16. April 2009, 13:20
von BlackJack
@Dauerbaustelle: Nein, in beiden Fällen muss das ganze Modul geladen werden. Die Frage ist nur was unter welchem Namen im importierenden Modul gebunden wird.

Verfasst: Donnerstag 16. April 2009, 14:16
von jens
Also ich importiere generell nur "os" und nichts spezielles daraus...

Es gibt auch eine Regel, die besagt, das man nur Module imporieren sollte, aber nichts daraus... IMHO kommt das aus dem Styleguide von google.

Verfasst: Donnerstag 16. April 2009, 14:49
von nemomuk
@jens: aber in manchem Fällen doch wenig sinnvoll? Sobald es sich um längere Namen und verschachtelte Module handelt. Dann bin ich schon am Zeilenende bevor der Name ausgeschrieben ist... (das ist bei os sich kein Problem)

Verfasst: Donnerstag 16. April 2009, 14:56
von jens
Nö, denke nicht... Hast du Beispiele?

os.path.join im Quellentext ist auch einfacher lesbar, als einfach nur ein join und man erstmal nicht weiß, wo es herkommt...

Verfasst: Donnerstag 16. April 2009, 15:28
von Dauerbaustelle
jens hat geschrieben:Nö, denke nicht... Hast du Beispiele?
Naja sowas wie

Code: Alles auswählen

import django.contrib.admin.views.decorators
ist durchaus so

Code: Alles auswählen

from django.contrib.admin.views import decorators
besser lesbar- und nutzbar ;)

Verfasst: Donnerstag 16. April 2009, 15:34
von jens
Ja, django ist da was extremer... Ich würde natürlich nicht auf die Idee kommen deine erste Varianten zu machen ;)

Aber ich importiere auch nicht immer nur den letzten Teil ;) Was in django selber glaube ich nur gemacht wird...

Verfasst: Donnerstag 16. April 2009, 15:41
von snafu
jens hat geschrieben:Ja, django ist da was extremer...
Beim Erstellen von Gui's i.d.R. auch. Es gibt also schon ein paar Beispiele.

Aber ich gebe dir schon irgendwo recht. Auch ich habe ganze gerne wenigsten eine "Punktebene" dazwischen.

Verfasst: Donnerstag 16. April 2009, 15:55
von BlackJack
Ist aber auch kein Beispiel gegen jens' Aussage nichts aus Modulen zu importieren, denn `decorators` ist doch wahrscheinlich selbst wieder ein Module, oder?

Verfasst: Donnerstag 16. April 2009, 17:03
von nemomuk
Auf jeden Fall gibt es Sachen, wo's einfach zu lang wird. In 90% der Fälle würde ich es auch so wie jens machen.

Verfasst: Freitag 17. April 2009, 13:16
von audax

Code: Alles auswählen

from * import *
;)

Verfasst: Freitag 17. April 2009, 13:27
von nemomuk
@audax: Ich habe gerade ernsthaft ausprobiert, ob das funktioniert^^