Daten erzeugen und im script speichern

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
hawiwo
User
Beiträge: 6
Registriert: Dienstag 16. Juni 2020, 19:17

Hi,
ich bin python neuling und will mal testen, was so alles geht.

Z.B. in einem bash script hatte ich mal daten erzeugt und an das script selbst unten angehängt.

ich hab's nicht mehr bzw. nicht mehr genau aufm Schirm wie das genau war bzw. wo ich's hin hab.
Und googletaugliche Stichworte... :roll:
irgendwie so...:
--------------------------------------------------------------------------------------------------------------------------------------------------------
#!/bin/bash
script=$(readlink -f "$0")
diskfreespace=$(df -h | awk ....)
echo ${diskfreespace >> ${script}
while read -r line
do
echo "$line"
done < EOF
#-----------------------------------------------------
line1
line2
....
-----------------------------------------------------------------------------------------------------------------------------------------------------------
das ist natürlich schnell zusammengeschusteter Pseudo-Code zu Verdeutlichung!
Wie geht das in Python?
Benutzeravatar
sparrow
User
Beiträge: 4165
Registriert: Freitag 17. April 2009, 10:28

Für die Information über die Verwendung von Festplattenspeicher hat Python eine Funktion in dem Modul shutil.
Das Öffnen und Bearbeiten von Dateien wird im offiziellen Tutorial ausführlich beschrieben.
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich würde in Frage stellen, was das soll. Wieso willst du selbst modifizierendem Code schreiben? Das ist extrem ungewöhnlich. Auch bei Shell Skripten. Stattdessen speichert man sowas in eigenen Dateien.
hawiwo
User
Beiträge: 6
Registriert: Dienstag 16. Juni 2020, 19:17

__deets__ hat geschrieben: Mittwoch 27. April 2022, 08:28 Ich würde in Frage stellen, was das soll. Wieso willst du selbst modifizierendem Code schreiben? Das ist extrem ungewöhnlich. Auch bei Shell Skripten. Stattdessen speichert man sowas in eigenen Dateien.
bei häufigem Wechseln des Systems bzw. beim weitergeben ist eben eine 1-Dateilösung Fehlerunanfälliger
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Und wenn du deinen Code veraendern willst, aber lauter Skripte im Umlauf sind mit jeweils eigenen Datenbestaenden, dann ist das fehleranfaelliger. Ich kenne kein einziges Beispiel aus der Praxis, in der so vorgegangen wird. Weder mit Shell-Skripten, noch mit Python.

Du kannst mit Python grundsaetzlich genauso auf die eigene Datei zugreifen, und du kannst dir wahlweise ein eigenes Format innerhalb von Kommtaren ueberlegen, damit du die Datenhaltung vom Parser trennst. Oder du modifizierst eine Variable im Code, aber das ist weniger robust, weil ein Syntaxfehler sofort einen Absturz nach sich zieht, ohne das dein Programm da eine Chance hat, auch nur einen vernuenftigen Fehler zu vermelden.
Benutzeravatar
sparrow
User
Beiträge: 4165
Registriert: Freitag 17. April 2009, 10:28

Ich sehe auch den Vorteil nicht, dass das in irgend einer Weise weniger fehleranfällig ist.
Wenn ich das Script auf einen anderen Rechner kopiere, sind die Ergebnisse, die vorher auf einem anderen Rechner ermittelt wurden und nun da irgendwie wnagefügt wurden, ja ungültig weil nicht zum System passend.
nezzcarth
User
Beiträge: 1632
Registriert: Samstag 16. April 2011, 12:47

In Shell-Skripten kann man Daten in einem Here-Doc hinterlegen (klassisches, aber kritisch gesehenes Beispiel: Shar-Archive). Perl und Ruby haben Sprachfeatures, um Datensegemente an das Ende der Datei anzufügen (__DATA__/__END__). All die Features sind aber eigentlich nur für den lesenden Zugriff gedacht. Wenn man da auch schreiben möchte, muss man ziemlich fummeln. Python hat solche Features nicht. (Meiner Meinung nach zum Glück.) Schreib die Daten in eine separate Datei. Das ist die sauberste Lösung.
hawiwo hat geschrieben: Mittwoch 27. April 2022, 04:24 ich hab's nicht mehr bzw. nicht mehr genau aufm Schirm wie das genau war bzw. wo ich's hin hab.
In Bash habe ich das mit einem Here-Doc hinbekommen, als Proof-of-Concept. Das ist aber extremes Gehacke und ich würde es nicht empfehlen.
Zuletzt geändert von nezzcarth am Mittwoch 27. April 2022, 12:28, insgesamt 3-mal geändert.
hawiwo
User
Beiträge: 6
Registriert: Dienstag 16. Juni 2020, 19:17

ok. Danke für die Antworten.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@hawiwo: Das es keine so gute Idee ist wurde ja schon geschrieben, ich wollte aber trotzdem mal spasseshalber das Shell-Skript in Python umsetzen.

Es gibt keine Here-Docs in Python wie im Beispiel und von nezzcarth auch beschrieben und in Python muss die gesamte Datei syntaktisch korrektes Python sein. Also muss man die Daten entweder als Kommentarzeilen anfügen, oder als Zeilen mit literalen Werten. Letzteres hat den Vorteil, das ein Datum in Form einer literalen Zeichenkette alles mögliche, inklusive Zeilenumbrüchen enthalten kann und sogar verschachtelte Datenstrukturen mit den Grunddatentypen möglich sind, wenn man die `repr()`-Variante an die Datei anhängt.

Den ``df``-Aufruf kann man sich mit dem `psutil`-Modul in Python nachprogrammieren wenn man nicht das externe Programm mit `subprocess` aufrufen will.

Die Daten sind über einen Kommentar vom Rest des Skriptes abgetrennt bis zu dem das Programm bei der Ausgabe der Daten die Programmzeilen überliest:

Code: Alles auswählen

#!/usr/bin/env python3
from ast import literal_eval
from pathlib import Path

from psutil import disk_partitions, disk_usage

SELF_FILE_PATH = Path(__file__)


def format_size(value):
    power = 1024
    for unit in ["", "K", "M", "G", "T"]:
        if value < power:
            break
        value /= power

    return f"{value:.1f}{unit}"


def main():
    with SELF_FILE_PATH.open("a", encoding="utf-8") as self_file:
        for partition in disk_partitions():
            usage = disk_usage(partition.mountpoint)
            #
            # Do whatever ``awk ....`` in the example was supposed to do here.
            #
            text = (
                f"{usage.percent:4.1f}%\t{format_size(usage.free)}"
                f"\t{partition.mountpoint}"
            )
            #
            # Need to write the `repr()` form of `text` because the file must be
            # a syntactycally valid Python source file.
            #
            self_file.write(f"{text!r}\n")

    with SELF_FILE_PATH.open("r", encoding="utf-8") as lines:
        #
        # Skip lines up to and including special comment.
        #
        for line in lines:
            if line.startswith("# DATA STARTS HERE -"):
                break

        for line in lines:
            print(literal_eval(line))


if __name__ == "__main__":
    main()

# DATA STARTS HERE ------------------------------------------------------
Wie im gezeigten Shell-Skript werden hier bei jedem Lauf immer mehr Daten angehängt. Wenn man die Daten ”überschreiben” will, wird es etwas komplizierter. Das wäre es aber auch im Shell-Skript.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Antworten