SlideShare ist ein Scribd-Unternehmen logo
1 von 22
Downloaden Sie, um offline zu lesen
Metaprogrammierung, praktisch

                                   Andi Albrecht

                                       PyCon DE 2012


                               30. Oktober 2012




Hintergrund        Ein paar Konzepte                    Use-Cases                          Sinn oder Unsinn?
...                .....                                .....
                                                Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
Andi Albrecht – @andialbrecht


              Erster Python-Kontakt vor etwa 10 Jahren als
              Studentische Hilfskraft bei der DFG
              Aktuell: Anwendungsentwickler für Webapplikationen bei
              ProUnix in Bonn
              Entwicklung und Pflege mittlerer und großer Systeme
              OpenSource: Rietveld Code Review Tool,
              python-sqlparse, CrunchyFrog, hgsvn, ...




Hintergrund              Ein paar Konzepte           Use-Cases                          Sinn oder Unsinn?
...                      .....                       .....
                                             Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
Übersicht

       Hintergrund


       Ein paar Konzepte


       Use-Cases


       Sinn oder Unsinn?




Hintergrund          Ein paar Konzepte           Use-Cases                          Sinn oder Unsinn?
...                  .....                       .....
                                         Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
Hintergrund
Was ist Metaprogrammierung?



              "Programmierung der Programmierung"
              "Programmcode erzeugt|untersucht|… Programmcode"
              "Programmcode wird zu Objekten von anderem
              (Meta-)Programmcode"




Hintergrund             Ein paar Konzepte           Use-Cases                          Sinn oder Unsinn?
...                     .....                       .....
                                            Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
Hintergrund
Was ist Metaprogrammierung?



              "Programmierung der Programmierung"
              "Programmcode erzeugt|untersucht|… Programmcode"
              "Programmcode wird zu Objekten von anderem
              (Meta-)Programmcode"
              mysterious, strange, weird, mind-blowing, …




Hintergrund              Ein paar Konzepte           Use-Cases                          Sinn oder Unsinn?
...                      .....                       .....
                                             Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
Hintergrund
Was ist Metaprogrammierung?


              "Programmierung der Programmierung"
              "Programmcode erzeugt|untersucht|… Programmcode"
              "Programmcode wird zu Objekten von anderem
              (Meta-)Programmcode"
              mysterious, strange, weird, mind-blowing, …
       Meta-: jenseits, dahinter liegend, …




Hintergrund              Ein paar Konzepte           Use-Cases                          Sinn oder Unsinn?
...                      .....                       .....
                                             Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
Hintergrund
Metaklassen in Python

              Wohl bekannteste Form der Metaprogrammierung in
              Python
              Möglichkeiten zur Modifikation von Klassen schon in 1995
              als C-Extension möglich (Don Beaudry Hook)
              Ab Python 1.5 auch ohne C-Extension∗
              Echter Support für Metaklassen mit New-Style-Classes in
              Python 2.2
       * dazu: Essay von GvR "Metaclasses in Python 1.5 (a.k.a. The Killer Joke)"
       http://www.python.org/doc/essays/metaclasses/
       http://python-history.blogspot.de/2009/04/metaclasses-and-extension-classes-aka.html




Hintergrund                 Ein paar Konzepte                Use-Cases                          Sinn oder Unsinn?
...                         .....                            .....
                                                     Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
Hintergrund
Metaklassen in Python
       Python 1995: C-Extension                 Python 2.2
       Python 1.5
                                                class Foo(object):
       class Tracing:
                                                  __metaclass__ = MyMetaclass
         def __init__(self,
           name, bases, namespace):
         def __call__(self):                    Python 3
       class Instance:
         def __init__(self, klass):
         def __getattr__(self, name):
                                                class Foo(metaclass=MyMetaclass):
                                                  pass
       class BoundMethod:
         def __init__(self,
           function, instance):
         def __call__(self, *args):

       Trace = Tracing(’Trace’, (), )

       class MyTracedClass(Trace):
         def method1(self, a):



Hintergrund                 Ein paar Konzepte           Use-Cases                          Sinn oder Unsinn?
...                         .....                       .....
                                                Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
Konzepte
Metaprogrammierung in Python


              Types
              Metaklassen
              Dekoratoren
              Code-Generierung zur Laufzeit (synthetische
              Funktionen/Klassen)
              ...




Hintergrund             Ein paar Konzepte           Use-Cases                          Sinn oder Unsinn?
...                     .....                       .....
                                            Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
Konzepte
type()

              type(object) → liefert Typ des Objekts
              type(name, bases, namespace) → erzeugt einen
              neuen Typ

       > def my_func(self):
       .    return 42

       > Question = type(’Question’, (), {’answer’: my_func})
       > Question().answer()
       < 42




Hintergrund             Ein paar Konzepte           Use-Cases                          Sinn oder Unsinn?
...                     .....                       .....
                                            Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
Konzepte
types-Modul
       import types

       # Modul erzeugen
       my_mod = types.ModuleType(’foo’, ’doc string’)
       my_mod.foo = my_func
       sys.modules[’heyho’] = my_mod
       import heyho
       heyho.foo()

       # Methode erzeugen
       def answer(self):
           return 42
       class Foo(object):
           pass
       foo1 = Foo()
       foo2 = Foo()
       foo1.answer = types.MethodType(answer, foo1)
       foo1.answer() # gibt 42 zurück
       foo2.answer() # wirft einen AttributeError

Hintergrund            Ein paar Konzepte           Use-Cases                          Sinn oder Unsinn?
...                    .....                       .....
                                           Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
Konzepte
Metaklassen


              Metaklassen modifizieren Klassen
              Metaklassen können Meta-Funktionen haben
              Beispiel für Einsatzzwecke:
                  neue Typen von Klassen
                  neues Verhalten von Klassen
                  Automatisierungen
                  Registrierung von Klassen
                  Frameworks, ORMs
                  Introspektion, QA




Hintergrund             Ein paar Konzepte           Use-Cases                          Sinn oder Unsinn?
...                     .....                       .....
                                            Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
Konzepte
Metaklassen, Beispiel
       class PluginRegistry(type):

              registry = {}

              def __new__(mcls, name, bases, classdict):
                  return type.__new__(mcls, name, bases, classdict)

              def __init__(cls, name, bases, namespace):
                  PluginRegistry.register(cls)
                  return super(PluginRegistery, cls).__init__(name, bases, namespace)

              @classmethod
              def register(mcls, cls):
                  mcls.registry[cls.__name__] = cls

              @classmethod
              def get_all(cls):
                  return cls.registry

       class Foo(metaclass=PluginRegistry): pass
       class Bar(metaclass=PluginRegistry): pass

       PluginRegistry.get_all() # –> gibt {’Foo’: <class Foo>, ’Bar’: <class Bar>} zurück
       Foo.get_all()     # –> gibt {’Foo’: <class Foo>, ’Bar’: <class Bar>} zurück
       Foo().get_all()   # –> AttributeError


Hintergrund                    Ein paar Konzepte                Use-Cases                          Sinn oder Unsinn?
...                            .....                            .....
                                                        Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
Konzepte
Klassendekoratoren, Definition zur Laufzeit, ...
              Klassendekoratoren                           Monkey-Patching

                                                           import amodule
              @my_classdecorator
              class Foo(object):                           def better_func():
                pass                                         print(’This is better!’)
                                                             return None
              Code-Generierung zur
              Laufzeit                                     amodule.func = better_func

              namespace = {}                               ...
              exec(”””def answer():
                return 42”””, namespace)
              namespace[’answer’]() # 42

              aber exec lieber vermeiden!




Hintergrund                          Ein paar Konzepte           Use-Cases                          Sinn oder Unsinn?
...                                  .....                       .....
                                                         Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
Use-Cases



              Enum-Implementierung mit type (Erstellung neuer Typen)
              ORM-API mit Metaklassen (Framework / ORM)
              Aufbau einer Testmatrix (Automatisierung)




Hintergrund              Ein paar Konzepte           Use-Cases                          Sinn oder Unsinn?
...                      .....                       .....
                                             Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
Use-Cases
Enums
       def enum(**enums):
           return type(’Enum’, (), enums)

       > Numbers = enum(ONE=1, TWO=2, THREE=’three’)
       > Numbers.ONE
       1
       > Numbers.TWO
       2
       > Numbers.THREE
       ’three’

       def enum(name, *sequential):
           enums = dict(x[::-1] for x in enumerate(sequential))
           return type(name, (), enums)
       > Colors = enum(’Colors’, ’RED’, ’GREEN’, ’BLUE’)
       > Colors.RED
       0

       Siehe http://stackoverflow.com/a/1695250/97167
Hintergrund            Ein paar Konzepte            Use-Cases                          Sinn oder Unsinn?
...                    .....                        .....
                                            Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
Use-Cases
Django-Models


       from django.db import model

       class Book(model.Model):
           author = models.CharField(max_length=200)
           title = models.CharField(max_length=200)
           year = models.IntegerField()

              class Meta:
                  verbose_name_plural = u’Books’




Hintergrund               Ein paar Konzepte           Use-Cases                          Sinn oder Unsinn?
...                       .....                       .....
                                              Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
Use-Cases
Django-Models
       from django.db import model

       class Book(model.Model):
           author = models.CharField(max_length=200)
           title = models.CharField(max_length=200)
           year = models.IntegerField()

              class Meta:
                  verbose_name_plural = u’Books’

       ...und was Django's Metaklasse macht (unter anderem):
              verschiebt "Meta" nach "_meta" und erstellt eigenes Objekt
              fügt neue DoesNotExist/MultipleObjectsReturned-Attribute hinzu
              ergänzt einen Record-Manager als "objects"-Attribut
              wertet die gegebenen Attribute (Namespace) aus und macht sie fit zur
              Verwendung mit einer DB
              ...
Hintergrund                Ein paar Konzepte             Use-Cases                          Sinn oder Unsinn?
...                        .....                         .....
                                                 Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
Use-Cases
Test-Matrix
       class ApiTestCase(unittest.TestCase, metaclass=TestMatrixMeta):
           apicalls = (
               (’/user/1’, ’GET’, {’name’: ’foo’}),
               (’/user/1/locations’, ’GET’, [’Leipzig’,]),
           )


       python3 testmatrix.py -v
       test__user_1_json (__main__.test__user_1_locations_xml) ... ok
       test__user_1_locations_json (__main__.test__user_1_locations_xml) ... ok
       test__user_1_locations_xml (__main__.test__user_1_locations_xml) ... FAIL
       test__user_1_xml (__main__.test__user_1_locations_xml) ... ok

       ======================================================================
       FAIL: test__user_1_locations_xml (__main__.test__user_1_locations_xml)
       ———————————————————————-
       Traceback (most recent call last):
         File ”testmatrix.py”, line 17, in test_wrapper
           self.assertFalse(u==’/user/1/locations’ and c == ’xml’)
       AssertionError: True is not false

       ———————————————————————-
       Ran 4 tests in 0.001s

       FAILED (failures=1)


Hintergrund                  Ein paar Konzepte               Use-Cases                          Sinn oder Unsinn?
...                          .....                           .....
                                                     Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
Use-Cases
Test-Matrix
       class TestMatrixMeta(type):

              def __new__(mcls, name, bases, attrs):
                  apicalls = attrs.pop(’apicalls’, [])
                  for url, method, expected in apicalls:
                      for ctype in (’json’, ’xml’):
                          name = ’test_%s_%s’ % (url.replace(’/’, ’_’), ctype)
                          attrs[name] = mcls.build_test(name, url, method, expected, ctype)
                  new_cls = type.__new__(mcls, name, bases, attrs)
                  return new_cls

              @classmethod
              def build_test(cls, name, url, method, expected, ctype):
                  def test_wrapper(self, u=url, m=method, e=expected, c=ctype):
                      self.assertFalse(u==’/user/1/locations’ and c == ’xml’)
                  test_wrapper.__name__ = name
                  return test_wrapper

       class ApiTestCase(unittest.TestCase, metaclass=TestMatrixMeta):
           apicalls = (
               (’/user/1’, ’GET’, {’name’: ’foo’}),
               (’/user/1/locations’, ’GET’, [’Leipzig’,]),
           )



Hintergrund                    Ein paar Konzepte                Use-Cases                          Sinn oder Unsinn?
...                            .....                            .....
                                                        Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
Sinn oder Unsinn?

              Für (fast) alles gibt es auch einen andere Lösung
              Debugging wird teils schwieriger, Fehlverhalten nicht
              immer transparent

              Verwendung des Codes wird für End-Entwickler eleganter
              Leichte Erweiterung der Sprache um spezielle
              Paradigmen, Funktionen, Verhalten, Qualitätsrichtlinien, …

       → Metaprogrammierung gezielt einsetzen
       → Einsatz transparent machen



Hintergrund              Ein paar Konzepte           Use-Cases                          Sinn oder Unsinn?
...                      .....                       .....
                                             Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
Danke!

              E-Mail albrecht@prounix.de
                     albrecht.andi@gmail.com

              Twitter @andialbrecht

        Homepage http://andialbrecht.de

                     http://www.prounix.de/unternehmen/jobs/python/
                     prounix.de




Hintergrund             Ein paar Konzepte           Use-Cases                          Sinn oder Unsinn?
...                     .....                       .....
                                            Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012

Weitere ähnliche Inhalte

Ähnlich wie Metaprogrammierung, praktisch

Onno Reiners: E-Learning einfach selbst erstellen
Onno Reiners: E-Learning einfach selbst erstellenOnno Reiners: E-Learning einfach selbst erstellen
Onno Reiners: E-Learning einfach selbst erstellenlernet
 
Von Big Data zu Künstlicher Intelligenz - Maschinelles Lernen auf dem Vormarsch
Von Big Data zu Künstlicher Intelligenz - Maschinelles Lernen auf dem VormarschVon Big Data zu Künstlicher Intelligenz - Maschinelles Lernen auf dem Vormarsch
Von Big Data zu Künstlicher Intelligenz - Maschinelles Lernen auf dem VormarschAndreas Koop
 
Von Big Data zu Künstlicher Intelligenz - Maschinelles Lernen auf dem Vormarsch
Von Big Data zu Künstlicher Intelligenz - Maschinelles Lernen auf dem VormarschVon Big Data zu Künstlicher Intelligenz - Maschinelles Lernen auf dem Vormarsch
Von Big Data zu Künstlicher Intelligenz - Maschinelles Lernen auf dem Vormarschenpit GmbH & Co. KG
 
Einführung in NLP mit Deep Learning
Einführung in NLP mit Deep LearningEinführung in NLP mit Deep Learning
Einführung in NLP mit Deep Learninginovex GmbH
 
Pruefung iu k-2009
Pruefung iu k-2009Pruefung iu k-2009
Pruefung iu k-2009skoller15
 
Was ist der ProgrammierTrainer!
Was ist der ProgrammierTrainer!Was ist der ProgrammierTrainer!
Was ist der ProgrammierTrainer!Erhard Dinhobl
 
Jtl_connect jtl_shop_evo_template_best_practices
Jtl_connect jtl_shop_evo_template_best_practicesJtl_connect jtl_shop_evo_template_best_practices
Jtl_connect jtl_shop_evo_template_best_practicesJTL-Software
 
PLM Open Hours - Zugriffsrechte in einem globalen PDM mit verteilter Entwicklung
PLM Open Hours - Zugriffsrechte in einem globalen PDM mit verteilter EntwicklungPLM Open Hours - Zugriffsrechte in einem globalen PDM mit verteilter Entwicklung
PLM Open Hours - Zugriffsrechte in einem globalen PDM mit verteilter EntwicklungIntelliact AG
 
Kuck mal, Node.js! Einstieg für .NET Entwickler mit Visual Studio Code und Ty...
Kuck mal, Node.js! Einstieg für .NET Entwickler mit Visual Studio Code und Ty...Kuck mal, Node.js! Einstieg für .NET Entwickler mit Visual Studio Code und Ty...
Kuck mal, Node.js! Einstieg für .NET Entwickler mit Visual Studio Code und Ty...Gregor Biswanger
 
Metamodellierung und Validierung
Metamodellierung und ValidierungMetamodellierung und Validierung
Metamodellierung und Validierungfoobar2605
 
Java und Python - Das Beste aus beiden Welten nutzen
Java und Python - Das Beste aus beiden Welten nutzenJava und Python - Das Beste aus beiden Welten nutzen
Java und Python - Das Beste aus beiden Welten nutzenAndreas Schreiber
 
Typ-sichere DSLs
Typ-sichere DSLsTyp-sichere DSLs
Typ-sichere DSLsWerner Keil
 
Objektorientierte Techniken und UML
Objektorientierte Techniken und UMLObjektorientierte Techniken und UML
Objektorientierte Techniken und UMLSebastian Hempel
 
C/ C++ for Notes & Domino Developers
C/ C++ for Notes & Domino DevelopersC/ C++ for Notes & Domino Developers
C/ C++ for Notes & Domino DevelopersUlrich Krause
 

Ähnlich wie Metaprogrammierung, praktisch (20)

Onno Reiners: E-Learning einfach selbst erstellen
Onno Reiners: E-Learning einfach selbst erstellenOnno Reiners: E-Learning einfach selbst erstellen
Onno Reiners: E-Learning einfach selbst erstellen
 
Von Big Data zu Künstlicher Intelligenz - Maschinelles Lernen auf dem Vormarsch
Von Big Data zu Künstlicher Intelligenz - Maschinelles Lernen auf dem VormarschVon Big Data zu Künstlicher Intelligenz - Maschinelles Lernen auf dem Vormarsch
Von Big Data zu Künstlicher Intelligenz - Maschinelles Lernen auf dem Vormarsch
 
Von Big Data zu Künstlicher Intelligenz - Maschinelles Lernen auf dem Vormarsch
Von Big Data zu Künstlicher Intelligenz - Maschinelles Lernen auf dem VormarschVon Big Data zu Künstlicher Intelligenz - Maschinelles Lernen auf dem Vormarsch
Von Big Data zu Künstlicher Intelligenz - Maschinelles Lernen auf dem Vormarsch
 
Einführung in NLP mit Deep Learning
Einführung in NLP mit Deep LearningEinführung in NLP mit Deep Learning
Einführung in NLP mit Deep Learning
 
Pruefung iu k-2009
Pruefung iu k-2009Pruefung iu k-2009
Pruefung iu k-2009
 
Was ist der ProgrammierTrainer!
Was ist der ProgrammierTrainer!Was ist der ProgrammierTrainer!
Was ist der ProgrammierTrainer!
 
BIT I WiSe 2014 | Basisinformationstechnologie I - 08: Programmiersprachen I
BIT I WiSe 2014 | Basisinformationstechnologie I - 08: Programmiersprachen IBIT I WiSe 2014 | Basisinformationstechnologie I - 08: Programmiersprachen I
BIT I WiSe 2014 | Basisinformationstechnologie I - 08: Programmiersprachen I
 
Enterprise JS
Enterprise JS Enterprise JS
Enterprise JS
 
Erste Schritte in die neue Welt - So gelingt der Einstieg in Big Data und Mac...
Erste Schritte in die neue Welt - So gelingt der Einstieg in Big Data und Mac...Erste Schritte in die neue Welt - So gelingt der Einstieg in Big Data und Mac...
Erste Schritte in die neue Welt - So gelingt der Einstieg in Big Data und Mac...
 
PLUX.NET – SOFTWAREKOMPOSITION DURCH PLUG & PLAY
PLUX.NET – SOFTWAREKOMPOSITION DURCH PLUG & PLAYPLUX.NET – SOFTWAREKOMPOSITION DURCH PLUG & PLAY
PLUX.NET – SOFTWAREKOMPOSITION DURCH PLUG & PLAY
 
Erste Schritte in die neue Welt-So gelingt der Einstieg in Big Data und Machi...
Erste Schritte in die neue Welt-So gelingt der Einstieg in Big Data und Machi...Erste Schritte in die neue Welt-So gelingt der Einstieg in Big Data und Machi...
Erste Schritte in die neue Welt-So gelingt der Einstieg in Big Data und Machi...
 
Jtl_connect jtl_shop_evo_template_best_practices
Jtl_connect jtl_shop_evo_template_best_practicesJtl_connect jtl_shop_evo_template_best_practices
Jtl_connect jtl_shop_evo_template_best_practices
 
PLM Open Hours - Zugriffsrechte in einem globalen PDM mit verteilter Entwicklung
PLM Open Hours - Zugriffsrechte in einem globalen PDM mit verteilter EntwicklungPLM Open Hours - Zugriffsrechte in einem globalen PDM mit verteilter Entwicklung
PLM Open Hours - Zugriffsrechte in einem globalen PDM mit verteilter Entwicklung
 
Kuck mal, Node.js! Einstieg für .NET Entwickler mit Visual Studio Code und Ty...
Kuck mal, Node.js! Einstieg für .NET Entwickler mit Visual Studio Code und Ty...Kuck mal, Node.js! Einstieg für .NET Entwickler mit Visual Studio Code und Ty...
Kuck mal, Node.js! Einstieg für .NET Entwickler mit Visual Studio Code und Ty...
 
Metamodellierung und Validierung
Metamodellierung und ValidierungMetamodellierung und Validierung
Metamodellierung und Validierung
 
Erste Schritte in die neue Welt so gelingt der Einstieg in Big Data und Machi...
Erste Schritte in die neue Welt so gelingt der Einstieg in Big Data und Machi...Erste Schritte in die neue Welt so gelingt der Einstieg in Big Data und Machi...
Erste Schritte in die neue Welt so gelingt der Einstieg in Big Data und Machi...
 
Java und Python - Das Beste aus beiden Welten nutzen
Java und Python - Das Beste aus beiden Welten nutzenJava und Python - Das Beste aus beiden Welten nutzen
Java und Python - Das Beste aus beiden Welten nutzen
 
Typ-sichere DSLs
Typ-sichere DSLsTyp-sichere DSLs
Typ-sichere DSLs
 
Objektorientierte Techniken und UML
Objektorientierte Techniken und UMLObjektorientierte Techniken und UML
Objektorientierte Techniken und UML
 
C/ C++ for Notes & Domino Developers
C/ C++ for Notes & Domino DevelopersC/ C++ for Notes & Domino Developers
C/ C++ for Notes & Domino Developers
 

Mehr von Andi Albrecht

Django rest framework in 20 minuten
Django rest framework in 20 minutenDjango rest framework in 20 minuten
Django rest framework in 20 minutenAndi Albrecht
 
-getrieben. Wer treibt eigentlich die Test-Entwicklung?
-getrieben. Wer treibt eigentlich die Test-Entwicklung?-getrieben. Wer treibt eigentlich die Test-Entwicklung?
-getrieben. Wer treibt eigentlich die Test-Entwicklung?Andi Albrecht
 
sqlparse Lightning Talk
sqlparse Lightning Talksqlparse Lightning Talk
sqlparse Lightning TalkAndi Albrecht
 
Der Django-Admin-Bereich im Überblick
Der Django-Admin-Bereich im ÜberblickDer Django-Admin-Bereich im Überblick
Der Django-Admin-Bereich im ÜberblickAndi Albrecht
 
Webbrowser-Automatisierung mit Python und Selenium WebDriver
Webbrowser-Automatisierung mit Python und Selenium WebDriverWebbrowser-Automatisierung mit Python und Selenium WebDriver
Webbrowser-Automatisierung mit Python und Selenium WebDriverAndi Albrecht
 
Verbesserung der Code-"Qualität" durch statische Code-Analyse
Verbesserung der Code-"Qualität" durch statische Code-AnalyseVerbesserung der Code-"Qualität" durch statische Code-Analyse
Verbesserung der Code-"Qualität" durch statische Code-AnalyseAndi Albrecht
 

Mehr von Andi Albrecht (6)

Django rest framework in 20 minuten
Django rest framework in 20 minutenDjango rest framework in 20 minuten
Django rest framework in 20 minuten
 
-getrieben. Wer treibt eigentlich die Test-Entwicklung?
-getrieben. Wer treibt eigentlich die Test-Entwicklung?-getrieben. Wer treibt eigentlich die Test-Entwicklung?
-getrieben. Wer treibt eigentlich die Test-Entwicklung?
 
sqlparse Lightning Talk
sqlparse Lightning Talksqlparse Lightning Talk
sqlparse Lightning Talk
 
Der Django-Admin-Bereich im Überblick
Der Django-Admin-Bereich im ÜberblickDer Django-Admin-Bereich im Überblick
Der Django-Admin-Bereich im Überblick
 
Webbrowser-Automatisierung mit Python und Selenium WebDriver
Webbrowser-Automatisierung mit Python und Selenium WebDriverWebbrowser-Automatisierung mit Python und Selenium WebDriver
Webbrowser-Automatisierung mit Python und Selenium WebDriver
 
Verbesserung der Code-"Qualität" durch statische Code-Analyse
Verbesserung der Code-"Qualität" durch statische Code-AnalyseVerbesserung der Code-"Qualität" durch statische Code-Analyse
Verbesserung der Code-"Qualität" durch statische Code-Analyse
 

Metaprogrammierung, praktisch

  • 1. Metaprogrammierung, praktisch Andi Albrecht PyCon DE 2012 30. Oktober 2012 Hintergrund Ein paar Konzepte Use-Cases Sinn oder Unsinn? ... ..... ..... Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
  • 2. Andi Albrecht – @andialbrecht Erster Python-Kontakt vor etwa 10 Jahren als Studentische Hilfskraft bei der DFG Aktuell: Anwendungsentwickler für Webapplikationen bei ProUnix in Bonn Entwicklung und Pflege mittlerer und großer Systeme OpenSource: Rietveld Code Review Tool, python-sqlparse, CrunchyFrog, hgsvn, ... Hintergrund Ein paar Konzepte Use-Cases Sinn oder Unsinn? ... ..... ..... Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
  • 3. Übersicht Hintergrund Ein paar Konzepte Use-Cases Sinn oder Unsinn? Hintergrund Ein paar Konzepte Use-Cases Sinn oder Unsinn? ... ..... ..... Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
  • 4. Hintergrund Was ist Metaprogrammierung? "Programmierung der Programmierung" "Programmcode erzeugt|untersucht|… Programmcode" "Programmcode wird zu Objekten von anderem (Meta-)Programmcode" Hintergrund Ein paar Konzepte Use-Cases Sinn oder Unsinn? ... ..... ..... Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
  • 5. Hintergrund Was ist Metaprogrammierung? "Programmierung der Programmierung" "Programmcode erzeugt|untersucht|… Programmcode" "Programmcode wird zu Objekten von anderem (Meta-)Programmcode" mysterious, strange, weird, mind-blowing, … Hintergrund Ein paar Konzepte Use-Cases Sinn oder Unsinn? ... ..... ..... Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
  • 6. Hintergrund Was ist Metaprogrammierung? "Programmierung der Programmierung" "Programmcode erzeugt|untersucht|… Programmcode" "Programmcode wird zu Objekten von anderem (Meta-)Programmcode" mysterious, strange, weird, mind-blowing, … Meta-: jenseits, dahinter liegend, … Hintergrund Ein paar Konzepte Use-Cases Sinn oder Unsinn? ... ..... ..... Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
  • 7. Hintergrund Metaklassen in Python Wohl bekannteste Form der Metaprogrammierung in Python Möglichkeiten zur Modifikation von Klassen schon in 1995 als C-Extension möglich (Don Beaudry Hook) Ab Python 1.5 auch ohne C-Extension∗ Echter Support für Metaklassen mit New-Style-Classes in Python 2.2 * dazu: Essay von GvR "Metaclasses in Python 1.5 (a.k.a. The Killer Joke)" http://www.python.org/doc/essays/metaclasses/ http://python-history.blogspot.de/2009/04/metaclasses-and-extension-classes-aka.html Hintergrund Ein paar Konzepte Use-Cases Sinn oder Unsinn? ... ..... ..... Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
  • 8. Hintergrund Metaklassen in Python Python 1995: C-Extension Python 2.2 Python 1.5 class Foo(object): class Tracing: __metaclass__ = MyMetaclass def __init__(self, name, bases, namespace): def __call__(self): Python 3 class Instance: def __init__(self, klass): def __getattr__(self, name): class Foo(metaclass=MyMetaclass): pass class BoundMethod: def __init__(self, function, instance): def __call__(self, *args): Trace = Tracing(’Trace’, (), ) class MyTracedClass(Trace): def method1(self, a): Hintergrund Ein paar Konzepte Use-Cases Sinn oder Unsinn? ... ..... ..... Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
  • 9. Konzepte Metaprogrammierung in Python Types Metaklassen Dekoratoren Code-Generierung zur Laufzeit (synthetische Funktionen/Klassen) ... Hintergrund Ein paar Konzepte Use-Cases Sinn oder Unsinn? ... ..... ..... Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
  • 10. Konzepte type() type(object) → liefert Typ des Objekts type(name, bases, namespace) → erzeugt einen neuen Typ > def my_func(self): . return 42 > Question = type(’Question’, (), {’answer’: my_func}) > Question().answer() < 42 Hintergrund Ein paar Konzepte Use-Cases Sinn oder Unsinn? ... ..... ..... Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
  • 11. Konzepte types-Modul import types # Modul erzeugen my_mod = types.ModuleType(’foo’, ’doc string’) my_mod.foo = my_func sys.modules[’heyho’] = my_mod import heyho heyho.foo() # Methode erzeugen def answer(self): return 42 class Foo(object): pass foo1 = Foo() foo2 = Foo() foo1.answer = types.MethodType(answer, foo1) foo1.answer() # gibt 42 zurück foo2.answer() # wirft einen AttributeError Hintergrund Ein paar Konzepte Use-Cases Sinn oder Unsinn? ... ..... ..... Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
  • 12. Konzepte Metaklassen Metaklassen modifizieren Klassen Metaklassen können Meta-Funktionen haben Beispiel für Einsatzzwecke: neue Typen von Klassen neues Verhalten von Klassen Automatisierungen Registrierung von Klassen Frameworks, ORMs Introspektion, QA Hintergrund Ein paar Konzepte Use-Cases Sinn oder Unsinn? ... ..... ..... Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
  • 13. Konzepte Metaklassen, Beispiel class PluginRegistry(type): registry = {} def __new__(mcls, name, bases, classdict): return type.__new__(mcls, name, bases, classdict) def __init__(cls, name, bases, namespace): PluginRegistry.register(cls) return super(PluginRegistery, cls).__init__(name, bases, namespace) @classmethod def register(mcls, cls): mcls.registry[cls.__name__] = cls @classmethod def get_all(cls): return cls.registry class Foo(metaclass=PluginRegistry): pass class Bar(metaclass=PluginRegistry): pass PluginRegistry.get_all() # –> gibt {’Foo’: <class Foo>, ’Bar’: <class Bar>} zurück Foo.get_all() # –> gibt {’Foo’: <class Foo>, ’Bar’: <class Bar>} zurück Foo().get_all() # –> AttributeError Hintergrund Ein paar Konzepte Use-Cases Sinn oder Unsinn? ... ..... ..... Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
  • 14. Konzepte Klassendekoratoren, Definition zur Laufzeit, ... Klassendekoratoren Monkey-Patching import amodule @my_classdecorator class Foo(object): def better_func(): pass print(’This is better!’) return None Code-Generierung zur Laufzeit amodule.func = better_func namespace = {} ... exec(”””def answer(): return 42”””, namespace) namespace[’answer’]() # 42 aber exec lieber vermeiden! Hintergrund Ein paar Konzepte Use-Cases Sinn oder Unsinn? ... ..... ..... Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
  • 15. Use-Cases Enum-Implementierung mit type (Erstellung neuer Typen) ORM-API mit Metaklassen (Framework / ORM) Aufbau einer Testmatrix (Automatisierung) Hintergrund Ein paar Konzepte Use-Cases Sinn oder Unsinn? ... ..... ..... Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
  • 16. Use-Cases Enums def enum(**enums): return type(’Enum’, (), enums) > Numbers = enum(ONE=1, TWO=2, THREE=’three’) > Numbers.ONE 1 > Numbers.TWO 2 > Numbers.THREE ’three’ def enum(name, *sequential): enums = dict(x[::-1] for x in enumerate(sequential)) return type(name, (), enums) > Colors = enum(’Colors’, ’RED’, ’GREEN’, ’BLUE’) > Colors.RED 0 Siehe http://stackoverflow.com/a/1695250/97167 Hintergrund Ein paar Konzepte Use-Cases Sinn oder Unsinn? ... ..... ..... Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
  • 17. Use-Cases Django-Models from django.db import model class Book(model.Model): author = models.CharField(max_length=200) title = models.CharField(max_length=200) year = models.IntegerField() class Meta: verbose_name_plural = u’Books’ Hintergrund Ein paar Konzepte Use-Cases Sinn oder Unsinn? ... ..... ..... Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
  • 18. Use-Cases Django-Models from django.db import model class Book(model.Model): author = models.CharField(max_length=200) title = models.CharField(max_length=200) year = models.IntegerField() class Meta: verbose_name_plural = u’Books’ ...und was Django's Metaklasse macht (unter anderem): verschiebt "Meta" nach "_meta" und erstellt eigenes Objekt fügt neue DoesNotExist/MultipleObjectsReturned-Attribute hinzu ergänzt einen Record-Manager als "objects"-Attribut wertet die gegebenen Attribute (Namespace) aus und macht sie fit zur Verwendung mit einer DB ... Hintergrund Ein paar Konzepte Use-Cases Sinn oder Unsinn? ... ..... ..... Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
  • 19. Use-Cases Test-Matrix class ApiTestCase(unittest.TestCase, metaclass=TestMatrixMeta): apicalls = ( (’/user/1’, ’GET’, {’name’: ’foo’}), (’/user/1/locations’, ’GET’, [’Leipzig’,]), ) python3 testmatrix.py -v test__user_1_json (__main__.test__user_1_locations_xml) ... ok test__user_1_locations_json (__main__.test__user_1_locations_xml) ... ok test__user_1_locations_xml (__main__.test__user_1_locations_xml) ... FAIL test__user_1_xml (__main__.test__user_1_locations_xml) ... ok ====================================================================== FAIL: test__user_1_locations_xml (__main__.test__user_1_locations_xml) ———————————————————————- Traceback (most recent call last): File ”testmatrix.py”, line 17, in test_wrapper self.assertFalse(u==’/user/1/locations’ and c == ’xml’) AssertionError: True is not false ———————————————————————- Ran 4 tests in 0.001s FAILED (failures=1) Hintergrund Ein paar Konzepte Use-Cases Sinn oder Unsinn? ... ..... ..... Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
  • 20. Use-Cases Test-Matrix class TestMatrixMeta(type): def __new__(mcls, name, bases, attrs): apicalls = attrs.pop(’apicalls’, []) for url, method, expected in apicalls: for ctype in (’json’, ’xml’): name = ’test_%s_%s’ % (url.replace(’/’, ’_’), ctype) attrs[name] = mcls.build_test(name, url, method, expected, ctype) new_cls = type.__new__(mcls, name, bases, attrs) return new_cls @classmethod def build_test(cls, name, url, method, expected, ctype): def test_wrapper(self, u=url, m=method, e=expected, c=ctype): self.assertFalse(u==’/user/1/locations’ and c == ’xml’) test_wrapper.__name__ = name return test_wrapper class ApiTestCase(unittest.TestCase, metaclass=TestMatrixMeta): apicalls = ( (’/user/1’, ’GET’, {’name’: ’foo’}), (’/user/1/locations’, ’GET’, [’Leipzig’,]), ) Hintergrund Ein paar Konzepte Use-Cases Sinn oder Unsinn? ... ..... ..... Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
  • 21. Sinn oder Unsinn? Für (fast) alles gibt es auch einen andere Lösung Debugging wird teils schwieriger, Fehlverhalten nicht immer transparent Verwendung des Codes wird für End-Entwickler eleganter Leichte Erweiterung der Sprache um spezielle Paradigmen, Funktionen, Verhalten, Qualitätsrichtlinien, … → Metaprogrammierung gezielt einsetzen → Einsatz transparent machen Hintergrund Ein paar Konzepte Use-Cases Sinn oder Unsinn? ... ..... ..... Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012
  • 22. Danke! E-Mail albrecht@prounix.de albrecht.andi@gmail.com Twitter @andialbrecht Homepage http://andialbrecht.de http://www.prounix.de/unternehmen/jobs/python/ prounix.de Hintergrund Ein paar Konzepte Use-Cases Sinn oder Unsinn? ... ..... ..... Metaprogrammierung, praktisch / Andi Albrecht / PyCon DE 2012