2016-03-26 10 views
3

Ich führe mehrere Python-Skripte aus, die bis auf ein Präfix auf den Variablen identisch sind. (Nur aus Gründen der Klarheit arbeite ich mit Tweepy und der Twitter API).So rufen Sie 'from x import *' auf, wobei x eine Variable in Python ist

Ich habe jede API-Anmeldeinformationen , yy_apicred.py usw. benannt, und diese werden als separate Datei im Ordner gespeichert.

Auch habe ich Tabellen mit den Namen xx_info, yy_info, etc. Dieser Teil ist einfach durch String-Manipulation zu ändern.

Ich möchte dies ändern, so dass es eine Datei ist, in der ich die xx-Zeichenfolge als Argument übergeben. Dies funktioniert für alles außer den from xx_cred import*

Wenn ich es mit einem String-Variable ersetzen, ich den Fehler, dass ImportError: No module named 'var'

Gibt es eine Weise, die ich durch eine Variable importieren?

Antwort

2

Dies würde Strings als Modulnamen erlauben:

import importlib 

cred = importlib.import_module('{}_cred'.format(impl)) 

Wo impl ist die gewählte Implementierung 'xx' oder 'yy'.

Mehrere Python-Bibliotheken verwenden diesen Trick (Tornado, rethinkdb ...)

nun wie folgt verwenden:

cred.module_var 

Wenn Sie wirklich die Wirkung von from module import * verwenden möchten:

variables = {name: value for name, value in vars(cred).items() 
      if not name.startswith('__')} 
globals().update(variables) 

Aber import * ist nicht empfohlen.

+0

Ich habe dieses versucht und es findet das Modul nicht. Ich habe versucht, "Import-Cred" nach und es findet nicht das "Cred" Modul – pekasus

+0

Versuchen Sie nicht, es erneut zu importieren. Verwenden Sie einfach "cred" als Modul. –

+0

Super! Es klappt. Vielen Dank! Gibt es eine Möglichkeit, ein "from xx import *" zu machen oder muss ich jedes Mal "cred.variable" angeben? – pekasus

0

zusätzliche FYI nurnicht als beste Antwort gewählt werden

Dies ist, wie überdenken DB intern ist, basierend auf dem Schleifen die Benutzersätze geben:

def set_loop_type(library): 
    global connection_type 

    # find module file 
    moduleName = 'net_%s' % library 
    modulePath = None 
    driverDir = os.path.realpath(os.path.dirname(__file__)) 
    if os.path.isfile(os.path.join(driverDir, library + '_net', moduleName + '.py')): 
     modulePath = os.path.join(driverDir, library + '_net', moduleName + '.py') 
    else: 
     raise ValueError('Unknown loop type: %r' % library) 

    # load the module 
    moduleFile, pathName, desc = imp.find_module(moduleName, [os.path.dirname(modulePath)]) 
    module = imp.load_module('rethinkdb.' + moduleName, moduleFile, pathName, desc) 

imp ist ein nützliches Python-Bibliothek können Sie auch nutzen.

+0

Aus dem Dokument von 'imp': * In den meisten Fällen ist es vorzuziehen, dass Sie die' importlib' Modul-Funktionalität über dieses Modul verwenden. * –

+0

Erzählen Sie das den RethinkDB-Entwicklern ;-) Vielleicht fällt dies unter einige die kantigen Fälle, in denen Impl besser ist. –

+0

'importlib': * Neu in Version 3.1. * Und * Neu in Version 2.7 *. Dieser RethinkDB-Code ist wahrscheinlich älter als dieser. –

2

Vor allem, lassen Sie mich beachten, dass from module import * wird allgemein als schlechte Praxis in tatsächlichen Code betrachtet. Es ist wirklich nur ein Trick, um Dolmetscher-Sitzungen einfacher zu machen. Sie sollten entweder from module import a, b oder import module; module.a().

Wenn man wirklich dynamisch will alle Namen in den aktuellen globalen Namensraum im Modul mitbringen, können Sie dies tun:

import importlib 

module = importlib.import_module('module') 
globs = globals() 
for key, value in vars(module).items(): 
    if key not in globs: 
     globs[key] = value 

Dadurch werden Sie verwenden, um Mitglieder von module unqualifizierten aber Tool wie IDEs arbeiten und lassen wird diese Magie nicht verstehen und wird denken, dass Ihre Variablen nicht definiert sind (nicht dass dies den Code daran hindert, ausgeführt zu werden, da werden nur 'Fehler' hervorgehoben). Es wäre viel besser, manuell die Variablen zu erstellen, die Sie als Aliase der qualifizierten Versionen benötigen, wie es andere erwähnt haben, z.variable = cred.variable.

+0

inspect + globals gegen den eleganten getattr, wirklich ???? –

+1

@Apero Ich folge nicht, wie schlagen Sie vor, "getattr" zu verwenden, um dieses Problem zu lösen? Sie erwähnen es nicht in Ihrer Antwort. Meine Antwort ist die einzige, die tatsächlich die Frage von OP beantwortet (obwohl ich ihn gewarnt habe, dass seine Frage eine schlechte Idee ist). Das Erhalten eines Modulobjekts ist nicht das Gleiche wie das Importieren aller seiner Elemente, da Sie die Namen der Werte im Modul noch qualifizieren müssen, was OP offensichtlich nicht zu tun hat. –

+0

Meine Antwort war nur ein FYI keine Antwort. Ich bin kein Experte vom Modulimport * und ich importiere immer Modul und dann modul.something stattdessen. Wenn also das OP dasselbe tut, würde ein simples getattr es ihm leicht machen, aber wieder sollte er einfach modul.something machen und das Modul nur dynamisch laden, wie von der ausgewählten Antwort empfohlen. –

Verwandte Themen