Frage

Ich schreibe ein Programm, das genetische Techniken verwendet Gleichungen zu entwickeln. Ich möchte in der Lage, die Funktion ‚mainfunc‘ zur Parallel Python ‚Senden‘ Funktion zu unterbreiten. Die Funktion ‚mainfunc‘ nennt zwei oder drei Methoden in der Utility-Klasse definiert. Sie instanziiert andere Klassen und rufen verschiedene Methoden. Ich denke, was ich will, das alles in einem Namensraum ist. Also habe ich einige instanziiert habe der Klassen innerhalb der Funktion ‚mainfunc‘ (vielleicht sollte es sein). Ich nenne die Utility-Methode ‚erzeugen ()‘. Wenn wir es in der Kette der Ausführung folgen es würde alle Klassen und Methoden im Code einzubeziehen.

Nun werden die Gleichungen in einem Baum gespeichert. Jedes Mal, wenn ein Baum erzeugt wird, mutiert oder Quer gezüchtet, müssen die Knoten einen neuen Schlüssel gegeben werden, damit sie aus einem Wörterbuch Attribut des Baumes zugegriffen werden kann. Die Klasse 'KeySeq' erzeugt diese Tasten.

In Parallel Python, ich werde mehrere Instanzen von ‚mainfunc‘ zur ‚submit‘ Funktion von PP senden. Jeder muss in der Lage, den Zugang ‚KeySeq‘. Es wäre schön, wenn sie alle die gleiche Instanz von KeySeq zugegriffen, so dass keiner der Knoten auf den zurückgegebenen Bäumen den gleichen Schlüssel hatte, aber ich konnte umgehen, dass, wenn notwendig.

Also: meine Frage ist, über alles in mainfunc Füllung. Vielen Dank (Edit) Wenn ich nicht alles in mainfunc enthalten, muss ich versuchen, PP zu sagen, über abhängige Funktionen, etc. durch verschiedene Argumente an verschiedenen Orten vorbei. Ich versuche, das zu vermeiden.

(Ende Edit) wenn ks.next () innerhalb der genannt wird ‚erzeugen () Funktion, gibt es den Fehler 'Nameerror: global name 'ks' ist nicht definiert'

class KeySeq:
    "Iterator to produce sequential \
    integers for keys in dict"
    def __init__(self, data = 0):
        self.data = data
    def __iter__(self):
        return self
    def next(self):
        self.data = self.data + 1
        return self.data
class One:
    'some code'
class Two:
    'some code'
class Three:
    'some code'
class Utilities:
    def generate(x):
        '___________'
    def obfiscate(y):
        '___________'
    def ruminate(z):
        '__________'


def mainfunc(z):
    ks = KeySeq()
    one = One()
    two = Two()
    three = Three()
    utilities = Utilities()
    list_of_interest = utilities.generate(5)
    return list_of_interest

result = mainfunc(params)
War es hilfreich?

Lösung

Wenn Sie alle Instanzen von mainfunc wollen das gleiche KeySeq Objekt verwenden möchten, können Sie den Standard-Parameterwert Trick verwenden:

def mainfunc(ks=KeySeq()):
   key = ks.next()

Solange Sie nicht wirklich in einem Wert von ks passieren, werden alle Anrufe zu mainfunc wird die Instanz von KeySeq verwenden, die erstellt wurde, wenn die Funktion definiert wurde.

Hier ist der Grund, falls Sie nicht wissen: Eine Funktion ist ein Objekt. Es hat Attribute. Eines ihrer Attribute wird func_defaults genannt; es ist ein Tupel die Standardwerte für alle Argumente in seiner Signatur enthält, die Standardwerte haben. Wenn Sie eine Funktion aufrufen und bieten keinen Wert für ein Argument, das eine Standard hat, ruft die Funktion den Wert von func_defaults. Also, wenn Sie mainfunc aufrufen, ohne einen Wert für ks bereitstellt, es wird die KeySeq() Instanz aus dem func_defaults Tupels. Welche, für diese Instanz von mainfunc, ist immer die gleiche KeySeq Instanz.

Nun, sagen Sie, dass du gehst zu senden „mehrere Instanzen von mainfunc auf die submit Funktion von PP.“ Meinst du wirklich mehrere Instanzen? Wenn ja, der Mechanismus ich beschreibe wird nicht funktionieren.

Aber es ist schwierig, mehrere Instanzen einer Funktion zu erstellen (und den Code, den Sie geschrieben haben nicht). Zum Beispiel ist diese Funktion eine neue Instanz von g Rückkehr jedes Mal, es heißt:

>>> def f():
        def g(x=[]):
            return x
        return g
>>> g1 = f()
>>> g2 = f()
>>> g1().append('a')
>>> g2().append('b')
>>> g1()
['a']
>>> g2()
['b']

Wenn ich g() ohne Argument aufrufen, gibt es den Standardwert (zunächst eine leere Liste) aus seinem func_defaults Tupels. Da g1 und g2 verschiedene Instanzen der g Funktion sind, deren Standardwert für das x Argument auch eine andere Instanz, die die oben zeigt.

Wenn Sie möchten, dass dies noch deutlicher machen, als eine knifflige Nebenwirkung von Standardwerten, hier ist eine andere Art und Weise, es zu tun:

def mainfunc ():       wenn nicht hasattr (mainfunc "ks"):           setattr (mainfunc "ks", KeySeq ())       key = mainfunc.ks.next ()

Schließlich ein super wichtiger Punkt, dass der Code, den Sie geschrieben haben übersehen: Wenn du gehst, um parallele Verarbeitung auf gemeinsam genutzte Daten tun, wird der Code, dass berührt, dass Datenanforderungen Verriegelung zu implementieren. Schauen Sie sich das callback.py Beispiel in der Parallel-Python-Dokumentation und sehen, wie Verriegelung in der Sum Klasse verwendet wird und warum.

Andere Tipps

Es ist in Ordnung Ihr Programm auf diese Weise zu strukturieren. Viele Kommandozeilenprogramme folgen dem gleichen Muster:

#imports, utilities, other functions

def main(arg):
    #...

if __name__ == '__main__':
    import sys
    main(sys.argv[1])

Auf diese Weise können die main Funktion von einem anderen Modul durch den Import aufrufen können, oder Sie können es von der Kommandozeile ausgeführt werden.

Ihr Konzept von Klassen in Python ist nicht stichhaltig, denke ich. Vielleicht wäre es eine gute Idee, die Grundlagen zu überprüfen. Dieser Link wird helfen.

Python Basics - Klassen

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top