2013-06-21 5 views
7

Wir haben alle gesagt, mit from module import * ist eine schlechte Idee. Gibt es jedoch eine Möglichkeit, eine Untergruppe des Inhalts von module mit einem Platzhalter zu importieren?Python: Wildcard-Subset-Import

Zum Beispiel:

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 

Natürlich wollen wir nicht from module import * verwenden, da wir die abs Funktion überschreiben würde. Aber nehmen wir an, wir wollten, dass alle MODULE_VAR* Variablen lokal zugänglich sind.

Einfach setzen from module import MODULE_VAR* funktioniert nicht. Gibt es einen Weg, dies zu erreichen?

Ich habe 100 Variablen als Illustration verwendet, denn from module import MODULE_VAR1, MODULE_VAR2, MODULE_VAR3, ..., MODULE_VAR100 wäre offensichtlich unglaublich unhandlich und würde nicht funktionieren, wenn mehr Variablen (z. B. MODULE_VAR101) hinzugefügt wurden.

Antwort

2

Sie können die Variable __all__ verwenden, um bestimmte Variablen zu importieren, wenn Sie die import *-Syntax verwenden.

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 

Dann können wir es auf diese Weise verwenden:

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

Wenn ein Modul * importiert verwendet, prüft Python das Modul für eine __all__ Variable, die, was sonst in Betracht gezogen werden würde außer Kraft setzen können die normalen "öffentlichen" Variablen im Modul (das wären Variablen, die nicht mit Unterstrichen beginnen) und erlaubt Ihnen, explizit zu definieren, welche Variablen "öffentlich" sind. Check out this question

+0

Das ist großartig! Aber gibt es eine Möglichkeit, denselben Effekt zu erzielen, wenn Sie keine Kontrolle über den Quellcode des Moduls haben? – seaotternerd

+0

Sorry ich missverstanden. Ich kenne keine Möglichkeit, spezifische Variablen von einem anderen Modul nativ zu importieren. Aber als eine sehr einfache Lösung könnten Sie einen Helfer erstellen, der das Modul importiert und die Attribute des Moduls durchläuft, um die gewünschten Variablen zu extrahieren. In Ihrem Beispiel würde dies verhindern, dass die Variable "abs" außer Kraft gesetzt wird. Sie importieren nicht die Modulvariablen, sondern das Modul selbst. Alternativ könnten Sie die Modulvariablen im Rahmen einer Funktion importieren, wodurch verhindert wird, dass die integrierte Funktion "abs" außer Kraft gesetzt wird. Ich denke @jsbueno hat ein perfektes Beispiel. – kuujo

+0

Ich weiß nicht, ob Sie falsch verstanden - ich war nicht die Person, die die Frage stellte, ich war nur neugierig. Vielen Dank! – seaotternerd

7

Sie können, dass eine Hilfsfunktion haben - und es kann ohne Magie geschehen:

import re 

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

Jetzt können Sie zum Beispiel tun können:

from utils import matching_import 
import constants 

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

globals() ausdrücklich in diese Verwendung Weg vermeidet Rahmen Introspektion Magie, die in der Regel als schädlich angesehen wird.

+0

Gute Lösung. +1 – kuujo