SlideShare ist ein Scribd-Unternehmen logo
1 von 60
Downloaden Sie, um offline zu lesen
Dynamic OOP and Meta-Classes in Python

                                  Guy Wiener

                   Dept. of Applied Math and Computer Science
                          Weizmann Institute for Science


                                   24/5/2011




Guy Wiener (WIS)         Dynamic OOP and Meta-Classes in Python   24/5/2011   1 / 57
Introduction



Outline


1   Introduction

2   OOP Hacking

3   Meta-Classes

4   Examples

5   Summary



     Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   2 / 57
Introduction



What is OOP?

The OOP Manifest (abridged)
Alan Kay, 1993
    Everything is an object
    Computation is performed by objects communicating with each
    other by sending and receiving messages
    Each object has its own memory (state), which consists of other
    objects.
    Every object is an instance of a class.
    The class is the repository for behavior. All instances of the
    same class can perform the same actions.
    Classes are organized into a singly rooted tree, called the
    inheritance hierarchy.
    Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   3 / 57
Introduction



What is an object?



An object, according to the OOP manifest:
     State Memory
  Behavior Receiving and sending messages
   Identity Each object is unique




   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   4 / 57
Introduction



Objects Can Change!



Changing objects
     State Read, write, add and remove field
  Behavior Create, add and replace methods
   Identity Remains the same




   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   5 / 57
Introduction



Static Objects and Classes

Objects and Classes                             Example
           Class                                       A
     Field descriptors                           x: int
  Method desc. and code                          y: String
  Hierarchy information                          foo() {. . . }
                                                 goo() {. . . }
                       Object
 Run-time
                       Fields                                  Instance of A
 type infor-
                       content                                     5
 mation
                                                                   “hello”
    Guy Wiener (WIS)       Dynamic OOP and Meta-Classes in Python        24/5/2011   6 / 57
Introduction



Dynamic Objects and Classes

Objects and Classes                            Example
      Class                                           A
  A dictionary                                  “foo” ⇒ {. . . }
  of methods
                                                “goo” ⇒ {. . . }
  and static
  fields
                                                                   Instance of A
                       Object                                      “x” ⇒ 5
                 A dictionary of                                   “y” ⇒ “hello”
 Class
                 fields and bound
 pointer
                 methods

    Guy Wiener (WIS)      Dynamic OOP and Meta-Classes in Python         24/5/2011   7 / 57
OOP Hacking



Outline


1   Introduction

2   OOP Hacking

3   Meta-Classes

4   Examples

5   Summary



     Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   8 / 57
OOP Hacking



Everything is a Dictionary


Python’s modules, classes and objects = Dictionaries.
The dictionary holds:
    Classes Methods and class variables
    Objects Bound methods and fields

    The “.” operator = Access the inner dictionary
    The dir command = Lists keys of the inner dictionary




    Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   9 / 57
OOP Hacking



Manipulating the Inner Dictionary


The inner dictionary is accessible and manipulable by string keys!
Inner dictionary manipulation
   getattr(o, ’a’)      Get the attribute a from the dictionary of o
setattr(o, ’a’, v)      Set the attribute a of o to be v
           obj.foo      is same as getattr(obj, ’foo’)
     obj.foo = val      is same as setattr(obj, ’foo’, val)




    Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   10 / 57
OOP Hacking



Manipulating the Inner Dictionary (cont’d)


Example
>>> a = A()
>>> a.x = 5
>>> dir(a)
[..., ’x’]
>>> getattr(a, ’x’)
5
>>> setattr(a, ’x’, 6)
>>> a.x
6



   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   11 / 57
OOP Hacking



Adding Fields


 Adding fields to an object
 class A: pass
 >>> a = A()
 >>> a.x = 5
 >>> a.x
 5
 >>> setattr(a, ’y’, 6)
 >>> a.y
 6



   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   12 / 57
OOP Hacking



Adding Fields


 Adding fields to an object                  Gain & Loss
 class A: pass                              Gained Flexible object content
 >>> a = A()                                  Lost Type safety
 >>> a.x = 5
 >>> a.x
 5
 >>> setattr(a, ’y’, 6)
 >>> a.y
 6



   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python    24/5/2011   12 / 57
OOP Hacking



Replacing Methods

 Swapping methods
 class A:
   def f(self):
     print "f"
   def g(self):
     print "g"
 >>> a = A()
 >>> a.f, a.g = a.g, a.f
 >>> a.f()
 g
 >>> a.g()
 f

   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   13 / 57
OOP Hacking



Replacing Methods

 Swapping methods                           Gain & Loss
 class A:                                   Gained Change an object
   def f(self):                                    behavior at runtime
     print "f"                                Lost Control flow analysis
   def g(self):
     print "g"
 >>> a = A()
 >>> a.f, a.g = a.g, a.f
 >>> a.f()
 g
 >>> a.g()
 f

   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   13 / 57
OOP Hacking



Replacing Methods for a Class

 Swapping class methods
 class A:
   def f(self):
     print "f"
   def g(self):
     print "g"
 >>> a = A()
 >>> A.f, A.g = A.g, A.f
 >>> a.f()
 g
 >>> a.g()
 f

   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   14 / 57
OOP Hacking



Replacing Methods for a Class

 Swapping class methods                     Gain & Loss
 class A:                                   Gained Change a class at
   def f(self):                                    runtime
     print "f"                                Lost Sanity
   def g(self):
     print "g"
 >>> a = A()
 >>> A.f, A.g = A.g, A.f
 >>> a.f()
 g
 >>> a.g()
 f

   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   14 / 57
OOP Hacking



Classes are Return Values Too


A function that returns a class
def PersonClass(salut):
    class Person(object):
        def __init__(self, name):
            self.name = name
        def greet(self):
            print salut, self.name
    return Person




   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   15 / 57
OOP Hacking



Classes are Return Values Too (cont’d)


Making classes                              Output
Man = PersonClass("Mr.")                    for c in a: c.greet()
Woman = PersonClass("Ms.")
Doctor = PersonClass("Dr.")                 >>>     Ms. Rose Tylar
                                            Ms.     Amy Pond
a = [Woman("Rose Tylar"),                   Mr.     Mickey Smith
     Woman("Amy Pond"),                     Mr.     Rory Williams
     Man("Mickey Smith"),                   Dr.     Who
     Man("Rory Williams"),
     Doctor("Who")]


   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python    24/5/2011   16 / 57
Meta-Classes



Outline


1   Introduction

2   OOP Hacking

3   Meta-Classes

4   Examples

5   Summary



     Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   17 / 57
Meta-Classes



What is Meta-Programming?
Meta-Program
A program that:
    One of its inputs is a program (possibly itself)
    Its output is a program




    Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   18 / 57
Meta-Classes



What is Meta-OOP?



Meta-Class
A class that creates classes
     Objects are instances of classes
     Classes are objects
     Classes are instances of meta-classes




    Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   19 / 57
Meta-Classes



Object Systems

3-levels                                       4-levels
             Object                                             Object


  A Class                Type                    A Class                    Type
                      super: Type[]
                                                                         super: Type[]
 An Object
                                               An Object
                                                                     A MetaClass
Legend
       instance of
       extends

   Guy Wiener (WIS)        Dynamic OOP and Meta-Classes in Python            24/5/2011   20 / 57
Meta-Classes   Meta-Classes in Python



Outline

1   Introduction
2   OOP Hacking
3   Meta-Classes
     Meta-Classes in Python
4   Examples
      Logging
      Counting
      Delegation
      Associations
5   Summary

     Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python       24/5/2011   21 / 57
Meta-Classes   Meta-Classes in Python



Meta-Classes in Python

The type class
    Base class for meta-classes
    Creates new classes
    Dynamic members become static members of the instance class

type. init (cls, name, bases, dict)
  cls   The class object itself (i.e., “self”)
name    The name of the class
bases   A list of the base classes
 dict   A dictionary of the methods and static fields of the class


    Guy Wiener (WIS)    Dynamic OOP and Meta-Classes in Python       24/5/2011   22 / 57
Meta-Classes   Meta-Classes in Python



Creating Classes from Meta-Classes

Declaring a new class programatically
# Meta-Class
class Printable(type):
    def whoami(self): print "I am ", self.__name__

>>> Foo = Printable(’Foo’,(),{}) # Empty new class
>>> Foo.whoami()
I am Foo
>>> Foo.__class__
<class ’Printable’>
>>> f = Foo() # Object
>>> f.__class__
<class ’Foo’>

   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python       24/5/2011   23 / 57
Meta-Classes   Meta-Classes in Python



The       metaclass              field



Class C is an instance of a meta-class M if:
 1    C has a static field metaclass
 2    One of the ancestors classes of C is an instance of M
 3    There is a global variable metaclass
 4    Otherwise, the default meta-class type is used




     Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python       24/5/2011   24 / 57
Meta-Classes   Meta-Classes in Python



 metaclass            Example


Declaring a meta-class with                metaclass
class Bar:
    __metaclass__ = Printable
    def foo(self): print ’foo’

>>> Bar.whoami()
I am a Bar
>>> b = Bar()
>>> b.foo()
foo



   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python       24/5/2011   25 / 57
Examples



Outline


1   Introduction

2   OOP Hacking

3   Meta-Classes

4   Examples

5   Summary



     Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   26 / 57
Examples   Logging



Outline

1   Introduction
2   OOP Hacking
3   Meta-Classes
     Meta-Classes in Python
4   Examples
      Logging
      Counting
      Delegation
      Associations
5   Summary

     Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   27 / 57
Examples   Logging



Logging with Meta-Classes



A logger decorator
def log(name, f):
    def ret(*args):
        print "enter", name
        f(*args)
        print "exit", name
    return ret




   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   28 / 57
Examples   Logging



Logging with Meta-Classes (cont’d)


A logger meta-class
class Logged(type):
    def init (cls, name, bases, dict):
        type. init (cls, name, bases, dict)
        p = re.compile(cls. logmatch )
        for attr, item in dict.items():
            if callable(item) and p.match(attr):
                setattr(cls, attr, log(attr, item))




   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   29 / 57
Examples   Logging



Logging with Meta-Classes (cont’d)

A logged class
class Test:
     metaclass = Logged
     logmatch = ’.*’
    def foo(self):
        print ’foo’

>>> t = Test()
>>> t.foo()
enter foo
foo
exit foo

   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   30 / 57
Examples   Counting



Outline

1   Introduction
2   OOP Hacking
3   Meta-Classes
     Meta-Classes in Python
4   Examples
      Logging
      Counting
      Delegation
      Associations
5   Summary

     Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   31 / 57
Examples   Counting



Counting Instances

Countable meta-class
class Countable(type):
    def new_init(cls, init):
        def ret(self, *args):
            init(self, *args)
            cls.count = cls.count + 1
        return ret

    def __init__(cls, name, bases, dct):
        type.__init__(cls, name, bases, dct)
        cls.count = 0
        cls.__init__ = cls.new_init(cls.__init__)

   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   32 / 57
Examples   Counting



Counting Example

Some classes
class Person:
    __metaclass__ = Countable
    def __init__(self, name):
        self.name = name

class Book:
    __metaclass__ = Countable
    def __init__(self, name, author):
        self.name = name
        self.author = author


   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   33 / 57
Examples   Counting



Counting Example (cont’d)



Testing
rah = Person("Robert Anson Heinlin")
b1 = Book("Stranger in a Strange Land", rah)
b2 = Book("Starship Troopers", rah)

print Person.count, Book.count
>>> 1 2




   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   34 / 57
Examples   Delegation



Outline

1   Introduction
2   OOP Hacking
3   Meta-Classes
     Meta-Classes in Python
4   Examples
      Logging
      Counting
      Delegation
      Associations
5   Summary

     Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   35 / 57
Examples   Delegation



Automatic Delegation

Delegate


 An object of class A that
 dispatches all message of
 class B to a target field of
 type B.



    Writing a delegate class is a monotonous work
    But it can be done automatically

    Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   36 / 57
Examples   Delegation



Delegation Using Meta-Classes

A delegation function decorator
def dlgt(cls, method):
    def ret(self, *args):
        method(self.__tgt__, *args)
    return instancemethod(ret, None, cls)
instancemethod takes a function, an object/None and a class and
returns a method of the class
Auxiliary – Print class name
def clsname(self):
    return self.__class__.__name__


    Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   37 / 57
Examples   Delegation



Delegation Using Meta-Classes (cont’d)


The Delegate meta-class
class Delegate(type):
    def __init__(cls, name, bases, dict):
        type.__init__(cls, name, bases, dict)
        tgtclass = cls.__tgtclass__
        for name in dir(tgtclass):
            val = getattr(tgtclass, name)
            if callable(val):
                setattr(cls, name, dlgt(cls, val))




   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   38 / 57
Examples   Delegation



Delegation Using Meta-Classes (cont’d)



The delegated class
class A:
    def bar(self):
         print clsname(self), ’bar’
    def baz(self):
         print clsname(self), ’baz’




   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   39 / 57
Examples   Delegation



Delegation Using Meta-Classes (cont’d)


The delegating class
class B:
     metaclass = Delegate
     tgtclass = A
    def init (self, tgt):
         self. tgt = tgt
    def boo(self):
         print clsname(self), ’boo’




   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   40 / 57
Examples   Delegation



Delegation Using Meta-Classes (cont’d)


Delegation test
>>> b = B(A())
>>> b.bar()
A bar
>>> b.baz()
A baz
>>> b.boo()
B boo




   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   41 / 57
Examples   Delegation



Simplified Syntax for with Meta-Classes with Args.
Thanks to Yoav Goldberg




Use a function to create the meta-class
def delegate_of(tgtclass):
    class Delegate(type):
        def __init__(cls, name, bases, dict):
            type.__init__(cls, name, bases, dict)
            for name in dir(tgtclass):
                val = getattr(tgtclass, name)
                if callable(val):
                    setattr(cls, name, dlgt(cls,val))



     Guy Wiener (WIS)     Dynamic OOP and Meta-Classes in Python   24/5/2011   42 / 57
Examples   Delegation



Simplified Syntax for Meta-Classes with Args.
Thanks to Yoav Goldberg




Use the function to generate a meta-class
class B:
     metaclass = delegate_of(A)
    def init (self, tgt):
         self. tgt = tgt
    def boo(self):
         print clsname(self), ’boo’




     Guy Wiener (WIS)     Dynamic OOP and Meta-Classes in Python   24/5/2011   43 / 57
Examples   Associations



Outline

1   Introduction
2   OOP Hacking
3   Meta-Classes
     Meta-Classes in Python
4   Examples
      Logging
      Counting
      Delegation
      Associations
5   Summary

     Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   44 / 57
Examples   Associations



Associations


                            0..m           ab         0..n
                      A     myA                       myB
                                                                   B

Goals
   Aggregation operations, like
       a.getMyB().foreach().g()
       r = b.getMyA().filter().f().map().h()
   Optimizations: Multithreading, caching
   No textual code generation


   Guy Wiener (WIS)       Dynamic OOP and Meta-Classes in Python       24/5/2011   45 / 57
Examples   Associations



Basic Aggregation
Replace all public methods with an aggregator wrapper
class Aggr(type):
  def __init__(cls, name, bases, dct):
    p = re.compile(’__.*__’)
    type.__init__(cls, name, bases, {})
    for key, item in dct.iteritems():
      if callable(item) and not p.match(key):
        m = instancemethod(cls.wrap(item), None, self)
        setattr(self, key, m)

  def wrap(cls, func):
    def ret(self, *args):
      return self.__aggr__(func, *args)
    return ret
   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   46 / 57
Examples   Associations



Basic Aggregation (cont’d)
Make aggrs. that extend impl and wrap ifce
class ListAggr(Aggr):
  @staticmethod
  def make(name, impl, ifce):
    dct = {}
    for key in dir(ifce):
      dct[key] = getattr(ifce, key)
    return ListAggr(name, (impl,), dct)

  def __init__(self, name, bases, dct):
    Aggr.__init__(self, name, bases, dct)
    base = bases[0]
    ctr = base.__init__ % Use impl’s constructor
    self.__init__ = instancemethod(ctr, None, self)
   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   47 / 57
Examples   Associations



List-Based Sequential Aggrs.



Store list in private field
class ListFunc(object):
  def __init__(self, data):
    self.__data__ = data
  def onAdd(self, other): pass
  def onRemove(self, other): pass




    Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   48 / 57
Examples   Associations



List-Based Sequential Aggrs. (cont’d)



Sequential Foreach
class ListSeqForeach(ListFunc):
  def __init__(self, data):
    ListFunc.__init__(self, data)
  def __aggr__(self, func, *args):
    for inst in self.__data__:
      func(inst, *args)




   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   49 / 57
Examples   Associations



List-Based Sequential Aggrs. (cont’d)


Sequential Map
class ListSeqMap(ListFunc):
  def __init__(self, data):
    ListFunc.__init__(self, data)
  def __aggr__(self, func, *args):
    ret = []
    for inst in self.__data__:
      ret.append(func(inst, *args))
    return ret



   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   50 / 57
Examples   Associations



Binding It Together

Making an aggr. that extends seq. foreach
def makeForeachClass(cls):
  return ListAggr.make(’...’, ListSeqForeach, cls)

                            ListFunc                            Aggr

                       ListSeqForeach                          ListAggr


                      cls                  ForeachClass



   Guy Wiener (WIS)         Dynamic OOP and Meta-Classes in Python        24/5/2011   51 / 57
Examples   Associations



Optimizations

Multithreaded Foreach
class ListSpawnForeach(ListFunc):
  def __init__(self, data):
    ListFunc.__init__(self, data)
  def __aggr__(self, func, *args):
    n = max(len(self.__data__)/K, 1)
    ts = []
    for c in chunks(self.__data__, n):
      t = ForeachThread(c, func, args)
      ts.append(t)
      t.start()
      for tr in ts: tr.join()

   Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   52 / 57
Examples   Associations



Binding It Together, Multithreaded Version

Making an aggr. that extends parallel foreach
def makeForeachClass(cls):
  return ListAggr.make(’...’, ListSpawnForeach, cls)

                            ListFunc                            Aggr

                      ListSpawnForeach                         ListAggr


                      cls                   ForeachClass



   Guy Wiener (WIS)         Dynamic OOP and Meta-Classes in Python        24/5/2011   53 / 57
Examples   Associations



Links



Download complete code
http://www.cs.bgu.ac.il/~gwiener/software/associations/

Read full paper
Proceedings of ENASE’2010 / By request




    Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   54 / 57
Summary



Outline


1   Introduction

2   OOP Hacking

3   Meta-Classes

4   Examples

5   Summary



     Guy Wiener (WIS)   Dynamic OOP and Meta-Classes in Python   24/5/2011   55 / 57
Summary



Advantages of Meta-Classes

Turn this. . .                                             Into this

                    P   haarazu-Urh
                 os                a
            cr




                                   -Y
  eku Uru-Ne




                                      tah
                                          i Ia Dai-Uk
        -W
     ka




                                                     a-



                 Ha
                   kal         -U
                       Tru-Saka



    Guy Wiener (WIS)             Dynamic OOP and Meta-Classes in Python   24/5/2011   56 / 57
Summary




                    Thank You!


                   wiener.guy@gmail.com




Guy Wiener (WIS)      Dynamic OOP and Meta-Classes in Python   24/5/2011   57 / 57

Weitere ähnliche Inhalte

Was ist angesagt? (20)

Java- Nested Classes
Java- Nested ClassesJava- Nested Classes
Java- Nested Classes
 
Inheritance in c++
Inheritance in c++Inheritance in c++
Inheritance in c++
 
Nested class in java
Nested class in javaNested class in java
Nested class in java
 
Abstract Class Presentation
Abstract Class PresentationAbstract Class Presentation
Abstract Class Presentation
 
Object Oriented Programming with C#
Object Oriented Programming with C#Object Oriented Programming with C#
Object Oriented Programming with C#
 
Inner classes in java
Inner classes in javaInner classes in java
Inner classes in java
 
Inheritance C#
Inheritance C#Inheritance C#
Inheritance C#
 
Oops concept on c#
Oops concept on c#Oops concept on c#
Oops concept on c#
 
Polymorphism In Java
Polymorphism In JavaPolymorphism In Java
Polymorphism In Java
 
Java(Polymorphism)
Java(Polymorphism)Java(Polymorphism)
Java(Polymorphism)
 
Inheritance and Polymorphism
Inheritance and PolymorphismInheritance and Polymorphism
Inheritance and Polymorphism
 
Polymorphism in Java by Animesh Sarkar
Polymorphism in Java by Animesh SarkarPolymorphism in Java by Animesh Sarkar
Polymorphism in Java by Animesh Sarkar
 
Super keyword in java
Super keyword in javaSuper keyword in java
Super keyword in java
 
itft-Inheritance in java
itft-Inheritance in javaitft-Inheritance in java
itft-Inheritance in java
 
Inheritance in Java
Inheritance in JavaInheritance in Java
Inheritance in Java
 
Classes and objects in c++
Classes and objects in c++Classes and objects in c++
Classes and objects in c++
 
06. operator overloading
06. operator overloading06. operator overloading
06. operator overloading
 
Inheritance in java
Inheritance in javaInheritance in java
Inheritance in java
 
Templates in C++
Templates in C++Templates in C++
Templates in C++
 
Python programming : Abstract classes interfaces
Python programming : Abstract classes interfacesPython programming : Abstract classes interfaces
Python programming : Abstract classes interfaces
 

Ähnlich wie Meta-Classes in Python

Ähnlich wie Meta-Classes in Python (20)

A Featherweight Approach to FOOL
A Featherweight Approach to FOOLA Featherweight Approach to FOOL
A Featherweight Approach to FOOL
 
Dynamic Python
Dynamic PythonDynamic Python
Dynamic Python
 
From Java to Python: beating the Stockholm syndrome
From Java to Python: beating the Stockholm syndromeFrom Java to Python: beating the Stockholm syndrome
From Java to Python: beating the Stockholm syndrome
 
Py jail talk
Py jail talkPy jail talk
Py jail talk
 
Wrapper classes
Wrapper classes Wrapper classes
Wrapper classes
 
Modern Compiler Design
Modern Compiler DesignModern Compiler Design
Modern Compiler Design
 
Class1
Class1Class1
Class1
 
Class
ClassClass
Class
 
บทที่ 6 คลาสและการเขียนโปรแกรม
บทที่ 6 คลาสและการเขียนโปรแกรมบทที่ 6 คลาสและการเขียนโปรแกรม
บทที่ 6 คลาสและการเขียนโปรแกรม
 
About Python
About PythonAbout Python
About Python
 
1_7a6f85d03f132dcd9d7592bc4643be1c_MIT6_0001F16_Lec8.pdf
1_7a6f85d03f132dcd9d7592bc4643be1c_MIT6_0001F16_Lec8.pdf1_7a6f85d03f132dcd9d7592bc4643be1c_MIT6_0001F16_Lec8.pdf
1_7a6f85d03f132dcd9d7592bc4643be1c_MIT6_0001F16_Lec8.pdf
 
JS-02-JavaScript-Objects.ppt
JS-02-JavaScript-Objects.pptJS-02-JavaScript-Objects.ppt
JS-02-JavaScript-Objects.ppt
 
Ti1220 Lecture 7: Polymorphism
Ti1220 Lecture 7: PolymorphismTi1220 Lecture 7: Polymorphism
Ti1220 Lecture 7: Polymorphism
 
Dive into Python Class
Dive into Python ClassDive into Python Class
Dive into Python Class
 
Java tutorial part 3
Java tutorial part 3Java tutorial part 3
Java tutorial part 3
 
Scala: A brief tutorial
Scala: A brief tutorialScala: A brief tutorial
Scala: A brief tutorial
 
Python tour
Python tourPython tour
Python tour
 
Lecture20 vector
Lecture20 vectorLecture20 vector
Lecture20 vector
 
Python3
Python3Python3
Python3
 
Chap 3 Python Object Oriented Programming - Copy.ppt
Chap 3 Python Object Oriented Programming - Copy.pptChap 3 Python Object Oriented Programming - Copy.ppt
Chap 3 Python Object Oriented Programming - Copy.ppt
 

Meta-Classes in Python

  • 1. Dynamic OOP and Meta-Classes in Python Guy Wiener Dept. of Applied Math and Computer Science Weizmann Institute for Science 24/5/2011 Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 1 / 57
  • 2. Introduction Outline 1 Introduction 2 OOP Hacking 3 Meta-Classes 4 Examples 5 Summary Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 2 / 57
  • 3. Introduction What is OOP? The OOP Manifest (abridged) Alan Kay, 1993 Everything is an object Computation is performed by objects communicating with each other by sending and receiving messages Each object has its own memory (state), which consists of other objects. Every object is an instance of a class. The class is the repository for behavior. All instances of the same class can perform the same actions. Classes are organized into a singly rooted tree, called the inheritance hierarchy. Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 3 / 57
  • 4. Introduction What is an object? An object, according to the OOP manifest: State Memory Behavior Receiving and sending messages Identity Each object is unique Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 4 / 57
  • 5. Introduction Objects Can Change! Changing objects State Read, write, add and remove field Behavior Create, add and replace methods Identity Remains the same Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 5 / 57
  • 6. Introduction Static Objects and Classes Objects and Classes Example Class A Field descriptors x: int Method desc. and code y: String Hierarchy information foo() {. . . } goo() {. . . } Object Run-time Fields Instance of A type infor- content 5 mation “hello” Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 6 / 57
  • 7. Introduction Dynamic Objects and Classes Objects and Classes Example Class A A dictionary “foo” ⇒ {. . . } of methods “goo” ⇒ {. . . } and static fields Instance of A Object “x” ⇒ 5 A dictionary of “y” ⇒ “hello” Class fields and bound pointer methods Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 7 / 57
  • 8. OOP Hacking Outline 1 Introduction 2 OOP Hacking 3 Meta-Classes 4 Examples 5 Summary Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 8 / 57
  • 9. OOP Hacking Everything is a Dictionary Python’s modules, classes and objects = Dictionaries. The dictionary holds: Classes Methods and class variables Objects Bound methods and fields The “.” operator = Access the inner dictionary The dir command = Lists keys of the inner dictionary Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 9 / 57
  • 10. OOP Hacking Manipulating the Inner Dictionary The inner dictionary is accessible and manipulable by string keys! Inner dictionary manipulation getattr(o, ’a’) Get the attribute a from the dictionary of o setattr(o, ’a’, v) Set the attribute a of o to be v obj.foo is same as getattr(obj, ’foo’) obj.foo = val is same as setattr(obj, ’foo’, val) Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 10 / 57
  • 11. OOP Hacking Manipulating the Inner Dictionary (cont’d) Example >>> a = A() >>> a.x = 5 >>> dir(a) [..., ’x’] >>> getattr(a, ’x’) 5 >>> setattr(a, ’x’, 6) >>> a.x 6 Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 11 / 57
  • 12. OOP Hacking Adding Fields Adding fields to an object class A: pass >>> a = A() >>> a.x = 5 >>> a.x 5 >>> setattr(a, ’y’, 6) >>> a.y 6 Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 12 / 57
  • 13. OOP Hacking Adding Fields Adding fields to an object Gain & Loss class A: pass Gained Flexible object content >>> a = A() Lost Type safety >>> a.x = 5 >>> a.x 5 >>> setattr(a, ’y’, 6) >>> a.y 6 Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 12 / 57
  • 14. OOP Hacking Replacing Methods Swapping methods class A: def f(self): print "f" def g(self): print "g" >>> a = A() >>> a.f, a.g = a.g, a.f >>> a.f() g >>> a.g() f Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 13 / 57
  • 15. OOP Hacking Replacing Methods Swapping methods Gain & Loss class A: Gained Change an object def f(self): behavior at runtime print "f" Lost Control flow analysis def g(self): print "g" >>> a = A() >>> a.f, a.g = a.g, a.f >>> a.f() g >>> a.g() f Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 13 / 57
  • 16. OOP Hacking Replacing Methods for a Class Swapping class methods class A: def f(self): print "f" def g(self): print "g" >>> a = A() >>> A.f, A.g = A.g, A.f >>> a.f() g >>> a.g() f Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 14 / 57
  • 17. OOP Hacking Replacing Methods for a Class Swapping class methods Gain & Loss class A: Gained Change a class at def f(self): runtime print "f" Lost Sanity def g(self): print "g" >>> a = A() >>> A.f, A.g = A.g, A.f >>> a.f() g >>> a.g() f Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 14 / 57
  • 18. OOP Hacking Classes are Return Values Too A function that returns a class def PersonClass(salut): class Person(object): def __init__(self, name): self.name = name def greet(self): print salut, self.name return Person Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 15 / 57
  • 19. OOP Hacking Classes are Return Values Too (cont’d) Making classes Output Man = PersonClass("Mr.") for c in a: c.greet() Woman = PersonClass("Ms.") Doctor = PersonClass("Dr.") >>> Ms. Rose Tylar Ms. Amy Pond a = [Woman("Rose Tylar"), Mr. Mickey Smith Woman("Amy Pond"), Mr. Rory Williams Man("Mickey Smith"), Dr. Who Man("Rory Williams"), Doctor("Who")] Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 16 / 57
  • 20. Meta-Classes Outline 1 Introduction 2 OOP Hacking 3 Meta-Classes 4 Examples 5 Summary Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 17 / 57
  • 21. Meta-Classes What is Meta-Programming? Meta-Program A program that: One of its inputs is a program (possibly itself) Its output is a program Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 18 / 57
  • 22. Meta-Classes What is Meta-OOP? Meta-Class A class that creates classes Objects are instances of classes Classes are objects Classes are instances of meta-classes Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 19 / 57
  • 23. Meta-Classes Object Systems 3-levels 4-levels Object Object A Class Type A Class Type super: Type[] super: Type[] An Object An Object A MetaClass Legend instance of extends Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 20 / 57
  • 24. Meta-Classes Meta-Classes in Python Outline 1 Introduction 2 OOP Hacking 3 Meta-Classes Meta-Classes in Python 4 Examples Logging Counting Delegation Associations 5 Summary Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 21 / 57
  • 25. Meta-Classes Meta-Classes in Python Meta-Classes in Python The type class Base class for meta-classes Creates new classes Dynamic members become static members of the instance class type. init (cls, name, bases, dict) cls The class object itself (i.e., “self”) name The name of the class bases A list of the base classes dict A dictionary of the methods and static fields of the class Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 22 / 57
  • 26. Meta-Classes Meta-Classes in Python Creating Classes from Meta-Classes Declaring a new class programatically # Meta-Class class Printable(type): def whoami(self): print "I am ", self.__name__ >>> Foo = Printable(’Foo’,(),{}) # Empty new class >>> Foo.whoami() I am Foo >>> Foo.__class__ <class ’Printable’> >>> f = Foo() # Object >>> f.__class__ <class ’Foo’> Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 23 / 57
  • 27. Meta-Classes Meta-Classes in Python The metaclass field Class C is an instance of a meta-class M if: 1 C has a static field metaclass 2 One of the ancestors classes of C is an instance of M 3 There is a global variable metaclass 4 Otherwise, the default meta-class type is used Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 24 / 57
  • 28. Meta-Classes Meta-Classes in Python metaclass Example Declaring a meta-class with metaclass class Bar: __metaclass__ = Printable def foo(self): print ’foo’ >>> Bar.whoami() I am a Bar >>> b = Bar() >>> b.foo() foo Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 25 / 57
  • 29. Examples Outline 1 Introduction 2 OOP Hacking 3 Meta-Classes 4 Examples 5 Summary Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 26 / 57
  • 30. Examples Logging Outline 1 Introduction 2 OOP Hacking 3 Meta-Classes Meta-Classes in Python 4 Examples Logging Counting Delegation Associations 5 Summary Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 27 / 57
  • 31. Examples Logging Logging with Meta-Classes A logger decorator def log(name, f): def ret(*args): print "enter", name f(*args) print "exit", name return ret Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 28 / 57
  • 32. Examples Logging Logging with Meta-Classes (cont’d) A logger meta-class class Logged(type): def init (cls, name, bases, dict): type. init (cls, name, bases, dict) p = re.compile(cls. logmatch ) for attr, item in dict.items(): if callable(item) and p.match(attr): setattr(cls, attr, log(attr, item)) Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 29 / 57
  • 33. Examples Logging Logging with Meta-Classes (cont’d) A logged class class Test: metaclass = Logged logmatch = ’.*’ def foo(self): print ’foo’ >>> t = Test() >>> t.foo() enter foo foo exit foo Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 30 / 57
  • 34. Examples Counting Outline 1 Introduction 2 OOP Hacking 3 Meta-Classes Meta-Classes in Python 4 Examples Logging Counting Delegation Associations 5 Summary Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 31 / 57
  • 35. Examples Counting Counting Instances Countable meta-class class Countable(type): def new_init(cls, init): def ret(self, *args): init(self, *args) cls.count = cls.count + 1 return ret def __init__(cls, name, bases, dct): type.__init__(cls, name, bases, dct) cls.count = 0 cls.__init__ = cls.new_init(cls.__init__) Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 32 / 57
  • 36. Examples Counting Counting Example Some classes class Person: __metaclass__ = Countable def __init__(self, name): self.name = name class Book: __metaclass__ = Countable def __init__(self, name, author): self.name = name self.author = author Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 33 / 57
  • 37. Examples Counting Counting Example (cont’d) Testing rah = Person("Robert Anson Heinlin") b1 = Book("Stranger in a Strange Land", rah) b2 = Book("Starship Troopers", rah) print Person.count, Book.count >>> 1 2 Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 34 / 57
  • 38. Examples Delegation Outline 1 Introduction 2 OOP Hacking 3 Meta-Classes Meta-Classes in Python 4 Examples Logging Counting Delegation Associations 5 Summary Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 35 / 57
  • 39. Examples Delegation Automatic Delegation Delegate An object of class A that dispatches all message of class B to a target field of type B. Writing a delegate class is a monotonous work But it can be done automatically Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 36 / 57
  • 40. Examples Delegation Delegation Using Meta-Classes A delegation function decorator def dlgt(cls, method): def ret(self, *args): method(self.__tgt__, *args) return instancemethod(ret, None, cls) instancemethod takes a function, an object/None and a class and returns a method of the class Auxiliary – Print class name def clsname(self): return self.__class__.__name__ Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 37 / 57
  • 41. Examples Delegation Delegation Using Meta-Classes (cont’d) The Delegate meta-class class Delegate(type): def __init__(cls, name, bases, dict): type.__init__(cls, name, bases, dict) tgtclass = cls.__tgtclass__ for name in dir(tgtclass): val = getattr(tgtclass, name) if callable(val): setattr(cls, name, dlgt(cls, val)) Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 38 / 57
  • 42. Examples Delegation Delegation Using Meta-Classes (cont’d) The delegated class class A: def bar(self): print clsname(self), ’bar’ def baz(self): print clsname(self), ’baz’ Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 39 / 57
  • 43. Examples Delegation Delegation Using Meta-Classes (cont’d) The delegating class class B: metaclass = Delegate tgtclass = A def init (self, tgt): self. tgt = tgt def boo(self): print clsname(self), ’boo’ Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 40 / 57
  • 44. Examples Delegation Delegation Using Meta-Classes (cont’d) Delegation test >>> b = B(A()) >>> b.bar() A bar >>> b.baz() A baz >>> b.boo() B boo Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 41 / 57
  • 45. Examples Delegation Simplified Syntax for with Meta-Classes with Args. Thanks to Yoav Goldberg Use a function to create the meta-class def delegate_of(tgtclass): class Delegate(type): def __init__(cls, name, bases, dict): type.__init__(cls, name, bases, dict) for name in dir(tgtclass): val = getattr(tgtclass, name) if callable(val): setattr(cls, name, dlgt(cls,val)) Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 42 / 57
  • 46. Examples Delegation Simplified Syntax for Meta-Classes with Args. Thanks to Yoav Goldberg Use the function to generate a meta-class class B: metaclass = delegate_of(A) def init (self, tgt): self. tgt = tgt def boo(self): print clsname(self), ’boo’ Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 43 / 57
  • 47. Examples Associations Outline 1 Introduction 2 OOP Hacking 3 Meta-Classes Meta-Classes in Python 4 Examples Logging Counting Delegation Associations 5 Summary Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 44 / 57
  • 48. Examples Associations Associations 0..m ab 0..n A myA myB B Goals Aggregation operations, like a.getMyB().foreach().g() r = b.getMyA().filter().f().map().h() Optimizations: Multithreading, caching No textual code generation Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 45 / 57
  • 49. Examples Associations Basic Aggregation Replace all public methods with an aggregator wrapper class Aggr(type): def __init__(cls, name, bases, dct): p = re.compile(’__.*__’) type.__init__(cls, name, bases, {}) for key, item in dct.iteritems(): if callable(item) and not p.match(key): m = instancemethod(cls.wrap(item), None, self) setattr(self, key, m) def wrap(cls, func): def ret(self, *args): return self.__aggr__(func, *args) return ret Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 46 / 57
  • 50. Examples Associations Basic Aggregation (cont’d) Make aggrs. that extend impl and wrap ifce class ListAggr(Aggr): @staticmethod def make(name, impl, ifce): dct = {} for key in dir(ifce): dct[key] = getattr(ifce, key) return ListAggr(name, (impl,), dct) def __init__(self, name, bases, dct): Aggr.__init__(self, name, bases, dct) base = bases[0] ctr = base.__init__ % Use impl’s constructor self.__init__ = instancemethod(ctr, None, self) Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 47 / 57
  • 51. Examples Associations List-Based Sequential Aggrs. Store list in private field class ListFunc(object): def __init__(self, data): self.__data__ = data def onAdd(self, other): pass def onRemove(self, other): pass Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 48 / 57
  • 52. Examples Associations List-Based Sequential Aggrs. (cont’d) Sequential Foreach class ListSeqForeach(ListFunc): def __init__(self, data): ListFunc.__init__(self, data) def __aggr__(self, func, *args): for inst in self.__data__: func(inst, *args) Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 49 / 57
  • 53. Examples Associations List-Based Sequential Aggrs. (cont’d) Sequential Map class ListSeqMap(ListFunc): def __init__(self, data): ListFunc.__init__(self, data) def __aggr__(self, func, *args): ret = [] for inst in self.__data__: ret.append(func(inst, *args)) return ret Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 50 / 57
  • 54. Examples Associations Binding It Together Making an aggr. that extends seq. foreach def makeForeachClass(cls): return ListAggr.make(’...’, ListSeqForeach, cls) ListFunc Aggr ListSeqForeach ListAggr cls ForeachClass Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 51 / 57
  • 55. Examples Associations Optimizations Multithreaded Foreach class ListSpawnForeach(ListFunc): def __init__(self, data): ListFunc.__init__(self, data) def __aggr__(self, func, *args): n = max(len(self.__data__)/K, 1) ts = [] for c in chunks(self.__data__, n): t = ForeachThread(c, func, args) ts.append(t) t.start() for tr in ts: tr.join() Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 52 / 57
  • 56. Examples Associations Binding It Together, Multithreaded Version Making an aggr. that extends parallel foreach def makeForeachClass(cls): return ListAggr.make(’...’, ListSpawnForeach, cls) ListFunc Aggr ListSpawnForeach ListAggr cls ForeachClass Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 53 / 57
  • 57. Examples Associations Links Download complete code http://www.cs.bgu.ac.il/~gwiener/software/associations/ Read full paper Proceedings of ENASE’2010 / By request Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 54 / 57
  • 58. Summary Outline 1 Introduction 2 OOP Hacking 3 Meta-Classes 4 Examples 5 Summary Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 55 / 57
  • 59. Summary Advantages of Meta-Classes Turn this. . . Into this P haarazu-Urh os a cr -Y eku Uru-Ne tah i Ia Dai-Uk -W ka a- Ha kal -U Tru-Saka Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 56 / 57
  • 60. Summary Thank You! wiener.guy@gmail.com Guy Wiener (WIS) Dynamic OOP and Meta-Classes in Python 24/5/2011 57 / 57