Frage

Ich habe viel zu lange darüber nachgedacht und haben keine Ahnung bekommen, vielleicht können einige von euch helfen.

Ich habe einen Ordner mit Python-Skripte, die alle den gleichen umgebenden Körper (wörtlich: Ich erzeugen es von einem Shell-Skript), aber einen Brocken habe, als sie alle anders. Mit anderen Worten:

Top piece of code (always the same)
Middle piece of code (changes from file to file)
Bottom piece of code (always the same)

Und mir heute klar, dass dies eine schlechte Idee ist, zum Beispiel, wenn ich von den oberen oder unteren Abschnitten etwas ändern will, muß ich einen Shell-Skript schreiben, es zu tun. (Nicht, dass das ist schwer, es scheint nur, wie es ist sehr schlecht Code weise).

Also, was ich tun möchte, ist eine äußere Python-Skript, die wie folgt lautet:

Top piece of code
Dynamic function that calls the middle piece of code (based on a parameter)
Bottom piece of code

Und dann kann jede andere Python-Datei in dem Ordner einfach das mittlere Stück Code sein. Allerdings würde Normalmodul nicht hier arbeiten (es sei denn, ich irre), weil ich den Code bekommen würde ich von der arguement ausführen müssen, die eine Zeichenfolge sein würde, und so würde ich nicht wissen, welche Funktion erst zur Laufzeit laufen .

dachte Also habe ich zwei weitere Lösungen auf:

  1. Ich konnte eine Reihe von if-Anweisungen aufzuschreiben, ein jedes Skript ausgeführt werden sollen, basierend auf einem bestimmten Parameter. Ich lehnte dies, wie es ist noch schlimmer als die bisherige Konstruktion.
  2. Ich konnte verwenden:

    os.command (sys.argv [0] scriptName.py)

    , die das Skript ausführen würde, aber auf Anruf Python ruft Python scheint nicht sehr elegant zu mir.

So hat jemand noch andere Ideen? Danke.

War es hilfreich?

Lösung

Wenn Sie den Namen der Funktion als String und dem Namen des Moduls als String kennen, dann können Sie tun,

mod = __import__(module_name)
fn = getattr(mod, fn_name)
fn()

Andere Tipps

Ein andere mögliche Lösung ist jede Ihrer wiederholenden Dateien zu haben, um die Funktionalität von der Hauptdatei importieren

from topAndBottom import top, bottom
top()
# do middle stuff
bottom()

Zusätzlich zu den verschiedenen Antworten bereits gebucht, sollten Sie die Template-Methode Design-Muster: macht eine abstrakte Klasse wie

class Base(object):
    def top(self): ...
    def bottom(self): ...
    def middle(self): raise NotImplementedError
    def doit(self):
        self.top()
        self.middle()
        self.bottom()

Jedes steckbares Modul macht dann eine Klasse, die erbt von diesem Base und middle mit dem entsprechenden Code überschreiben muss.

Vielleicht nicht für diesen einfachen Fall gerechtfertigt (Sie müssen noch das richtige Modul importieren, um seine Klasse und Call doit darauf zu instanziiert), aber immer noch wert unter Berücksichtigung (zusammen mit seinen vielen Pythonic Variationen, die ich habe reichlich erklärte heute in vielen Tech-Gesprächen auf youtube verfügbar) für Fälle, in denen die Anzahl und Komplexität von „Pluggable Stücken“ weiter wachsen - Template-Methode (trotz seiner schrecklichen Namen ;-) ist ein solides, bewährten und hochskalierbare Muster [[ manchmal ein bisschen zu steif, aber das ist genau das, was ich in den vielen Tech-Gesprächen Adresse - und das Problem gilt nicht auf diesen speziellen Anwendungsfall]]

.
  

Allerdings würde Normalmodul nicht hier arbeiten (es sei denn, ich irre), weil ich den Code bekommen würde ich von der arguement ausführen müssen, die eine Zeichenfolge sein würde, und so würde ich weiß nicht, welche Funktion läuft bis zur Laufzeit.

Es wird gut funktionieren - Verwendung __import__ builtin oder, wenn Sie hat sehr komplexes Layout, imp Modul Ihr Skript zu importieren. Und dann können Sie die Funktion von module.__dict__[funcname] zum Beispiel erhalten.

ein Modul importieren (wie in anderen Antworten erklärt) ist auf jeden Fall der Reiniger Weg, dies zu tun, aber wenn aus irgendeinem Grund nicht funktioniert, solange Sie nicht etwas zu seltsam tun können Sie a href verwenden < = "http://docs.python.org/py3k/library/functions.html#exec" rel = "nofollow noreferrer"> exec . Es läuft im Grunde den Inhalt einer anderen Datei, als ob es in der aktuellen Datei an dem Punkt aufgenommen wurde, wo exec genannt wird. Es ist die nächste Sache, Python hat zu einer source Aussage der Art in vielen Schalen enthalten. Als absolutes Minimum, sollte in etwa so funktionieren:

exec(open(filename).read(None))

Wie wäre das?

function do_thing_one():
   pass

function do_thing_two():
   pass

dispatch = { "one" : do_thing_one,
             "two" : do_thing_two,
           }

# do something to get your string from the command line (optparse, argv, whatever)
# and put it in variable "mystring"

# do top thing
f = dispatch[mystring]
f()
# do bottom thing
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top