Verständnisfrage zum Codesnippet "755 -> rwxr-xr-x&q

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
mouses
User
Beiträge: 5
Registriert: Montag 29. März 2010, 23:55

Sonntag 4. April 2010, 22:31

Mahlzeit auch.

Ich habe mir gedacht ich schau mir mal die Snippets an, zum einen, da da bestimmt was brauchbares dabei ist, zum andern, da man dadurch bestimmt auch viel über die Sprache selbst lernen kann.

Maja, direkt beim ersten Snippet habe ich erstmal 20 minuten gesessen, bis ich das vollends entziffert habe, und bin immer noch nicht sicher, ob ich das alles korrekt verstanden habe. Es wird verwendet, um die Oktalschreibweise der Linux-Rechte in die Symbolische Schreibweise zu überführen

Nun gut, ich machs folgendermaßen:
* Code Zeigen
* code durchgehen
* erläutern, was man dadurch implizit zu Lernen gemeint hat

1. Code

Code: Alles auswählen

import os

def symbolic_notation(mode):
    return ''.join(
        mode & 0400 >> i and x or '-' for i, x in enumerate('rwxrwxrwx')
    )

print symbolic_notation(os.stat('blub').st_mode)
Quelle: [wiki]755 -> rwxr-xr-x[/wiki]

(Ih weiß, dass dazu einen Thread gibt; da dieser aber fast zwei Jahre alt ist, und ich kein keine Leichenschändung begehen wollte, habe ich einen neuen eröffnet)

2. Funktionsweise
Mich interessiert insbesondere die Zeile, welche den anzuhängenden Char ermittelt; den Rest kann ich problemlos lesen. Also:
  • *Zuerst wird mittels einem enumerate ein String enommen und daraus Charweise für eine for-Schleife zwei Variablen i ud x jeweils der Index bzw. der entsprechende Char übergeben

    *danach wird die Bitdarstellung von 0400 i mal bitweise nach rechts verschoben. Soweit ich weiß ist der von stat().st_mode übergebene Wert auch oktal; auf diese Weise bezweckt man zweierlei: zum einen werden nur die normalen Benutzerrechte ausgewertet; Sticky-bits und sowas werden ignoriert. Zum andern kann man beim highest bit (also dem User-r-bit in Symbolischer notation) anfangen und sich durch den String durcharbeiten

    *Danach wird der erzeugte Wert mit dem modus bitweise verundet
    *Das Logische UND danach sorgt für folgendes: ist der Vorherige Wert 1, so wird der in x vorhandene char - also der aktuelle Wert aus dem String - zurück gegeben

    *das logische ODER danach sorgt dafür, dass, falls der vorherige Wert 0 war, ein minus zurück gegeben wird.
3. Was lerne ich daraus:
  • * was in der gleichen Zeile vor einem for-Statement steht ist im Grunde der entsprechende Code-Block, der normalerweise darunter steht

    * ein Bitshifting bindet stärker als ein bitweises UND

    * die numerische 1 und das logische True werden identisch behandelt

    * eine Aussage ist solange True, wie sie nicht explizit False bzw 0 ist (sonst könnte das logische UND gar nicht funktionieren)

    * wenn ein logisches UND wahr ist, so wird der Wert des zweiten Parameters zurück gegeben, egal, ob dieser von einer Aussage oder eine Variable kommt bzw. was dieser für einen Typ hat

    * für das logische ODER gilt ähnliches: ist der erste Parameter nicht falsh, so wird der Wert dessen zurück gegeben, ansonsten der Wert des zweiten

    * Oktalzahlen werden in Python mit einer führenden Null gekennzeichnet (wobei sich das glaube ich mit der Version 3.x geändert hat. Klappt das Snippet hier dann überhaupt noch)
Habe ich das alles soweit richtig verstanden, oder gibts da irgendwo Fehler in meiner Ausarbeitung?
BlackJack

Sonntag 4. April 2010, 22:56

@mouses: Sieht soweit gut aus würde ich sagen.

Allerdings ist der Wert von ``stat().st_mode`` einfach eine Zahl. Zahlen haben keine Basis -- nur die *Darstellung* einer Zahl geschieht zu einer Basis. Zum Beispiel Dezimal. Statt der 0400 hätte man auch 256 oder 0x100 schreiben können -- es sind alles Darstellungen derselben Zahl.

Den ``and``/``or``-Trick sollte man nicht mehr verwenden denn mittlerweile hat Python Syntax für einen bedingten Ausdruck. ``x if (mode & (0400 >> i)) else '-'`` würde man an der Stelle heute schreiben. Wie Du schon herausgefunden hast bindet Bitweises verschieben stärker als die Und-Verknüpfung, aber ich würde trotzdem Klammern setzen, damit das auch jedem klar ist ohne lange drüber nachdenken zu müssen.
mouses
User
Beiträge: 5
Registriert: Montag 29. März 2010, 23:55

Sonntag 4. April 2010, 23:08

Ah, das mit der Zahl war wohl ein Denkfehler meinerseits: es wird eine Integer zurückgegeben, welche binär mit der binären entsprechung einer Integer verglichen wird, welche als Oktahlzahl angegeben wurde. *grmpf* Ok, war echt ein blöder Verdenker.

Zurück zur Oktaldarstellung: stimmt das, dass diese ab 3.x nicht mehr gilt, oder ist das nur ein Gerücht? Wenn nein, wo genau kann ich das nachlesen?
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Sonntag 4. April 2010, 23:13

[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
Antworten