2011-02-25 19 views
7

Estoy tratando de escribir algunos (en mi opinión) código legible en Python. Necesito un módulo que contendrá varias clases. Teóricamente, sé todo lo que se necesita para lograr esto: simplemente puedo poner definiciones de clase en un solo archivo de módulo.Espaciado de nombres y clases

Para fines de legibilidad, quiero poner cada definición de clase en un archivo separado (¡están empezando a ser bastante largas!), Y todas estas clases en un solo directorio. Cada vez que creo un archivo nuevo, aunque sus contenidos están visibles donde los necesito, la definición de clase que está dentro tiene un alcance con el módulo innecesario.

¿Cómo debo hacerlo? ¿Cuál es la forma de 'Python' de hacer eso?

Respuesta

8

Importe todos dentro de __init__.py y haga que el consumidor importe el paquete.

from .module1 import Class1 
from .module2 import Class2 
... 
+0

¿Qué significa punto anterior? – samuil

+0

@samuil: http://www.python.org/dev/peps/pep-0328/ –

+0

Lamentablemente, estoy restringido a Python 2.4, ya que los scripts se ejecutarán en dispositivos integrados de terceros. Esta notación de puntos no parece funcionar en la versión heredada. Lo he reemplazado con una ruta completa a estos submódulos. – samuil

3

Si se quiere evitar hardcoding rutas completas, archivo, clase y nombres de funciones en muchos lugares, se podría hacer algo como lo siguiente que importa dinámicamente (casi) todos los archivos del pitón se encuentra en el subdirectorio de un paquete .

La clave es recordar que el archivo __init__.py es en sí mismo un script Python en gran medida sin restricciones y, por lo tanto, es libre de realizar un procesamiento propio bastante sofisticado para determinar qué hay en el espacio de nombres del paquete.

Archivo package\__init__.py:

def _import_package_files(): 
    """ Dynamically import all the Python modules in this module's sub directory. """ 
    import os 
    import sys 
    import traceback 

    package_path = os.path.split(__file__)[0] 
    package_directory = os.path.split(package_path)[1] 

    for fn in os.listdir(package_directory): 
     globals_, locals_ = globals(), locals() 
     # process all python files in directory that don't start with underscore 
     if fn[0] != '_' and fn.split('.')[-1] in ('py', 'pyw'): 
      modulename = fn.split('.')[0] # filename without extension 
      subpackage = ".".join([package_directory, modulename]) 
      try: 
       module = __import__(subpackage, globals_, locals_, [modulename]) 
      except: 
       traceback.print_exc(file=sys.stdout) 
       raise # reraise exception 

_import_package_files() 

Archivo package\Class1.py:

class Class1(object): 
    pass 

Archivo package\Class2.py:

class Class2(object): 
    pass 

Archivo package\Class3.py:

class Class3(object): 
    pass 

Archivo usepackage.py:

import package 

print(package.Class1) 
print(package.Class2) 
print(package.Class3) 

resultado de la ejecución usepackage.py:

<module 'package.Class1' from 'C:\Files\package\Class1.pyc'> 
<module 'package.Class2' from 'C:\Files\package\Class2.pyc'> 
<module 'package.Class3' from 'C:\Files\package\Class3.pyc'> 
+0

Esto es increíble. Funciona en Python 3.4.1. – blockloop

Cuestiones relacionadas