42 Stimmen

Wie kann man in Python Variablen in verschiedenen Skripten gemeinsam nutzen?

Das Folgende funktioniert nicht

ein.py

import shared
shared.value = 'Hello'
raw_input('A cheap way to keep process alive..')

zwei.py

import shared
print shared.value

auf zwei Befehlszeilen als ausgeführt:

>>python one.py
>>python two.py

(der zweite erhält zu Recht einen Attributfehler).

Gibt es eine Möglichkeit, dies zu erreichen, d.h. eine Variable zwischen zwei Skripten zu teilen?

7 Stimmen

Meinen Sie, dass Sie einen Wert in zwei völlig getrennten Python-Sitzungen gemeinsam nutzen wollen? Wenn ja, ist das nicht möglich, indem Sie einfach einen Wert in einem gemeinsamen Modul setzen.

0 Stimmen

Ich danke Ihnen. Im Moment bin ich dabei, ein drittes Modul zu erstellen, das beide importiert, so dass alles in der gleichen Sitzung geschieht. Die Pickle-Lösung funktioniert nicht ganz für mich, weil ich eine threading.Condition()-Variable in einem Modul setzen wollte (die wegen der impliziten Sperre nicht gepickt werden kann) und sie von beiden Sitzungen aus verwenden wollte. Und jetzt, wo ich darüber nachdenke, ist die Möglichkeit, die Variable gemeinsam zu nutzen, wahrscheinlich das geringste meiner Probleme, da ich nicht glaube, dass der Zustand in der Bedingungsvariable gemeinsam genutzt werden wird.

0 Stimmen

Ich bin auf diese Frage gekommen, als ich das gleiche Problem hatte. Dann habe ich über Steckdosen gelesen. Warum sollte man sie nicht verwenden?

6voto

Benyamin Jafari Punkte 20585

Teilen Sie eine dynamische Variable durch Redis :

skript_eins.py

from redis import Redis
from time import sleep

cli = Redis('localhost')
shared_var = 1

while True:
   cli.set('share_place', shared_var)
   shared_var += 1
   sleep(1)

Ejecutar skript_eins in einem Terminal (einem Prozess):

$ python script_one.py

skript_zwei.py

from redis import Redis
from time import sleep

cli = Redis('localhost')

while True:
    print(int(cli.get('share_place')))
    sleep(1)

Ejecutar skript_zwei in einem anderen Terminal (einem anderen Prozess):

$ python script_two.py

Aus:

1
2
3
4
5
...

Abhängigkeiten:

$ pip install redis
$ apt-get install redis-server

0 Stimmen

Was wäre, wenn Sie die Redis-Verbindungspool zwischen zwei Kommandozeilenprozessen?

4voto

UsAaR33 Punkte 3376

Ich würde empfehlen, dass Sie die Multiprozessorbetrieb Modul. Sie können nicht zwei Skripte von der Befehlszeile aus ausführen, aber Sie können zwei separate Prozesse leicht miteinander sprechen lassen.

Aus den Beispielen des Arztes:

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print q.get()    # prints "[42, None, 'hello']"
    p.join()

0 Stimmen

Ich habe gerade gebucht diese Antwort , bei dem zwei Skripte von der Befehlszeile aus ausgeführt werden, und verwenden multiprocessing um Variablen zu teilen.

3voto

Dave Kirby Punkte 24272

Sie müssen die Variable in einer Art dauerhafter Datei speichern. Es gibt verschiedene Module, die dies ermöglichen, je nachdem, was Sie genau benötigen.

Die Module pickle und cPickle können die meisten Python-Objekte in Dateien speichern und laden.

Das Modul shelve kann Python-Objekte in einer wörterbuchähnlichen Struktur speichern (unter Verwendung von pickle im Hintergrund).

Die Module dbm/bsddb/dbhash/gdm können String-Variablen in einer wörterbuchartigen Struktur speichern.

Das Modul sqlite3 kann Daten in einer leichtgewichtigen SQL-Datenbank speichern.

Das größte Problem bei den meisten von ihnen ist, dass sie nicht zwischen verschiedenen Prozessen synchronisiert sind - wenn ein Prozess einen Wert liest, während ein anderer in den Datenspeicher schreibt, kann es zu falschen Daten oder Datenbeschädigungen kommen. Um dies zu umgehen, müssen Sie Ihren eigenen Dateisperrmechanismus schreiben oder eine vollwertige Datenbank verwenden.

3voto

onofricamila Punkte 730

Wenn Sie wollen gemeinsame Daten lesen und ändern zwischen 2 Skripten, die separat laufen, wäre eine gute Lösung, die Vorteile des Python-Multiprocessing-Moduls zu nutzen und eine Pipe() oder eine Warteschlange() (siehe Unterschiede aquí ). Auf diese Weise können Sie Skripte synchronisieren und Probleme in Bezug auf Gleichzeitigkeit und globale Variablen vermeiden (z. B. was passiert, wenn beide Skripte gleichzeitig eine Variable ändern wollen).

Das Beste an der Verwendung von Pipes/Queues ist, dass man Python-Objekte durch sie hindurchleiten kann.

Außerdem gibt es Methoden, um das Warten auf Daten zu vermeiden, wenn diese noch nicht übergeben wurden ( Warteschlange.leer() y pipeConn.poll() ).

Nachstehend finden Sie ein Beispiel für die Verwendung von Queue():

    # main.py
    from multiprocessing import Process, Queue
    from stage1 import Stage1
    from stage2 import Stage2

    s1= Stage1()
    s2= Stage2()

    # S1 to S2 communication
    queueS1 = Queue()  # s1.stage1() writes to queueS1

    # S2 to S1 communication
    queueS2 = Queue()  # s2.stage2() writes to queueS2

    # start s2 as another process
    s2 = Process(target=s2.stage2, args=(queueS1, queueS2))
    s2.daemon = True
    s2.start()     # Launch the stage2 process

    s1.stage1(queueS1, queueS2) # start sending stuff from s1 to s2 
    s2.join() # wait till s2 daemon finishes

    # stage1.py
    import time
    import random

    class Stage1:

      def stage1(self, queueS1, queueS2):
        print("stage1")
        lala = []
        lis = [1, 2, 3, 4, 5]
        for i in range(len(lis)):
          # to avoid unnecessary waiting
          if not queueS2.empty():
            msg = queueS2.get()    # get msg from s2
            print("! ! ! stage1 RECEIVED from s2:", msg)
            lala = [6, 7, 8] # now that a msg was received, further msgs will be different
          time.sleep(1) # work
          random.shuffle(lis)
          queueS1.put(lis + lala)             
        queueS1.put('s1 is DONE')

    # stage2.py
    import time

    class Stage2:

      def stage2(self, queueS1, queueS2):
        print("stage2")
        while True:
            msg = queueS1.get()    # wait till there is a msg from s1
            print("- - - stage2 RECEIVED from s1:", msg)
            if msg == 's1 is DONE ':
                break # ends loop
            time.sleep(1) # work
            queueS2.put("update lists")             

EDIT : Ich habe gerade herausgefunden, dass man mit queue.get(False) um eine Blockierung beim Datenempfang zu vermeiden. Auf diese Weise muss nicht erst geprüft werden, ob die Warteschlange leer ist. Dies ist nicht möglich, wenn Sie Pipes verwenden.

1voto

David Brunelle Punkte 6348

Verwenden Sie Textdateien oder Umgebungsvariablen. Da die beiden getrennt voneinander laufen, können Sie nicht wirklich tun, was Sie versuchen.

0 Stimmen

Die Verwendung einer Textdatei ist eine gute Idee, aber die Verwendung einer Umgebungsvariablen funktioniert nicht zwischen zwei getrennten Prozessen oder Kindprozessen (z. B. zwei Terminals oder zwei Python-Skriptdateien). Hier ist eine betreffende Stelle .

0 Stimmen

Die Verwendung einer Textdatei kann jedoch zu Problemen führen, wenn zufällige Lese- und Schreibvorgänge gleichzeitig stattfinden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X