Seite 1 von 1
dict und dict zusammenführen...
Verfasst: Sonntag 3. Mai 2009, 04:39
von stuhlbein
Hallo!
Ich weiss dass ich diese Frage bereits im IRC channel mal gestellt habe, allerdings weiss ich wirklich nicht weiter hier.
Momentan nutz ich folgendes Skript um die datei
/etc/passwd in Lesbarem Format wiederzugeben:
Code: Alles auswählen
import sys
class PasswdDumper:
def readfile(self, f):
try:
data = open(f).read()
return data
except IOError, w:
sys.stderr.write("Error Opening \"%s\" for reading: %s\n" % (f, w))
sys.exit(1)
def __init__(self, passwd_file="/etc/passwd", delim="="):
data = self.readfile(passwd_file)
for line in data.split("\n"):
if line not in (None, ''):
sb = line.split(':')
print("USER %s %s" % (delim, sb[0]))
print("PASSWD %s %s" % (delim, sb[1]))
print("USER_ID %s %s" % (delim, sb[2]))
print("GROUP_ID %s %s" % (delim, sb[3]))
print("INFORMATION %s %s" % (delim, sb[4]))
print("HOME %s %s" % (delim, sb[5]))
print("SHELL %s %s" % (delim, sb[6]))
print("---------------------------\n")
if __name__ == '__main__':
if len(sys.argv) > 1:
PasswdDumper(sys.argv[1])
else:
PasswdDumper()
Geplant war aber eigentlich mal, dass am ende ein Dict mit den werten der /etc/passwort "generiert" wird.
Aber hier fängt nun das eigentliche Problem an...: Ich weiss nicht, wie ich zwei Dicts zusammenführen soll, da diese ja notwendigerweise im Skript entstehen würden!
ps: ja, ich bin neu (im Forum

)
greetz, bitfish
Verfasst: Sonntag 3. Mai 2009, 07:17
von BlackJack
@Bitfish: Wo würden da zwangsläufig zwei `dict`\s entstehen!?
Anmerkungen zum Skript: Was soll die Klasse? Die ist völlig überflüssig -- das sind einfach nur zwei Funktionen.
Dateien, die man öffnet, sollte man auch explizit wieder schliessen oder die ``with``-Anweisung verwenden. Und in Funktionen/Methoden sollte man das Programm nicht einfach mit `sys.exit()` beenden. Damit kann man die Funktion schlechter wiederverwenden und schlechter testen.
In der Regel versucht man es zu vermeiden Textdateien komplett in den Speicher zu lesen, wenn man die Zeilen einzeln verarbeiten möchte. Dateiobjekte sind nämlich "iterables" über die Zeilen.
Wie soll ein `None` beim `split()`\en entstehen können? Was ist mit Leerzeilen die nicht ganz leer sind, sondern nur "whitespace"-Zeichen enthalten?
Wofür steht die Abkürzung `sb`?
Wenn man sich die ``print``\s anschaut und das Du da einen Index manuell in jeder Zeile "hochgezählt hinschreibst" legt die Verwendung einer Schleife nahe.
Code: Alles auswählen
from __future__ import with_statement
import sys
FIELD_NAMES = ['USER', 'PASSWD', 'USER_ID', 'GROUP_ID',
'INFORMATION', 'HOME', 'SHELL']
MAX_FIELDNAME_LENGTH = max(map(len, FIELD_NAMES))
def iter_passwd(filename='/etc/passwd'):
with open(filename, 'r') as lines:
for line in (s.sstrip() for s in lines):
if line:
yield line.split(':')
def dump_passwd(rows, delimiter='='):
for row in rows:
for name, value in zip(FIELD_NAMES, row):
print '%-*s %s %s' % (MAX_FIELDNAME_LENGTH, name, delimiter, value)
print '-' * 30
def main():
try:
rows = iter_passwd(sys.argv[1]) if len(sys.argv) > 1 else iter_passwd()
except IOError, error:
sys.stderr.write('Error: %s\n' % error)
else:
dump_passwd(rows)
if __name__ == "__main__":
main()
Verfasst: Sonntag 3. Mai 2009, 09:32
von helduel
Moin,
das pwd-Modul parst die passwd bereits und kann eine Liste mit allen Einträgen zurückgeben. Allerdings ist es nicht so flexibel: Man kann keine passwd angeben (zumindest weiß ich nicht, wie). Außerdem liest es auch alle Daten in den Speicher. Wobei man das IMO bei der passwd auch vernachlässigen kann.
Gruß,
Manuel
Verfasst: Sonntag 3. Mai 2009, 11:10
von Leonidas
helduel hat geschrieben:Allerdings ist es nicht so flexibel: Man kann keine passwd angeben (zumindest weiß ich nicht, wie).
Mir ist kein System bekannt dass seine ``passwd`` nicht in ``/etc/passwd`` hat.
Verfasst: Sonntag 3. Mai 2009, 12:14
von Darii
helduel hat geschrieben:das pwd-Modul parst die passwd bereits und kann eine Liste mit allen Einträgen zurückgeben. Allerdings ist es nicht so flexibel: Man kann keine passwd angeben (zumindest weiß ich nicht, wie).
Die braucht man auch nicht angeben. Das Modul nutzt die Funktionen aus der <pwd.h> und die funktionieren zuverlässig auf jeden System. Unter OSX beispielsweise stehen die Benutzer nicht in der /etc/passwd (es gibt die Datei zwar die wird aber nur im Single-User-Modus beachtet), das läuft über einen Open-Directory-Dienst. Da kommt man mit dem Auslesen von irgendwelchen Textdateien nicht weit.
Verfasst: Sonntag 3. Mai 2009, 13:20
von helduel
Leonidas hat geschrieben:helduel hat geschrieben:Allerdings ist es nicht so flexibel: Man kann keine passwd angeben (zumindest weiß ich nicht, wie).
Mir ist kein System bekannt dass seine ``passwd`` nicht in ``/etc/passwd`` hat.
Sein Code sieht das nunmal vor. Warum auch nicht? Er kann ja die passwds von verschiedenen Rechnern untersuchen/bearbeiten wollen. Wenn nicht, dann ist der Punkt natürlich irrelevant.
Gruß,
Manuel
Verfasst: Sonntag 3. Mai 2009, 19:09
von stuhlbein
helduel hat geschrieben:Moin,
das pwd-Modul parst die passwd bereits und kann eine Liste mit allen Einträgen zurückgeben. Allerdings ist es nicht so flexibel: Man kann keine passwd angeben (zumindest weiß ich nicht, wie). Außerdem liest es auch alle Daten in den Speicher. Wobei man das IMO bei der passwd auch vernachlässigen kann.
Gruß,
Manuel
Ah, dann war die ganze arbeit mehr oder weniger Umsonst
BlackJack hat geschrieben:
@Bitfish: Wo würden da zwangsläufig zwei `dict`\s entstehen!?
Lies bitte die frage. Es entstehen keine dicts, es war
geplant dass am ende ein Dict mit den werten der /etc/passwd generiert wird. Da ich aber nicht wusste wie ich das lösen soll, habe ich es bei einer einfachen Ausgabe belassen.
Anmerkungen zum Skript: Was soll die Klasse? Die ist völlig überflüssig -- das sind einfach nur zwei Funktionen.
Das ist richtig, aber Python ist eine Objekt Orientierte Sprache, und das ist für >mich< grund genug auch Klassen zu verwenden.
Dateien, die man öffnet, sollte man auch explizit wieder schliessen oder die ``with``-Anweisung verwenden. Und in Funktionen/Methoden sollte man das Programm nicht einfach mit `sys.exit()` beenden. Damit kann man die Funktion schlechter wiederverwenden und schlechter testen.
In der Regel versucht man es zu vermeiden Textdateien komplett in den Speicher zu lesen, wenn man die Zeilen einzeln verarbeiten möchte. Dateiobjekte sind nämlich "iterables" über die Zeilen.
Danke, ich werds mir merken
Wie soll ein `None` beim `split()`\en entstehen können? Was ist mit Leerzeilen die nicht ganz leer sind, sondern nur "whitespace"-Zeichen enthalten?
Ist vielleicht eine Angewohnheit aus altn PHP zeiten, da PHP auch '' als NULL interpretiert (einer dieser WTF momente in PHP).
Wofür steht die Abkürzung `sb`?
Für nix, ich hätte vermutlich einen besseren Namen wählen können.
Wenn man sich die ``print``\s anschaut und das Du da einen Index manuell in jeder Zeile "hochgezählt hinschreibst" legt die Verwendung einer Schleife nahe.
Jo.

Verfasst: Sonntag 3. Mai 2009, 19:12
von DasIch
Bitfish hat geschrieben:Das ist richtig, aber Python ist eine Objekt Orientierte Sprache, und das ist für >mich< grund genug auch Klassen zu verwenden.
Die Verwendung von Klassen macht Code nicht Objekt orientiert. Ein sehr gutes Beispiel ist dafür Java. Die Idee nur Klassen zu verwenden hat da zu allem geführt aber nicht zu OOP.
Verfasst: Sonntag 3. Mai 2009, 19:24
von lunar
helduel hat geschrieben: Außerdem liest es auch alle Daten in den Speicher.
Woher weißt du das?
Verfasst: Sonntag 3. Mai 2009, 20:49
von BlackJack
@Bitfish: Ich habe die Frage gelesen, darum steht in der Antwort bzw. Gegenfrage auch "würden" und nicht "werden".
Python ist eine *objekt*orientierte Programmiersprache, also reicht es völlig aus Funktions*objekte* zu erstellen. Alles sinnlos in Klassen zu stopfen macht ein Programm weder objektorientiert, noch besonders sauber oder verständlich.
Wenn man eine Klasse sieht, erwartet man eine Verbindung von Daten und dazugehörigen Operationen und nach der `__init__()` ein initialisiertes Exemplar von so einem Verbund, mit dem man dann sinnvolle Dinge anstellen kann. Wenn sich die `__init__()` wie eine Funktion verhält, und die Methoden nur Funktionen sind, und das Objekt was man erzeugt, überhaupt gar nicht verwendet wird, dann ist das überraschend und unsauber. Und eben nicht OOP.
Verfasst: Montag 4. Mai 2009, 08:42
von helduel
lunar hat geschrieben:helduel hat geschrieben: Außerdem liest es auch alle Daten in den Speicher.
Woher weißt du das?
Weil ich mit getpwall, was der Funktion entspricht, die hier nachgebaut werden soll, eine Liste mit allen Daten bekomme.
Verfasst: Montag 4. Mai 2009, 23:41
von stuhlbein
BlackJack hat geschrieben:@Bitfish: Ich habe die Frage gelesen, darum steht in der Antwort bzw. Gegenfrage auch "würden" und nicht "werden".
Sorry - hab ich wohl missverstanden
Python ist eine *objekt*orientierte Programmiersprache, also reicht es völlig aus Funktions*objekte* zu erstellen. Alles sinnlos in Klassen zu stopfen macht ein Programm weder objektorientiert, noch besonders sauber oder verständlich.
Ich werds mir merken. Vielleicht bin ich einer dieser Javakranken... auch wenn ich nie mit Java arbeiten musste (zum glück

).
Wenn man eine Klasse sieht, erwartet man eine Verbindung von Daten und dazugehörigen Operationen und nach der `__init__()` ein initialisiertes Exemplar von so einem Verbund, mit dem man dann sinnvolle Dinge anstellen kann. Wenn sich die `__init__()` wie eine Funktion verhält, und die Methoden nur Funktionen sind, und das Objekt was man erzeugt, überhaupt gar nicht verwendet wird, dann ist das überraschend und unsauber. Und eben nicht OOP.
So hab ichs noch nicht betrachtet - ergibt aber durchaus sinn. Vielleicht ist mein verständnis von OOP einfach durch falsche vorbilder getrübt
