Mirroring · Apr 10, 10:32 von stargaming
Dank Armin Ronacher (der mich auf den entscheidenden Tipp gebracht hat, Informationen einfach in einem Funktionsattribut zu speichern), ist folgendes Codeschnipselchen entstanden:
python:
- class Mirroring(type):
- def __new__(meta, name, bases, clsdict):
- for key, value in clsdict.items():
- if hasattr(value, 'func_code') and hasattr(value, '_mirroring'):
- for mirror in value._mirroring:
- for alias in mirror[0]:
- if alias not in clsdict:
- clsdict[alias] = lambda *a, **k: value(*a, **k)
- clsdict[alias].__name__ = alias
- if mirror[1]:
- clsdict[alias].doc = mirror1
- else:
- clsdict[alias].__doc__ = \
- getattr(value, '__doc__', None)
- return type.__new__(meta, name, bases, clsdict)
- def mirror(*names, **doc):
- def wrapped(f):
- if not hasattr(f, '_mirroring'):
- f._mirroring = []
- f._mirroring.append((names, doc.get('doc', None)))
- return f
- return wrapped
Benutzt wird es in etwa so:
python:
- class A(object):
- __metaclass__ = Mirroring
- @mirror("bar", doc="abkuerzung fuer foo")
- def foo(self):
- "irgendeine wichtige methode"
- print "hi!"
- a = A()
- a.foo() # hi!
- a.bar() # hi!
- print a.foo.__doc__ # irgendeine wichtige methode
- print a.bar.__doc__ # abkuerzung fuer foo
Mirroring muss als Metaklasse gesetzt werden, um das Injizieren der Aliase zu ermöglichen. mirror nimmt als Argumente arbiträr viele positionale Namen auf die gespiegelt wird und eine Schlüsselwortargument doc (andere werden verschluckt), welches die Dokumentation ergibt.
Nützlich ist das zum Beispiel in cmd.Cmd, wo jeder Befehl der Kommandozeile mit einer Methode do_Befehl registriert wird.
python:
- __metaclass__ = Mirroring
- class Cmd(cmd.Cmd):
- @mirror('do_q', doc='shorthand for quit')
- def do_quit(self):
- exit()

