2013-06-21 5 views
7

Ci è stato detto che usare from module import * è una cattiva idea. Tuttavia, esiste un modo per importare un sottoinsieme del contenuto di module utilizzando un carattere jolly?Python: importazione sottotitoli jolly

Ad esempio:

module.py:

MODULE_VAR1 = "hello" 
MODULE_VAR2 = "world" 
MODULE_VAR3 = "The" 
MODULE_VAR4 = "quick" 
MODULE_VAR5 = "brown" 
... 
MODULE_VAR10 = "lazy" 
MODULE_VAR11 = "dog!" 
MODULE_VAR12 = "Now" 
MODULE_VAR13 = "is" 
... 
MODULE_VAR98 = "Thats" 
MODULE_VAR99 = "all" 
MODULE_VAR100 = "folks!" 

def abs(): 
    print "Absolutely useful function: %s" % MODULE_VAR1 

Ovviamente non si desidera utilizzare from module import * perché saremmo sovrascrivendo la funzione abs. Ma supponiamo di volere che tutte le variabili MODULE_VAR* siano accessibili localmente.

Inserire semplicemente from module import MODULE_VAR* non funziona. C'è un modo per realizzare questo?

Ho usato 100 variabili come illustrazione, perché fare from module import MODULE_VAR1, MODULE_VAR2, MODULE_VAR3, ..., MODULE_VAR100 sarebbe ovviamente incredibilmente ingombrante e non funzionerebbe se fossero state aggiunte più variabili (ad esempio MODULE_VAR101).

risposta

2

È possibile utilizzare la variabile __all__ per importare variabili specifiche quando si utilizza la sintassi import *.

mymodule.py

__all__ = [ 
    'MODULE_VAR1', 
    'MODULE_VAR2', 
    'MODULE_VAR3', 
    'MODULE_VAR4', 
    'MODULE_VAR5', 
] 

MODULE_VAR1 = "hello" 
MODULE_VAR2 = "world" 
MODULE_VAR3 = "The" 
MODULE_VAR4 = "quick" 
MODULE_VAR5 = "brown" 

def abs(): 
    print "Absolutely useful function: %s" % MODULE_VAR1 

Poi possiamo usare questa convenzione:

from mymodule import * 
print MODULE_VAR1 # hello 
print abs # <built-in function abs> 

Quando un modulo viene importato utilizzando *, Python controlla il modulo per una variabile __all__ che può ignorare ciò che altrimenti sarebbe considerato le normali variabili "pubbliche" nel modulo (che sarebbero variabili che non iniziano con caratteri di sottolineatura) e consente di definire esplicitamente quali variabili sono "pubbliche". Check out this question

+0

Questo è fantastico! Ma esiste un modo per ottenere lo stesso effetto se non si ha il controllo sul codice sorgente del modulo? – seaotternerd

+0

Mi dispiace aver frainteso. Non conosco alcun modo per importare in modo nativo variabili specifiche da un altro modulo. Ma come soluzione molto semplice, potresti creare un helper che importa il modulo e itera sugli attributi del modulo per estrarre le variabili che desideri. Nel tuo esempio, questo eviterebbe la sovrascrittura della variabile 'abs', non stai importando le variabili del modulo ma il modulo stesso. In alternativa, * potresti * importare le variabili del modulo nell'ambito di una funzione, impedendo la sovrascrittura della funzione incorporata 'abs'. Penso che @jsbueno abbia un esempio perfetto. – kuujo

+0

Non so se hai frainteso - non ero la persona che ha fatto la domanda, ero solo curioso. Grazie! – seaotternerd

7

Si può avere una funzione di supporto per questo - e può essere fatto senza la magia:

import re 

def matching_import(pattern, module, globals): 
    for key, value in module.__dict__.items(): 
     if re.findall(pattern, key): 
      globals[key] = value 

Ora, si può fare ad esempio:

from utils import matching_import 
import constants 

matching_import("MODULE_VAR.*", constants, globals()) 

Utilizzando globals() esplicitamente in questa modo evita di incorniciare la magia dell'introspezione, che di solito è considerata dannosa.

+0

Buona soluzione. +1 – kuujo