Python source beautifier

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.
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Hallo, ich kann es kaum glauben, aber mit google fand ich keinen (brauchbaren) python code beautifier.

Warum werden sich einige fragen, programmier gleich ordentlich. :)

Ich habe einige Fremdsourcen, in der z.b. nicht auf spaces 4 programmiert wurde. (Ich kenne reindent.py, such aber eher eine Komplettlösung, schön wäre auch eine Gui).

Hm, wäre eventuell auch ein nettes Projekt, nur ich selber habe keine Zeit momentan.

Features, die ich mir wünschen würde.
Use Spaces, size: 4
macht aus (unnötigen) if (a > b): if a > b
fügt spaces ein (nicht aber bei Funktionen)
a+=1 => a += 1
p(t + 1) => p(t+1)

macht aus konstrukte:
self.scriptcount = self.scriptcount + 1 => self.scriptcount += 1
aus is == und "is not" != (ok das wäre einfach)
break long lines (vernünftig)
macht aus compare if len(string) > 0: => if string:
if if len(string) < 1 oder if string == "" => if not string

detect mixed line ending
detect tabs mixed with space
trim trailing whitespaces.

Gibt es irgendwo so ein Tool?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Francesco hat geschrieben: aus is == und "is not" != (ok das wäre einfach)
und dämlich noch dazu :D
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

EyDu hat geschrieben:
Francesco hat geschrieben: aus is == und "is not" != (ok das wäre einfach)
und dämlich noch dazu :D
Naja, muss das schon ein bisschen relativieren.
Ich weiss ja nicht (bitte korrigiert mich), hat es nicht früher (irgendwann bei 1.5 oder noch vorher) noch gar nicht den != operator gegeben?

Ausserdem: is not: vielleicht bevorzugt irgendwer diese Schreibweise? *zuck*
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

Z.B. PEP 8:
- Comparisons to singletons like None should always be done with
'is' or 'is not', never the equality operators.
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

mkallas hat geschrieben:Z.B. PEP 8:
- Comparisons to singletons like None should always be done with
'is' or 'is not', never the equality operators.
Hm, aber es macht keinen Unterschied, oder?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Francesco hat geschrieben:Hm, aber es macht keinen Unterschied, oder?
Doch. Stell dir mal vor du hast einen Unit-Test test und möchtest überprüfen, ob dein Singleton wirklich nur einmal konstruiert worden ist. Ein Test über "==" könnte falsche Ergebnise liefern, ein Test über "is" nicht.

Gut zugegeben, dieses Beispiel ist sehr Konstruiert, aber es gibt halt Situationen in denen der Unterschied wichtig ist.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Hoi,

möchte auch meinen Senf dazu abgeben:
Francesco hat geschrieben: macht aus (unnötigen) if (a > b): if a > b
Das mag hier unnötig sein, erhöht aber in anderen, ähnlichen Fällen die Lesbarkeit. PEPs hin oder her: Ich mache das sehr häufig und stehe auch dazu. Ein paar zusätzliche Klammern helfen mir - gerade bei verschachtelten Abfragen - den Durchblick zu bewahren, auch wenn die Klammern das Ergebnis nicht ändern würden.
Francesco hat geschrieben: macht aus konstrukte:
self.scriptcount = self.scriptcount + 1 => self.scriptcount += 1
Muß man hierbei nicht überprüfen, ob die Objekte vom selben Typ sind? In den meisten Fällen dürfte das kein Problem sein, aber was, wenn self.scriptcount kein Integer oder Float ist und das '+' "überladen"? Ließen sich solche Fälle für "beautifier" immer eindeutig lösen?
Francesco hat geschrieben: macht aus compare if len(string) > 0: => if string:
if if len(string) < 1 oder if string == "" => if not string
Der Beautifier dürfte an dieser Stelle ein bißchen umständlich werden: Auch hier muß überprüft werden, ob der Typ wirklich einem String entspricht.

Bzgl. Unittest: Sooo konstruiert ist die Sache nicht, etwas in der Richtung ist mir schon passiert :oops:

Gruß,
Christian
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

CM hat geschrieben:
Francesco hat geschrieben: macht aus konstrukte:
self.scriptcount = self.scriptcount + 1 => self.scriptcount += 1
Muß man hierbei nicht überprüfen, ob die Objekte vom selben Typ sind? In den meisten Fällen dürfte das kein Problem sein, aber was, wenn self.scriptcount kein Integer oder Float ist und das '+' "überladen"? Ließen sich solche Fälle für "beautifier" immer eindeutig lösen?
Auch das funktioniert nicht, da die Semantik von + und += verschieden sind. Bei + erwartet man ein neues Objekt, bei += eine Veränderung die in-place geschieht (wenn möglich). An Listen wird das Problem schon deutlich. Noch besser wird es dann, wenn + und += noch völlig verschieden überladen werden, weil jemand dies aus irgend einem Grund für sinnvoll hält.

(IDLE)

Code: Alles auswählen

>>> a=[1]
>>> b=[2]
>>> c=a+b
>>> c
[1, 2]
>>> a
[1]
>>> b
[2]
>>> a+=b
>>> a
[1, 2]
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Francesco hat geschrieben:
mkallas hat geschrieben:Z.B. PEP 8:
- Comparisons to singletons like None should always be done with
'is' or 'is not', never the equality operators.
Hm, aber es macht keinen Unterschied, oder?
Doch. ``is`` und ``is not`` testen auf Identität, ``==``, ``!=`` und ``<>`` auf Gleichheit. Und das muss nicht immer das gleiche sein, so können zwei verschiedene Objekte gleich sein, aber nicht die gleiche Identität haben.

@EyDu: Irgendwie entgeht mir der Sinn deines Codebeispiels. Wenn man statt ``c = a + b`` ``a = a + b`` kommt man genau auf das gleiche Ergebnis. Und wirklich überraschend ist es ja nicht, da das ``+=`` ja irgendwie klar macht, dass die Variable *) links davon geändert wird.

*) oder genauer das an den Namen gebundene Objekt
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

@EyDu: Eben, genau das ist das Argument. Allerdings verstehe ich ebensowenig wie Leonidas, was Du mit dem Beispiel eigentlich zeigen willst - aus dem gleichen Grund wie Leonidas.
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Hi

Ich denke das Beispiel sollte eher so sein:

Code: Alles auswählen

a = [1]
b = [2]
c = a
a = a+b
print 'a:',a
print 'c:',c

a = [1]
b = [2]
c = a
a += b
print 'a:',a
print 'c:',c
Ausgabe:

Code: Alles auswählen

a: [1, 2]
c: [1]

a: [1, 2]
c: [1, 2]
Kommt also nicht aufs gleiche.

Gruss
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

rayo hat da schon ganz richtig vermutet, was ich meinte. Nächstes mal lese ich einfach noch mal durch was ich poste :roll:
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Wie schon geschrieben machen "is" und "==" etwas anderes: Ein schönes Beispiel:

Code: Alles auswählen

>>> a = 50
>>> b = 50
>>> a is b
True
>>> a = 100
>>> b = 100
>>> a is b
False
(hier CPython, in Jython kann das noch ganz anders aussehen)

Warum ist das so? Wenn du "50" schreibst, wird ein Integer-Objekt mit dem Wert 50 erzeugt, dito für "101", jedoch ist bei CPython eine kleine Optimierung vorgenommen worden, so werden alle Integers von 0 bis 99 einmal global erzeugt und gecacht, so dass sie, wenn man wieder ein Integer mit dem Wert "42" gebraucht wird, auf die bereits existierende Instanz verwiesen werden kann. Bei Zahlen über 99 wird das Objekt jedesmal neu erzeugt; und is schaut nunmal, ob es sich um dasselbe Objekt handelt, ==, ob es sich um ein gleiches Objekt handelt.
dst
User
Beiträge: 27
Registriert: Mittwoch 28. Februar 2007, 23:42

Ist das letzte Beispiel nicht eher ein Grund dafür, in den meisten Fällen == zu benutzen?
Gerade bei primitiven kommt es doch i.d.R. weniger auf Identität als auf Wertigkeit an.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Das ist der entscheidende Punkt:
dst hat geschrieben: i.d.R.
Also kann ein potentieller beautifier '==' und 'is' nicht gleichsetzten. Was im Programm relevant ist, ist natürlich eine ganz andere Frage.
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Joghurt hat geschrieben:Wie schon geschrieben machen "is" und "==" etwas anderes: Ein schönes Beispiel:

Code: Alles auswählen

>>> a = 50
>>> b = 50
>>> a is b
True
>>> a = 100
>>> b = 100
>>> a is b
False
(hier CPython, in Jython kann das noch ganz anders aussehen)
Würg, das ist ein Hammer. ;)
Wie soll man auf so etwas kommen, ohne sich genau zu informieren?
Intuitiv ist das nicht gerade.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Francesco hat geschrieben:Wie soll man auf so etwas kommen, ohne sich genau zu informieren?
Intuitiv ist das nicht gerade.
Darauf kommt man nicht. Wer testet schon ob eine Instanz der Int-Klasse gleich einer anderen (oder eben der gleichen) Instanz der Int-Klasse ist. Dafür gibt es ``==`` und sonst gibt es mit dieser Optimierung in echten Programmen keinerlei Probleme.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Francesco hat geschrieben: Wie soll man auf so etwas kommen, ohne sich genau zu informieren?
Ich werde ja das Gefühl nicht los, dass einige Menschen versuchen Programiersprachen nur durch ausprobieren zu lernen und mit wenig Untersütztung von Literatur ... Aber wenn man mit solchen Feinheiten nicht in Kontakt kommt ist das ja auch in Ordnung. Immerhin braucht eine Sprache ja auch eine breite Basis.
Francesco hat geschrieben: Intuitiv ist das nicht gerade.
Wenn man den Unterschied von Objektgleichheit und Wertegleichheit kennt schon :D
BlackJack

Dem würde ich mich anschliessen. Das ``=`` eine Zuweisung und ``==`` ein Vergleich ist, ist auch nicht intuitiv. Oder ``lambda``. Closures. Klassen. Metaklassen. Sichtbarkeitsbereiche von Namen. Man muss halt Doku lesen wenn man wissen will was für eine Semantik hinter den Syntaxkonstrukten steckt.
Mad-Marty
User
Beiträge: 317
Registriert: Mittwoch 18. Januar 2006, 19:46

weitere anmerkung zu == & is:

Code: Alles auswählen

>>> True is 1
False
>>> True == 1
True
Antworten