Mittwoch, 7. August 2013

Na super() - Freude mit Python

Neulich in PyCharm: Da hacke ich so froh vor mich hin, bastel ein Skriptchen mit zwei Klässelchen, und stelle fest, dass man Teile davon in eine gemeinsame Superklasse ziehen kann. Nichts besonderes, und weil Python ja objektorientiert konzeptioniert ist, geht das auch total einfach:

class Common(object):
  def __init__(self, some):
    self._some = some


class A(Common):
  def __init__(self):
    super(A, self).__init__('some soll hier A sein')


class B(Common):
  def __init__(self):
    super(B, self).__init__('hier soll es B sein')

Ok, ist schon klar, das ist synthetischer Code, tut aber nichts zu Sache. Nach allem, was ich so weiß, funktioniert das theoretisch. In der Praxis funktioniert das auch, beispielsweise auf einem 2.7.x-Python auf Linux.

Bis ich das in einem virtualenv auf meinem Mac laufen lasse (Python 2.7.2). Dann werde ich mit folgender Meldung beglückt:

TypeError: super(type, obj): obj must be an instance or subtype of type

Nicht, was ich erwartet hatte. Google spuckt dazu einen netten Link namens Another super() wrinkle – raising TypeError aus, und wer Freude dran hat, darf sich ruhig in den Artikel vertiefen. Allein: Ich benutze keinen Plugin-Loader, der Fehler tritt bei mir beim ganz normalen Unittest auf (mit einem ganz normalen unittest2, muss ich wohl dazu sagen). Ich überspringe hier mal lange Debugging-Sessions und komme gleich zum Kern: super(self.__class__, self).__init__(...) tut's:

class Common(object):
  def __init__(self, some):
    self._some = some


class A(Common):
  def __init__(self):
    super(self.__class__, self).__init__('some soll hier A sein')


class B(Common):
  def __init__(self):
    super(self.__class__, self).__init__('hier soll es B sein')

Das sieht mir zwar irgendwie wirklich zu schräg aus, und ich kann mir gut vorstellen, dass hier super irgendwie falsch behandelt wird, aber auch, dass man hier noch basteln kann, damit es hübscher aussieht. Andererseits reicht es mir wirklich vollkommen, die Vererbung im Kopf der Klassendefinition anzugeben, also ist diese Schreibweise vielleicht sogar wert, ins Muskelgedächtnis der Finger aufgenommen zu werden.

Ausserdem funktioniert's.

Montag, 5. August 2013

Git Branches auf dem Terminal

Es passiert ja immer wieder mal, dass man auf irgendeinem Rechner, der keine grafische Oberfläche angeschlossen hat, in die History eines Repositories reingucken muss. Das Werkzeug dazu ist natürlich git log:

> git log

commit 123...789

Author: John Doe <john.doe@inter.net>
Date:  Fri Feb 1 13:23:03 2013 +0100

    Add nice stuff

    Today I decided to add nice stuff to this repository.
...

Auf die Art und Weise bekommt man natürlich keinen Überblick über das Repository, das ist ja viel zu ausführlich. Aber git kennt einen Einzeiler-Modus, der praktischerweise gleich so heißt:

> git log --oneline
1234567 Add nice stuff
...

Als History kreuz und quer über alle Branches ist das dann aber etwas unübersichtlich. ASCII-Art sei Dank gibt's auch auch dem Terminal Grafiken:

> git log --graph --oneline
* 1234567 Add nice stuff
...

Schon besser. Wenn wir alle Branches sehen wollen, nicht nur den aktuellen Branch, gibt's dazu noch ein "--all":

> git log --graph --oneline --all
* 1234567 Add nice stuff
...

Ok, der Unterschied ist hier nicht gerade deutlich, aber das sollte man einfach mal mit einem echten Repository probieren. Wenn man das tut, stellt man aber fest: Welcher Commit auf welchen Branch ist, kann man einfach nicht sehen. Das kann schon mal wichtig sein, also lassen wir uns das einfach noch mit anzeigen:

> git log --graph --oneline --decorate=short --all
* 1234567 (HEAD, origin/master, master) Add nice stuff
...

Das ist schon fast perfekt. Damit wir das aber nicht jedes Mal tippen müssen, legen wir dafür einfach noch einen Alias an.

> git config --global alias.lg 'log --graph --oneline --decorate=short'
> git lg --all
* 1234567 (HEAD, origin/master, master) Add nice stuff
...

Den Alias haben wir global für den Nutzer angelegt, damit funktioniert er in allen Repos des Nutzers. Das letzte '--all' habe ich im Beispiel weggelassen, damit mal auch mal einfach nur die Historie des aktuellen Branches sehen kann. Noch schöner wird's übrigens, wenn man die Farbe einschaltet.

So einfach können die kleinen Freuden sein.