Übertragung von Variablen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
maxwer
User
Beiträge: 16
Registriert: Mittwoch 20. Januar 2021, 11:46

Code: Alles auswählen

def main():
    with Path(filepath).open("rb") as fp:
        image_binary = fp.read()
        response = requests.post(
            PINATA_BASE_URL + endpoint,
            files={"file": (filename, image_binary)},
            headers=headers,
        )
        ipfs_hash = response.json()["IpfsHash"]
        print(response.json())
        image_uri = "{}{}".format(first_part_image_uri, ipfs_hash)
        print(image_uri)

        # Aufruf Funktion create_image_uri_meta_file
        simple_collectible = SimpleCollectible[len(SimpleCollectible) - 1]
        token_id = simple_collectible.tokenCounter()
        create_image_uri_meta_file(response, token_id)
    return image_uri
Ich möchte die Variable image_uri in ein anderes Python Skript übertragen.
Der bisher beste Versuch ist mir gelungen mit:

Code: Alles auswählen

from scripts.upload_to_pinata import main

image_uri = main()
image_uri_from_upload = image_uri
Jedoch entsteht hier die Problematik das ich alle Befehle und sonstige Variablen von main mit übernehme. Ich möchte aber NUR die eine Variable übernehmen.
Hat jemand eine Lösung, Idee oder Vorschlag wie ich nur die eine Variable zwischen den Python-Skripten übertragen kann?
Hier ist noch ein Teil des Skripts indem die Variable eingefügt werden soll.

Code: Alles auswählen

#!/usr/bin/python3
from brownie import SimpleCollectible, accounts, network, config
from scripts.upload_to_pinata import main

# image_uri = main()
# image_uri_from_upload = image_uri


image_uri_from_upload = ""


def main():
Im Voraus vielen Dank für die Unterstützung.
Benutzeravatar
sparrow
User
Beiträge: 4540
Registriert: Freitag 17. April 2009, 10:28

Du importierst eine Funktion mit dem Namen main aus einem anderen Modul.
Dann rufst du die Funktion auf und bindest das Ergebnis an den Namen image_uri.
Da wird nichts anderes übernommen.

Warum du allerdings die Umweg gehst, sie erst an den Namen "image_uri" zu binden und sie anschließend an "image_uri_from_upload" zu binden ist mir etwas schleierhaft.
Benutzeravatar
__blackjack__
User
Beiträge: 14078
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@maxwer: `main()` ist ein bisschen komisch als Name für diese Funktion.

`filepath`, `endpoint`, `filename`, `headers`, `first_part_image_uri`, `SimpleCollectible` kommen in der Funktion irgendwie aus dem Nichts. Funktion und Methoden bekommen alles was sie ausser Konstanten benötigen als Argument(e) übergeben.

In dem ``with`` muss eigentlich nur die erste Zeile des Blocks enthalten sein, denn danach wird mit dem Dateiobjekt ja nichts mehr gemacht.

Aber dieser Fall dort geht noch einfacher weil `Path` eine Methode hat um die Daten einzulesen.

`SimpleCollectible` ist vom Namen wie eine Klasse geschrieben, wird aber wie ein Objekt verwendet.

``SimpleCollectible[len(SimpleCollectible) - 1]`` ist sehr wahrscheinlich umständlich geschrieben für ``SimpleCollectible[-1]``.

Die Antwort vom Webserver sollte man in der Regel auf den HTTP-Status prüfen.

Zwischenstand (untetestet):

Code: Alles auswählen

#
# TODO Der Name `main()` taugt hier nicht.
#
def main(
    file_path,
    endpoint,
    filename,
    headers,
    first_part_image_uri,
    simple_collectibles,
):
    response = requests.post(
        PINATA_BASE_URL + endpoint,
        files={"file": (filename, Path(file_path).read_bytes())},
        headers=headers,
    )
    response.raise_for_status()

    create_image_uri_meta_file(
        response, simple_collectibles[-1].tokenCounter()
    )

    ipfs_hash = response.json()["IpfsHash"]
    return f"{first_part_image_uri}{ipfs_hash}"
Im anderen Modul sieht es dann problematisch aus, das `image_uri_from_upload` ausserhalb einer Funktion als leere Zeichenkette definiert wird. Variablen haben da nichts zu suchen und als Konstante macht der Wert so keinen Sinn, und müsste dann auch KOMPLETT_GROSS geschrieben werden.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Sirius3
User
Beiträge: 18279
Registriert: Sonntag 21. Oktober 2012, 17:20

Das "übertragen von Variablen" hört sich seltsam an. Ein Pythonprogramm besteht aus Funktionen, die Rückgabewerte haben. Es werden also Werte "übertragen" indem man Funktionen aufruft.
Und natürlich muß in Deinem Beispiel die Funktion main ausgeführt werden. Oder was meinst Du mit "sonstige Variablen übernehmen"?
maxwer
User
Beiträge: 16
Registriert: Mittwoch 20. Januar 2021, 11:46

@sparrow: Wie könnte ich den den Wert image_uri an etwas binden um auch nur diesen Inhalt wieder zu geben? Das mit der Bindung von "image_uri" zu "image_uri_from_upload" ist ungünstig gewählt.

@__blackjack__: Bei `filepath`, `endpoint`, `filename`, `headers`, `first_part_image_uri`, `SimpleCollectible` handelt es sich um Teile von URL Links. Simple Collectible ist ein Smart Contract der wiederum selbst Funktionen enthält. filepath ist ein Dateipfad und filename ein Dateiname. Bei headers handelt es sich um importierte Schlüssel.

``SimpleCollectible[len(SimpleCollectible) - 1]`` ist sehr wahrscheinlich umständlich geschrieben für ``SimpleCollectible[-1]``. = korrekt

`image_uri_from_upload` ist als leere Zeichenkette definiert da ich bisher den erstellten Link aus (first_part_image_uri und ipfs_hash) manuell übertragen habe. Ich bedanke mich schon mal für den bereitgestellten Code. Wie schaffe ich es aber den Inhalte von image_uri in einer anderen Funktion in einem anderen Skript (im gleichen Verzeichnis) wieder zu verwenden?

@sirius3: Ich rufe die Funktion main auf um mir den Wert image_uri übergeben zu lassen. Das Problem ist, dass dabei auch alle anderen Funktionsinhalte mitübergeben werden und die hinterlegten Befehle noch mal ausgeführt werden.

Ich möchte wirklich nur den Inhalt von image_uri in einer anderen Funktion welche wiederum in einem anderen Skript ist verwenden. Es soll nur image_uri exportiert werden.
Benutzeravatar
__blackjack__
User
Beiträge: 14078
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@maxwer: Was das alles ist, ist nahezu egal, die Frage ist ob das Konstanten sind, und falls nicht, und das wird in vielen Fällen so sein, darf das nicht einfach so magisch aus der Umgebung genommen werden, weil Variablen da nichts zu suchen haben. Genau so wie Code der nicht Konstanten, Funktionen, und Klassen definiert, nicht einfach auf Modulebene stehen darf. Dann passiert nämlich das was Du ja anscheinend nicht willst: der Code wird beim importieren ausgeführt.

`image_uri_from_upload` auch an der falschen Stelle definiert. Das hat nichts ausserhalb einer Funktion zu suchen. Siehe den vorherigen Absatz.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Sirius3
User
Beiträge: 18279
Registriert: Sonntag 21. Oktober 2012, 17:20

@maxwer: Du rufst also `main` an anderer Stelle nochmal auf. Ich vermute mal in `scripts.upload_to_pinata` steht ein main-Aufruf, ohne dass er durch ein if-__name__-Konstrukt gekoppelt ist.
maxwer
User
Beiträge: 16
Registriert: Mittwoch 20. Januar 2021, 11:46

@__blackjack__ Tatsächlich handelt es sich bei fast all diesen Angaben um Konstanten, mit Ausnahme vom `filename`. Als Quereinsteiger habe ich echt nicht erwartete dass das exportieren eines bestimmten Inhalts solche Probleme verursacht.

@sirius3 die Funktion `main` ist im Skript "upload_to_pinata.py" definiert. Der Funktionsaufruf von `main` findet dann im Skript "create_collectible.py" statt. der Inhalt von "image_uri" der sich bei jeder Ausführung ändert, soll dann dabei von "upload_to_pinata.py" nach "create_collectible.py" übertragen werden.
Sirius3
User
Beiträge: 18279
Registriert: Sonntag 21. Oktober 2012, 17:20

Deine Bezeichnung "skript" ist falsch, wenn Du Module importierst. Und dieses falsche Verständnis hängt wahrscheinlich auch mit den Problemen zusammen, die Du siehst. Module sind Sammlungen von Funktionen, und man keine Variable von einem Modul ins andere übertragen, sondern es gibt nur Funktionsaufrufe mit Rückgabewerten.

Ohne den gesamten relevanten Code zu sehen, können wir aber nicht konkret weiterhelfen.
Benutzeravatar
__blackjack__
User
Beiträge: 14078
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@maxwer: Wenn es Konstanten sind, sollten sie KOMPLETT_GROSS geschrieben sein, damit der Leser erkennt, dass es Konstanten sind. Wobei eventuell noch die Frage ist, ob es wirklich Konstanten sein sollten. Denn wenn Du da ein Programm mit mehreren Modulen hast und in jedem irgendwelche Konstanten die sich auf externe Ressourcen beziehen, wird das schnell unübersichtlich/unflexibel.

„Inhalte exportieren“ gibt es so nicht. Was soll das sein? Und auch Inhalte von Skript/Modul a nach b übertragen ist nichts was man macht, beziehungsweise ist mir nicht mal klar was das bedeuten soll. Man hat Funktionen und Objekte mit Methoden und Daten werden bei Aufrufen als Argumente und Rückgabewerte zwischen diesen ausgetauscht. In welchen Modulen die Funktionen/Klassen definiert sind, spielt dabei nicht so wirklich eine Rolle, denn der Austausch zwischen Funktionen im gleichen Modul funktioniert genau so wie der Austausch zwischen Funktionen aus verschiedenen Modulen. Einzig wie man an die Funktion kommt, also ob sie im gleichen Modul einfach da ist, oder ob man dafür ein anderes Modul importieren muss, unterscheidet sich.

Das Grundgerüst für ein Programm/Skript sieht so aus:

Code: Alles auswählen

#!/usr/bin/env python3
#
# Hier darf nur Code stehen der Konstanten, Funktionen, und Klassen definiert.
#

def main():
    ...


if __name__ == "__main__":
    main()
Bei Modulen kann man die erste Zeile weg lassen und das hinter dem Kommentar. Und der Kommentar gilt weiterhin! Da darf nichts stehen ausser Code der Konstanten, Funktionen, und Klassen definiert.

Manchmal, aber eher selten, hat man da auch bedingten Code, der zum Beispiel zwischen der Plattform unterscheidet unter der das läuft, oder den Aufruf von Hilfsfunktionen um Werte für Konstanten zu erstellen. Aber da darf nichts stehen was irgendwelche ”drastischen” Effekte hat, wie Verbindungen zu Datenbanken oder zu Webseiten aufbauen, oder Benutzerein-/ausgaben macht. Man muss jedes Programm/Skript/Modul ohne Seiteneffekte importieren können.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
maxwer
User
Beiträge: 16
Registriert: Mittwoch 20. Januar 2021, 11:46

@sirius3 und @__blackjack__: Danke für eure Lösungsvorschläge und Tipps. Ich konnte das Problem dadurch lösen.
Antworten