Frage

Ich versuche, Daten eines Moduls aus dem Innern seines __main__.py zugreifen zu können.

Die Struktur ist wie folgt:

mymod/
    __init__.py
    __main__.py

Nun, wenn ich eine Variable in __init__.py wie folgt aussetzen:

__all__ = ['foo']
foo = {'bar': 'baz'}

Wie kann ich foo von __main__.py?

War es hilfreich?

Lösung

Sie müssen entweder das Paket bereits in sys.path, fügen Sie das Verzeichnis mymod zu sys.path in __main__.py enthält, oder die -m Schalter verwenden.

Um mymod auf den Pfad hinzufügen würde wie folgt aussehen (in __main__.py):

import sys
import os
path = os.path.dirname(sys.modules[__name__].__file__)
path = os.path.join(path, '..')
sys.path.insert(0, path)
from myprog import function_you_referenced_from_init_file

den -m Schalter verwenden möchten:

python -m mymod

finden Sie unter diese Antwort .

Andere Tipps

Das Problem, das ich mit dieser Art der Sache in den meisten laufen, ist, dass ich möchte oft die __init__.py Datei als Skript zu Testfunktionen ausführen, aber diese sollten nicht ausgeführt werden, wenn das Paket geladen werden. Es ist eine nützliche Abhilfe für die verschiedenen Ausführungspfade zwischen python <package>/__init__.py und python -m <package>.

  • $ python -m <module> ausführt <package>/__main__.py. __init__.py nicht geladen ist.
  • $ python <package>/__init__.py führt einfach das Skript __init__.py wie ein normales Skript.


Das Problem

Wenn wir wollen __init__.py eine if __name__ == '__main__': ... Klausel haben, dass Anwendungen Sachen aus __main__.py. Wir können nicht importieren __main__.py, weil es immer Import __main__.pyc aus dem Weg des Dolmetschers. ( Es sei denn, ... greifen wir auf absoluten Pfad Import Hacks, die eine Menge anderen Chaos verursachen kann).


Die Lösung Eine Lösung:)

Mit zwei Skriptdateien für das Modul des __main__:

<package>/
         __init__.py
         __main__.py
         main.py

# __init__.py

# ...
# some code, including module methods and __all__ definitions

__all__ = ['foo', 'bar']
bar = {'key': 'value'}
def foo():
    return bar
# ...
if __name__ == '__main__':
    from main import main
    main.main()

# __main__.py

# some code...such as:
import sys
if (len(sys.argv) > 1 and sys.argv[1].lower() == 'option1'):
    from main import main()
    main('option1')
elif (len(sys.argv) > 1 and sys.argv[1].lower() == 'option2'):
    from main import main()
    main('option2')
else:
    # do something else?
    print 'invalid option. please use "python -m <package> option1|option2"'

# main.py

def main(opt = None):
    if opt == 'option1':
        from __init__ import foo
        print foo()
    elif opt == 'option2':
        from __init__ import bar
        print bar.keys()
    elif opt is None:
        print 'called from __init__'

Die Einfuhren in main.py sind wahrscheinlich nicht ideal in dem Fall, dass wir von __init__.py laufen, wie wir sie in den lokalen Bereich eines anderen Moduls sind Nachladen trotz Laden sie bereits in __init__.py zu haben, aber die explizite Laden sollte Kreis Belastung vermeiden. Wenn Sie den gesamten __init__ Modul laden Sie wieder in Ihren main.py, wird es nicht als __main__ geladen werden, so sicher sein, sollte so weit wie Kreis Belastung betroffen ist.

Das __init__ Modul von ein Paket wirkt wie Mitglieder der Verpackung selbst , so werden die Objekte direkt aus mymod importiert werden:

from mymod import foo

oder

from . import foo

Wenn Sie sein terse mögen, dann lesen Sie über relativ Importe . Sie müssen sicherstellen, wie immer, dass Sie nicht rufen Sie das Modul als mymod/__main__.py zum Beispiel, wie der Python verhindern mymod als Paket aus zu erkennen. Vielleicht möchten Sie schauen distutils .

Wenn Sie das Modul mit python -m mymod dann Code in __main__.py laufen in der Lage, vom Rest des Moduls zu importieren, ohne das Modul zu sys.path hinzuzufügen.

Modulverzeichnisstruktur ist wie folgt:

py/
   __init__.py
   __main__.py

__ init __. Py

#!/usr/bin/python3
#
# __init__.py
#

__all__ = ['foo']
foo = {'bar': 'baz'}
info = { "package": __package__,
         "name": __name__,
         "locals": [x for x in locals().copy()] }
print(info)

__ Haupt __. Py

#!/usr/bin/python3
#
# __main__.py
#

info = { "package": __package__,
         "name": __name__,
         "locals": [x for x in locals().copy()] }
print(info)
from . import info as pyinfo
print({"pyinfo: ": pyinfo})

Führen Sie das Modul als Skript die -m Flagge mit

$ python -m py

# the printout from the 'print(info)' command in __init__.py
{'name': 'py', 'locals': ['__all__', '__builtins__', '__file__', '__package__', '__path__', '__name__', 'foo', '__doc__'], 'package': None}
# the printout from the 'print(info)' command in __main__.py
{'name': '__main__', 'locals': ['__builtins__', '__name__', '__file__', '__loader__', '__doc__', '__package__'], 'package': 'py'}
# the printout from the 'print(pyinfo)' command in __main__.py
{'pyinfo: ': {'name': 'py', 'locals': ['__all__', '__builtins__', '__file__', '__package__', '__path__', '__name__', 'foo', '__doc__'], 'package': None}}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top