sirve run que pass para name__ name main__ def python main init

python - run - Usar los propios objetos del módulo en__main__.py



que es__ name__ python (5)

Estoy intentando acceder a los datos de un módulo desde dentro de su __main__.py .

La estructura es la siguiente:

mymod/ __init__.py __main__.py

Ahora, si __init__.py una variable en __init__.py esta manera:

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

¿Cómo puedo acceder a foo desde __main__.py ?


El módulo __init__ de un paquete actúa como miembros del paquete en sí, por lo que los objetos se importan directamente desde mymod :

from mymod import foo

O

from . import foo

si le gusta ser conciso, lea sobre importaciones relativas . mymod/__main__.py asegurarse, como siempre, de que no invoque el módulo como mymod/__main__.py , por ejemplo, ya que eso evitará que Python detecte mymod como un paquete. Es posible que desee ver en distutils .


El problema con el que me __init__.py más con este tipo de cosas es que a menudo quiero ejecutar el archivo __init__.py como un script para probar las características, pero estas no deben ejecutarse al cargar el paquete. Existe una solución útil para las diferentes rutas de ejecución entre python <package>/__init__.py y python -m <package> .

  • $ python -m <module> ejecuta <package>/__main__.py . __init__.py no está cargado.
  • $ python <package>/__init__.py simplemente ejecuta el script __init__.py como un script normal.


El problema

Cuando queremos que __init__.py tenga una cláusula if __name__ == ''__main__'': ... que usa cosas de __main__.py . No podemos importar __main__.py porque siempre importará __main__.pyc de la ruta del intérprete. ( A menos que ... recurramos a los cortes de importación de ruta absoluta, que pueden causar muchos otros problemas).


La solución Una solución :)

Use dos archivos de script para __main__ del módulo:

<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__''

Las importaciones en main.py probablemente no sean ideales en caso de que __init__.py , ya que las estamos recargando en el ámbito local de otro módulo, a pesar de tenerlas __init__.py en __init__.py , pero la carga explícita debe evitar carga circular Si vuelve a cargar todo el módulo __init__ en main.py , no se cargará como __main__ , por lo que debería ser seguro en lo que respecta a la carga circular.


La estructura del directorio del módulo es la siguiente:

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})

Ejecute el módulo como una secuencia de comandos utilizando la -m

$ 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}}


Necesita tener el paquete ya en sys.path , agregar el directorio que contiene mymod a sys.path en __main__.py , o usar el __main__.py -m .

Agregar mymod a la ruta sería algo como esto (en __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

El uso del -m le gustaría:

python -m mymod

Vea esta respuesta para más discusión.


Si ejecuta el módulo con python -m mymod , el código en __main__.py podrá importar desde el resto del módulo sin tener que agregar el módulo a sys.path .