2009-12-01 6 views
27

estoy usando Django y tengo un archivo llamado models.admin.py y quiero hacer la siguiente idea en models.py:cómo hacer referencia al paquete python nombre de archivo contiene un período

from "models.admin" import * 

sin embargo, Obtengo un error de sintaxis por tener comillas dobles. Pero si acabo de hacer

from models.admin import * 

entonces consigo "ImportError: Ningún módulo llamado admin"

¿Hay alguna manera de importar desde un archivo de Python (que tiene un período en su nombre)?

+7

HELLO HELLO ¿Qué está ** forzando ** a tener un nombre de archivo como models.admin.py ?? Por qué no llamarlo models_admin.py o models/admin.Py o lo que sea que encaja con Django? –

+7

Por favor, no hagas esto. –

+1

Técnicamente, eso es un módulo, no un paquete. – Cerin

Respuesta

23

En realidad, usted puede importar un módulo con un nombre no válido. Pero necesitará usar imp para eso, p. asumiendo archivo se llama models.admin.py, se podría hacer

import imp 
with open('models.admin.py', 'rb') as fp: 
    models_admin = imp.load_module(
     'models_admin', fp, 'models.admin.py', 
     ('.py', 'rb', imp.PY_SOURCE) 
    ) 

Pero leer los documentos en imp.find_module y imp.load_module antes de empezar a usarla.

+3

¿Mala práctica? 'imp' es el mecanismo detrás de' import' y '__import__'. Más flexibilidad, pero requiere más código. Sin embargo, nada mágico al respecto. –

+5

Y el código de máquina es el mecanismo detrás de todo. Más flexibilidad y ... ¿ver a dónde voy? :) – shylent

+1

Obviamente necesitas pensarlo dos veces si realmente necesitas usarlo, pero no veo cómo usarlo es terriblemente incorrecto. ;) Y se usa en producción - ver p. Trac - http://trac.edgewall.org/browser/trunk/trac/loader.py. –

4

El archivo se llama models/admin.py. (Source)

Es decir, se debe llamar admin.py en un directorio llamado models.

Luego puede importar usando from models.admin import *, suponiendo que está en su ruta de Python.

2

No, no puede importar un archivo python como un módulo si su nombre contiene un punto (o un signo de interrogación o signo de exclamación, etc.). El nombre de un módulo python (sin incluir el .py) debe ser un nombre python válido (es decir, se puede usar como un nombre de variable).

+0

¿Tiene una referencia a mano para esto? – Taras

+2

La referencia es la especificación de gramática de Python (https://docs.python.org/2/reference/grammar.html). Sin embargo, esto realmente solo especifica lo que está permitido para la declaración de importación, como se señaló anteriormente en la respuesta aceptada, es técnicamente posible evitar esto utilizando los mecanismos de importación subyacentes. –

0

No se hace referencia a los archivos en la declaración de importación, se hace referencia a módulos y paquetes.

Lea el docs, ellos son muy claros al respecto.

De todos modos, como está utilizando django, el enfoque habitual no funcionará. Si desea mantener los modelos en archivos separados, en lugar de en models.py, debe realizar pasos adicionales, descritos, por ejemplo, here.

Edit:
Bueno, realmente no sé lo que quiere decir el interrogador cuando menciona administrador y si está relacionado o no con la interfaz de administración de django. Mis puntos siguen en pie.

+1

Un módulo es un archivo. Para citar los documentos a los que hizo referencia: 'Para respaldar esto, Python tiene una forma de poner definiciones en un archivo y usarlas en un script o en una instancia interactiva del intérprete. Tal archivo se llama módulo; ' –

10

Si realmente desea, puede importar un módulo con un nombre de archivo original (por ejemplo, un nombre de archivo que contiene una antes de la '.py' '') usando el módulo imp:

>>> import imp 
>>> a_b = imp.load_source('a.b', 'a.b.py') 
>>> a_b.x 
"I was defined in a.b.py!" 

Sin embargo, esa es generalmente una mala idea. Es más probable que intente usar paquetes, en cuyo caso debe crear un directorio llamado "a", que contenga un archivo llamado "b.py"; y luego "importar a.b" cargará a/b.py.

+1

' load_source' es obsoleto desde al menos 1.5. –

+0

Es cierto, aunque la forma no obsoleta de hacerlo es un poco más verbo: a_b = imp.load_module ('a.b', open ('abpy'), os.path.abspath ('abpy'), ('.py', 'r', imp.PY_SOURCE)) –

Cuestiones relacionadas