Utilisation des propres objets du module dans main.py

j'essaie d'accéder aux données d'un module depuis son __main__.py.

la structure est la suivante:

mymod/
    __init__.py
    __main__.py

Maintenant, si j'expose une variable __init__.py comme ceci:

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

Comment puis-je accéder à foo__main__.py?

39
demandé sur Zearin 2010-08-05 06:15:58

5 réponses

vous devez avoir le paquet déjà dans sys.path, ajouter le répertoire contenant mymodsys.path__main__.py, ou -m switch.

ajouter mymod vers le chemin ressemblerait à quelque chose comme ceci (dans __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

-m interrupteur serait de la forme:

python -m mymod

Voir cette réponse pour plus de discussion.

22
répondu pdemb 2017-05-23 10:31:10

le problème que je rencontre le plus avec ce genre de chose est que je veux souvent exécuter le __init__.py fichier en tant que script pour tester les fonctionnalités, mais celles-ci ne doivent pas être exécutées lors du chargement du paquet. Il y a une solution utile pour les différents chemins d'exécution entre python <package>/__init__.py et python -m <package>.

  • $ python -m <module> exécute <package>/__main__.py. __init__.py n'est pas chargé.
  • $ python <package>/__init__.py exécute simplement le script __init__.py comme un script normal.



Le problème

Quand on veut __init__.py avoir if __name__ == '__main__': ... clause que des trucs à partir de __main__.py. Nous ne pouvons pas importer!--14-- > parce qu'il importera toujours __main__.pyc à partir du chemin de l'interprète. ( à moins que ... nous avons recours à des hacks d'importation de chemin absolu, ce qui peut causer beaucoup d'autres dégâts).



la solution une solution :)

utilisez deux fichiers de script pour __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__'

Les importations en main.py ne sont probablement pas idéales dans le cas où nous fuyons __init__.py, alors que nous sommes en train de les recharger dans la portée locale d'un autre module, malgré le fait de les avoir chargés dans __init__.py déjà, mais le chargement explicite devrait éviter circulaire de chargement. Si vous ne charge l'ensemble de l' __init__ module de nouveau dans votre main.py, il ne sera pas chargé comme

4
répondu Nisan.H 2012-10-22 22:15:00

__init__ module deun paquet agit comme les membres du paquet lui-même, de sorte que les objets sont importés directement de mymod:

from mymod import foo

Ou

from . import foo

si vous voulez être laconique, puis lisez à propos de importations relatives. Vous devez vous assurer que, comme toujours, que vous n'avez pas invoquer le module mymod/__main__.py, par exemple, car cela empêchera Python de détecter mymod comme un paquet. Vous pouvez regarder dans distutils.

2
répondu Josh Lee 2010-08-05 02:27:36

Si vous exécutez le module python -m mymod puis coder en __main__.py sera en mesure d'importer du reste du module sans avoir à ajouter le module sys.path.

1
répondu glyphobet 2012-05-10 19:57:17

la structure des répertoires de Modules est la suivante:

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)

_ _ main__.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})

exécutez le module comme un script en utilisant le -m drapeau

$ 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}}
-2
répondu cogsmos 2012-07-19 17:33:14