module importieren

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Wieder eine eigentlich simple Frage.
Sagen wir Datei a.py enthählt folgenden Code:

Code: Alles auswählen

import random

A = 3
def do_something():
    pass

if __name__ == "__main__":
    b = 3
    do_something()
Nun importiere ich a.py:

Code: Alles auswählen

>>> import a
Jetzt kann ich ja logischerweise auf a.A, a.do_something() zugreifen aber nicht auf b.
Nun meine eigentlich Frage, da ich Module wie random Standardmäßig oben importiere, also nicht im Main-Bereich, kann ich ja auch auf a.random Zugreifen.

Ist sowas erwünscht ?
Also sollte ich wirklich noch mal random importieren, wenn ich es brauche, oder auf a.random zugreifen ?
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Benutzeravatar
snafu
User
Beiträge: 6834
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Nö, ich würde nochmal das eigentliche Modul explizit importieren und das nicht über Attributzugriffe von anderen Modulen machen, die es zufällig ebenfalls verwenden.
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Mach ich auch immer so, weil mir das andere unlogisch erscheint, nur warum besteht diese Möglichkeit.

bzw. das warum ist eigentlich klar, weil die Module ja oben im Globalen-Bereich importiert werden.
Aber ich finde es trotzdem ulkig warum dies möglich ist, gibt es da einen bestimmten Grund warum dies nicht unterbunden wird ?
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Xynon1 hat geschrieben:Aber ich finde es trotzdem ulkig warum dies möglich ist, gibt es da einen bestimmten Grund warum dies nicht unterbunden wird ?
Warum denn? Das zieht jede menge Sonderfaelle nach sich, denn ein Modul ist im Namespace eben auch nur irgendein Name und wenn du den fuer "externe" Module anders behandelst als fuer das momentane (und das muss man, wenn man Module nicht exportieren will) kommst du am ende mit 2 Namespaces raus oder hast jede Menge Ueberpruefungen zur Laufzeit.

Und warum?
Benutzeravatar
DrFaust
User
Beiträge: 21
Registriert: Freitag 15. Oktober 2010, 23:10

Sehe ich wie cofi. Python hat noch nie den Programmierer vor seiner eigenen Dummheit geschützt (anders als z.B. Java, die das ins Extrem getrieben haben). Ob ich dieses Beispiel jetzt schon als Dummheit bezeichnen würde weiß ich nicht. Aber grundsätzlich gilt in Python aber doch: Wenn der Programmierer meint etwas machen zu müssen das ihm vielleicht später auf die Füße fällt oder zumindest kein guter Stil ist, dann wird Python ihn nicht daran hindern.
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Wie wirkt sich das dann generell auf den Speicher aus ?
Also wenn zwei/mehr Scripte ganz normal das gleiche Modul importieren.

Greifen dann beide trotzdem auf das selbe Modul im speicher zu nur mit anderen Variablennamen und/oder anderen Namensraum, oder wird das importierte Modul für beide Zugriffe extra hinterlegt ?
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Xynon1 hat geschrieben: Greifen dann beide trotzdem auf das selbe Modul im speicher zu nur mit anderen Variablennamen und/oder anderen Namensraum, oder wird das importierte Modul für beide Zugriffe extra hinterlegt ?
Ohne es def. zu wissen würde ich davon ausgehen, dass dann das Modul-Objekt nur an einen anderen Namen gebunden wird und somit dasselbe bleibt.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Code: Alles auswählen

%> echo "import os" > a.py
%> echo "import os" > b.py
%> echo "import a,b" > c.py
%> echo "print a.os is b.os" >> c.py
%> python c.py
True
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

q.e.d. :-)

Weiß jemand, wie Python da intern vorgeht, um zu prüfen, ob ein Modul bereits im Speicher vorhanden ist? Woran erkennt Python das?

Edit: Ok, habe mal in der Shell die Liste sys.modules entdeckt und mal os importiert:

Code: Alles auswählen

In [17]: sys.modules["os"]
Out[17]: <module 'os' from 'C:\Programme\Python27\lib\os.pyc'>
Augenscheinlich ist der Pfad, woher ein Modul geladen wurde, das 'Erkennungsmerkmal'.

Edit2: Nee, wohl doch nicht:
python-2.7-docs-html/reference/simple_stmts.html#the-import-statement hat geschrieben: Once the name of the module is known (unless otherwise specified, the term “module” will refer to both packages and modules), searching for the module or package can begin. The first place checked is sys.modules, the cache of all modules that have been imported previously. If the module is found there then it is used in step (2) of import.
Also geht es doch "stumpf" über den Namen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Naja, zwei Module die genauso heißen importieren zu wollen, indem man zwischen dem ersten und den zweiten Import ``sys.path`` anpasst würde ich eher als "Bad Practice" ansehen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten