• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Metaclass Programming in Python
 

Metaclass Programming in Python

on

  • 4,843 views

An introduction to metaclasses in python.

An introduction to metaclasses in python.

Statistics

Views

Total Views
4,843
Views on SlideShare
4,804
Embed Views
39

Actions

Likes
13
Downloads
186
Comments
0

5 Embeds 39

http://www.slideshare.net 18
https://confluence.uk.jpmorgan.com 9
http://localhost 7
http://192.168.6.52 4
http://confluence.uk.jpmorgan.com 1

Accessibility

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution-ShareAlike LicenseCC Attribution-ShareAlike License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Metaclass Programming in Python Metaclass Programming in Python Presentation Transcript

    • Metaclass Programming in Python Advanced OO concepts Juan Manuel Gimeno Illa jmgimeno@diei.udl.cat December 2008 J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 1 / 21
    • This is dangerous, so don’t do it at home :-) [Metaclasses] are deeper magic than 99% of users should ever worry about. If you wonder whether you need them, you don’t (the people who actually need them know with certainty that they need them, and don’t need an explanation about why). Tim Peters (c.l.p post 2002-12-22) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 2 / 21
    • Outline 1 Basic Concepts 2 How classes are created Inside class statement Metaclass Programming Metaclass Conflicts 3 More Examples 4 Concluding Remarks J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 3 / 21
    • Basic Concepts Objects and Classes Classes are templates used to create objects that share structure (attributes) and behaviour (methods) but have different state (attributes’ values) For object obj, type(obj) is the class or type of obj For object obj, type(type(obj)) is the metaclass or metatype of obj (Sometimes type(type(obj)) is referred as the metaclass of type(obj) but this is incorrect) The same way that classes shape objects, metaclasses shape classes. For instance, in Python, the difference between new and old classes resides in the metaclass used to create the classes (Note that the difference in metaclass can affect the objects of the classes. For instance, instances of new-style classes behave differently than those of old-style ones) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 4 / 21
    • Basic Concepts Objects and Classes Classes are templates used to create objects that share structure (attributes) and behaviour (methods) but have different state (attributes’ values) For object obj, type(obj) is the class or type of obj For object obj, type(type(obj)) is the metaclass or metatype of obj (Sometimes type(type(obj)) is referred as the metaclass of type(obj) but this is incorrect) The same way that classes shape objects, metaclasses shape classes. For instance, in Python, the difference between new and old classes resides in the metaclass used to create the classes (Note that the difference in metaclass can affect the objects of the classes. For instance, instances of new-style classes behave differently than those of old-style ones) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 4 / 21
    • Basic Concepts Objects and Classes Classes are templates used to create objects that share structure (attributes) and behaviour (methods) but have different state (attributes’ values) For object obj, type(obj) is the class or type of obj For object obj, type(type(obj)) is the metaclass or metatype of obj (Sometimes type(type(obj)) is referred as the metaclass of type(obj) but this is incorrect) The same way that classes shape objects, metaclasses shape classes. For instance, in Python, the difference between new and old classes resides in the metaclass used to create the classes (Note that the difference in metaclass can affect the objects of the classes. For instance, instances of new-style classes behave differently than those of old-style ones) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 4 / 21
    • Basic Concepts Objects and Classes Classes are templates used to create objects that share structure (attributes) and behaviour (methods) but have different state (attributes’ values) For object obj, type(obj) is the class or type of obj For object obj, type(type(obj)) is the metaclass or metatype of obj (Sometimes type(type(obj)) is referred as the metaclass of type(obj) but this is incorrect) The same way that classes shape objects, metaclasses shape classes. For instance, in Python, the difference between new and old classes resides in the metaclass used to create the classes (Note that the difference in metaclass can affect the objects of the classes. For instance, instances of new-style classes behave differently than those of old-style ones) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 4 / 21
    • Basic Concepts Objects and Classes Classes are templates used to create objects that share structure (attributes) and behaviour (methods) but have different state (attributes’ values) For object obj, type(obj) is the class or type of obj For object obj, type(type(obj)) is the metaclass or metatype of obj (Sometimes type(type(obj)) is referred as the metaclass of type(obj) but this is incorrect) The same way that classes shape objects, metaclasses shape classes. For instance, in Python, the difference between new and old classes resides in the metaclass used to create the classes (Note that the difference in metaclass can affect the objects of the classes. For instance, instances of new-style classes behave differently than those of old-style ones) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 4 / 21
    • Basic Concepts Objects and Classes Classes are templates used to create objects that share structure (attributes) and behaviour (methods) but have different state (attributes’ values) For object obj, type(obj) is the class or type of obj For object obj, type(type(obj)) is the metaclass or metatype of obj (Sometimes type(type(obj)) is referred as the metaclass of type(obj) but this is incorrect) The same way that classes shape objects, metaclasses shape classes. For instance, in Python, the difference between new and old classes resides in the metaclass used to create the classes (Note that the difference in metaclass can affect the objects of the classes. For instance, instances of new-style classes behave differently than those of old-style ones) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 4 / 21
    • Basic Concepts Objects and Classes Classes are templates used to create objects that share structure (attributes) and behaviour (methods) but have different state (attributes’ values) For object obj, type(obj) is the class or type of obj For object obj, type(type(obj)) is the metaclass or metatype of obj (Sometimes type(type(obj)) is referred as the metaclass of type(obj) but this is incorrect) The same way that classes shape objects, metaclasses shape classes. For instance, in Python, the difference between new and old classes resides in the metaclass used to create the classes (Note that the difference in metaclass can affect the objects of the classes. For instance, instances of new-style classes behave differently than those of old-style ones) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 4 / 21
    • Basic Concepts Objects and Classes Classes are templates used to create objects that share structure (attributes) and behaviour (methods) but have different state (attributes’ values) For object obj, type(obj) is the class or type of obj For object obj, type(type(obj)) is the metaclass or metatype of obj (Sometimes type(type(obj)) is referred as the metaclass of type(obj) but this is incorrect) The same way that classes shape objects, metaclasses shape classes. For instance, in Python, the difference between new and old classes resides in the metaclass used to create the classes (Note that the difference in metaclass can affect the objects of the classes. For instance, instances of new-style classes behave differently than those of old-style ones) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 4 / 21
    • Basic Concepts Objects and Classes Classes are templates used to create objects that share structure (attributes) and behaviour (methods) but have different state (attributes’ values) For object obj, type(obj) is the class or type of obj For object obj, type(type(obj)) is the metaclass or metatype of obj (Sometimes type(type(obj)) is referred as the metaclass of type(obj) but this is incorrect) The same way that classes shape objects, metaclasses shape classes. For instance, in Python, the difference between new and old classes resides in the metaclass used to create the classes (Note that the difference in metaclass can affect the objects of the classes. For instance, instances of new-style classes behave differently than those of old-style ones) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 4 / 21
    • Basic Concepts New and Old Classes >>> class New(object): pass ... >>> class Old: pass ... Differences in new and >>> n = New() old style objects (for >>> o = Old() instance, the mro of >>> type(n) attributes) . . . <class ’ main .New’> >>> type(o) . . . are due to the <type ’instance’> different metaclasses >>> type(New) they have <type ’type’> >>> type(Old) <type ’classobj’> J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 5 / 21
    • Basic Concepts New and Old Classes >>> class New(object): pass ... >>> class Old: pass ... Differences in new and >>> n = New() old style objects (for >>> o = Old() instance, the mro of >>> type(n) attributes) . . . <class ’ main .New’> >>> type(o) . . . are due to the <type ’instance’> different metaclasses >>> type(New) they have <type ’type’> >>> type(Old) <type ’classobj’> J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 5 / 21
    • Basic Concepts New and Old Classes >>> class New(object): pass ... >>> class Old: pass ... Differences in new and >>> n = New() old style objects (for >>> o = Old() instance, the mro of >>> type(n) attributes) . . . <class ’ main .New’> >>> type(o) . . . are due to the <type ’instance’> different metaclasses >>> type(New) they have <type ’type’> >>> type(Old) <type ’classobj’> J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 5 / 21
    • Basic Concepts New and Old Classes >>> class New(object): pass ... >>> class Old: pass ... Differences in new and >>> n = New() old style objects (for >>> o = Old() instance, the mro of >>> type(n) attributes) . . . <class ’ main .New’> >>> type(o) . . . are due to the <type ’instance’> different metaclasses >>> type(New) they have <type ’type’> >>> type(Old) <type ’classobj’> J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 5 / 21
    • Basic Concepts New and Old Classes >>> class New(object): pass ... >>> class Old: pass ... Differences in new and >>> n = New() old style objects (for >>> o = Old() instance, the mro of >>> type(n) attributes) . . . <class ’ main .New’> >>> type(o) . . . are due to the <type ’instance’> different metaclasses >>> type(New) they have <type ’type’> >>> type(Old) <type ’classobj’> J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 5 / 21
    • How classes are created Inside class statement The built-in type type(name, bases, attribs)(a.k.a types.TypeType) creates a new-style class object name is a string containing the name of the class (C. name ) bases is a tuple containing the base classes for the new class (C. bases ) attribs is a dictionary pairing the attribute’s names with their corresponding values So the usual class statement (when dealing with new-style classes) class Class(base1, base2, ...): statements calls type with parameters ‘‘Class’’, (base1, base2, ...) and a dictionary containing the bindings created by the execution of the statements. J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 6 / 21
    • How classes are created Inside class statement The built-in type type(name, bases, attribs)(a.k.a types.TypeType) creates a new-style class object name is a string containing the name of the class (C. name ) bases is a tuple containing the base classes for the new class (C. bases ) attribs is a dictionary pairing the attribute’s names with their corresponding values So the usual class statement (when dealing with new-style classes) class Class(base1, base2, ...): statements calls type with parameters ‘‘Class’’, (base1, base2, ...) and a dictionary containing the bindings created by the execution of the statements. J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 6 / 21
    • How classes are created Inside class statement The built-in type type(name, bases, attribs)(a.k.a types.TypeType) creates a new-style class object name is a string containing the name of the class (C. name ) bases is a tuple containing the base classes for the new class (C. bases ) attribs is a dictionary pairing the attribute’s names with their corresponding values So the usual class statement (when dealing with new-style classes) class Class(base1, base2, ...): statements calls type with parameters ‘‘Class’’, (base1, base2, ...) and a dictionary containing the bindings created by the execution of the statements. J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 6 / 21
    • How classes are created Inside class statement The built-in type type(name, bases, attribs)(a.k.a types.TypeType) creates a new-style class object name is a string containing the name of the class (C. name ) bases is a tuple containing the base classes for the new class (C. bases ) attribs is a dictionary pairing the attribute’s names with their corresponding values So the usual class statement (when dealing with new-style classes) class Class(base1, base2, ...): statements calls type with parameters ‘‘Class’’, (base1, base2, ...) and a dictionary containing the bindings created by the execution of the statements. J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 6 / 21
    • How classes are created Inside class statement The built-in type type(name, bases, attribs)(a.k.a types.TypeType) creates a new-style class object name is a string containing the name of the class (C. name ) bases is a tuple containing the base classes for the new class (C. bases ) attribs is a dictionary pairing the attribute’s names with their corresponding values So the usual class statement (when dealing with new-style classes) class Class(base1, base2, ...): statements calls type with parameters ‘‘Class’’, (base1, base2, ...) and a dictionary containing the bindings created by the execution of the statements. J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 6 / 21
    • How classes are created Inside class statement Inside the class statement When one defines a new-style class: >>> class Class1(object): ... attrib = 1 ... def __init__(self, n): ... self.n = n One actually executes: >>> class_name = quot;Class1quot; >>> class_bases = (object,) >>> class_dict = {} >>> class_body = quot;quot;quot; attrib = 1 def __init__(self, n): self.n = n quot;quot;quot; >>> exec class_body in globals(), class_dict >>> locals()[class_name] = type(class_name, class_bases, class_dict) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 7 / 21
    • How classes are created Inside class statement Inside the class statement When one defines a new-style class: >>> class Class1(object): ... attrib = 1 ... def __init__(self, n): ... self.n = n One actually executes: >>> class_name = quot;Class1quot; >>> class_bases = (object,) >>> class_dict = {} >>> class_body = quot;quot;quot; attrib = 1 def __init__(self, n): self.n = n quot;quot;quot; >>> exec class_body in globals(), class_dict >>> locals()[class_name] = type(class_name, class_bases, class_dict) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 7 / 21
    • How classes are created Inside class statement Inside the class statement When one defines a new-style class: >>> class Class1(object): ... attrib = 1 ... def __init__(self, n): ... self.n = n One actually executes: >>> class_name = quot;Class1quot; >>> class_bases = (object,) >>> class_dict = {} >>> class_body = quot;quot;quot; attrib = 1 def __init__(self, n): self.n = n quot;quot;quot; >>> exec class_body in globals(), class_dict >>> locals()[class_name] = type(class_name, class_bases, class_dict) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 7 / 21
    • How classes are created Inside class statement Inside the class statement When one defines a new-style class: >>> class Class1(object): ... attrib = 1 ... def __init__(self, n): ... self.n = n One actually executes: >>> class_name = quot;Class1quot; >>> class_bases = (object,) >>> class_dict = {} >>> class_body = quot;quot;quot; attrib = 1 def __init__(self, n): self.n = n quot;quot;quot; >>> exec class_body in globals(), class_dict >>> locals()[class_name] = type(class_name, class_bases, class_dict) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 7 / 21
    • How classes are created Inside class statement The full truth of the class statement To execute a class statement: 1 Python first collects the class name in a string n, the base classes into a tuple t and executes the body in dictionary d 2 Then determines the metaclass to use for the new class object C 1 When metaclass is a key in d, then M = d[’ metaclass ’] 2 When t is nonempty, then M is the leafmost1 metaclass among all the metaclasses of C’s bases that are not old-style classes 3 If the current module has a global variable metaclass , then M is the value of this variable 4 Failing all of these, M defaults to types.ClassType, that is, an old-style class is created 3 Finally, C = M(n, t, d) 1 If the metaclasses of C’s bases’ do not form an inheritance lattice including its lower bound - i.e. if there is no leafmost metaclass - Python raises and exception diagnosing this metatype conflict. J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 8 / 21
    • How classes are created Inside class statement The full truth of the class statement To execute a class statement: 1 Python first collects the class name in a string n, the base classes into a tuple t and executes the body in dictionary d 2 Then determines the metaclass to use for the new class object C 1 When metaclass is a key in d, then M = d[’ metaclass ’] 2 When t is nonempty, then M is the leafmost1 metaclass among all the metaclasses of C’s bases that are not old-style classes 3 If the current module has a global variable metaclass , then M is the value of this variable 4 Failing all of these, M defaults to types.ClassType, that is, an old-style class is created 3 Finally, C = M(n, t, d) 1 If the metaclasses of C’s bases’ do not form an inheritance lattice including its lower bound - i.e. if there is no leafmost metaclass - Python raises and exception diagnosing this metatype conflict. J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 8 / 21
    • How classes are created Inside class statement The full truth of the class statement To execute a class statement: 1 Python first collects the class name in a string n, the base classes into a tuple t and executes the body in dictionary d 2 Then determines the metaclass to use for the new class object C 1 When metaclass is a key in d, then M = d[’ metaclass ’] 2 When t is nonempty, then M is the leafmost1 metaclass among all the metaclasses of C’s bases that are not old-style classes 3 If the current module has a global variable metaclass , then M is the value of this variable 4 Failing all of these, M defaults to types.ClassType, that is, an old-style class is created 3 Finally, C = M(n, t, d) 1 If the metaclasses of C’s bases’ do not form an inheritance lattice including its lower bound - i.e. if there is no leafmost metaclass - Python raises and exception diagnosing this metatype conflict. J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 8 / 21
    • How classes are created Inside class statement The full truth of the class statement To execute a class statement: 1 Python first collects the class name in a string n, the base classes into a tuple t and executes the body in dictionary d 2 Then determines the metaclass to use for the new class object C 1 When metaclass is a key in d, then M = d[’ metaclass ’] 2 When t is nonempty, then M is the leafmost1 metaclass among all the metaclasses of C’s bases that are not old-style classes 3 If the current module has a global variable metaclass , then M is the value of this variable 4 Failing all of these, M defaults to types.ClassType, that is, an old-style class is created 3 Finally, C = M(n, t, d) 1 If the metaclasses of C’s bases’ do not form an inheritance lattice including its lower bound - i.e. if there is no leafmost metaclass - Python raises and exception diagnosing this metatype conflict. J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 8 / 21
    • How classes are created Inside class statement The full truth of the class statement To execute a class statement: 1 Python first collects the class name in a string n, the base classes into a tuple t and executes the body in dictionary d 2 Then determines the metaclass to use for the new class object C 1 When metaclass is a key in d, then M = d[’ metaclass ’] 2 When t is nonempty, then M is the leafmost1 metaclass among all the metaclasses of C’s bases that are not old-style classes 3 If the current module has a global variable metaclass , then M is the value of this variable 4 Failing all of these, M defaults to types.ClassType, that is, an old-style class is created 3 Finally, C = M(n, t, d) 1 If the metaclasses of C’s bases’ do not form an inheritance lattice including its lower bound - i.e. if there is no leafmost metaclass - Python raises and exception diagnosing this metatype conflict. J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 8 / 21
    • How classes are created Inside class statement The full truth of the class statement To execute a class statement: 1 Python first collects the class name in a string n, the base classes into a tuple t and executes the body in dictionary d 2 Then determines the metaclass to use for the new class object C 1 When metaclass is a key in d, then M = d[’ metaclass ’] 2 When t is nonempty, then M is the leafmost1 metaclass among all the metaclasses of C’s bases that are not old-style classes 3 If the current module has a global variable metaclass , then M is the value of this variable 4 Failing all of these, M defaults to types.ClassType, that is, an old-style class is created 3 Finally, C = M(n, t, d) 1 If the metaclasses of C’s bases’ do not form an inheritance lattice including its lower bound - i.e. if there is no leafmost metaclass - Python raises and exception diagnosing this metatype conflict. J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 8 / 21
    • How classes are created Inside class statement The full truth of the class statement To execute a class statement: 1 Python first collects the class name in a string n, the base classes into a tuple t and executes the body in dictionary d 2 Then determines the metaclass to use for the new class object C 1 When metaclass is a key in d, then M = d[’ metaclass ’] 2 When t is nonempty, then M is the leafmost1 metaclass among all the metaclasses of C’s bases that are not old-style classes 3 If the current module has a global variable metaclass , then M is the value of this variable 4 Failing all of these, M defaults to types.ClassType, that is, an old-style class is created 3 Finally, C = M(n, t, d) 1 If the metaclasses of C’s bases’ do not form an inheritance lattice including its lower bound - i.e. if there is no leafmost metaclass - Python raises and exception diagnosing this metatype conflict. J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 8 / 21
    • How classes are created Inside class statement The full truth of the class statement To execute a class statement: 1 Python first collects the class name in a string n, the base classes into a tuple t and executes the body in dictionary d 2 Then determines the metaclass to use for the new class object C 1 When metaclass is a key in d, then M = d[’ metaclass ’] 2 When t is nonempty, then M is the leafmost1 metaclass among all the metaclasses of C’s bases that are not old-style classes 3 If the current module has a global variable metaclass , then M is the value of this variable 4 Failing all of these, M defaults to types.ClassType, that is, an old-style class is created 3 Finally, C = M(n, t, d) 1 If the metaclasses of C’s bases’ do not form an inheritance lattice including its lower bound - i.e. if there is no leafmost metaclass - Python raises and exception diagnosing this metatype conflict. J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 8 / 21
    • How classes are created Metaclass Programming A very simple metaclass Redefining method repr in class changes the way python show its instances So to change the way python shows a class, we redefine repr in the metaclass >>> class MetaPretty(type): ... def __repr__(cls): ... return quot;I’m the class %squot; % cls.__name__ ... >>> class Ugly: pass >>> Ugly <class ’__main__.Ugly’> >>> class Pretty(object): ... __metaclass__ = MetaPretty >>> Pretty I’m the class Pretty Metaclass programming is easier than you thought !!! J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 9 / 21
    • How classes are created Metaclass Programming A very simple metaclass Redefining method repr in class changes the way python show its instances So to change the way python shows a class, we redefine repr in the metaclass >>> class MetaPretty(type): ... def __repr__(cls): ... return quot;I’m the class %squot; % cls.__name__ ... >>> class Ugly: pass >>> Ugly <class ’__main__.Ugly’> >>> class Pretty(object): ... __metaclass__ = MetaPretty >>> Pretty I’m the class Pretty Metaclass programming is easier than you thought !!! J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 9 / 21
    • How classes are created Metaclass Programming A very simple metaclass Redefining method repr in class changes the way python show its instances So to change the way python shows a class, we redefine repr in the metaclass >>> class MetaPretty(type): ... def __repr__(cls): ... return quot;I’m the class %squot; % cls.__name__ ... >>> class Ugly: pass >>> Ugly <class ’__main__.Ugly’> >>> class Pretty(object): ... __metaclass__ = MetaPretty >>> Pretty I’m the class Pretty Metaclass programming is easier than you thought !!! J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 9 / 21
    • How classes are created Metaclass Programming A very simple metaclass Redefining method repr in class changes the way python show its instances So to change the way python shows a class, we redefine repr in the metaclass >>> class MetaPretty(type): ... def __repr__(cls): ... return quot;I’m the class %squot; % cls.__name__ ... >>> class Ugly: pass >>> Ugly <class ’__main__.Ugly’> >>> class Pretty(object): ... __metaclass__ = MetaPretty >>> Pretty I’m the class Pretty Metaclass programming is easier than you thought !!! J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 9 / 21
    • How classes are created Metaclass Programming Automatic property creation I We don’t want to tell python the properties defined in a class if there are methods in the class that evidently want a property defined !!! We implement it redefining init class MetaAutoProp(type): def __init__(cls, name, bases, dict): super(MetaAutoProp, cls).__init__(name, bases, dict) props = set(name[5:] for name in dict.iterkeys() if name.startswith(quot;_get_quot;) or name.startswith(quot;_set_quot;)) for name in props: fget = getattr(cls, quot;_get_%squot; % name, None) fset = getattr(cls, quot;_set_%squot; % name, None) setattr(cls, name, property(fget, fset)) class AutoProp(object): __metaclass__ = MetaAutoProp class UseX(AutoProp): def __init__(self): self.__x = 0 def _get_x(self): return self.__x def _set_x(self, x): self.__x = x J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 10 / 21
    • How classes are created Metaclass Programming Automatic property creation I We don’t want to tell python the properties defined in a class if there are methods in the class that evidently want a property defined !!! We implement it redefining init class MetaAutoProp(type): def __init__(cls, name, bases, dict): super(MetaAutoProp, cls).__init__(name, bases, dict) props = set(name[5:] for name in dict.iterkeys() if name.startswith(quot;_get_quot;) or name.startswith(quot;_set_quot;)) for name in props: fget = getattr(cls, quot;_get_%squot; % name, None) fset = getattr(cls, quot;_set_%squot; % name, None) setattr(cls, name, property(fget, fset)) class AutoProp(object): __metaclass__ = MetaAutoProp class UseX(AutoProp): def __init__(self): self.__x = 0 def _get_x(self): return self.__x def _set_x(self, x): self.__x = x J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 10 / 21
    • How classes are created Metaclass Programming Automatic property creation I We don’t want to tell python the properties defined in a class if there are methods in the class that evidently want a property defined !!! We implement it redefining init class MetaAutoProp(type): def __init__(cls, name, bases, dict): super(MetaAutoProp, cls).__init__(name, bases, dict) props = set(name[5:] for name in dict.iterkeys() if name.startswith(quot;_get_quot;) or name.startswith(quot;_set_quot;)) for name in props: fget = getattr(cls, quot;_get_%squot; % name, None) fset = getattr(cls, quot;_set_%squot; % name, None) setattr(cls, name, property(fget, fset)) class AutoProp(object): __metaclass__ = MetaAutoProp class UseX(AutoProp): def __init__(self): self.__x = 0 def _get_x(self): return self.__x def _set_x(self, x): self.__x = x J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 10 / 21
    • How classes are created Metaclass Programming Automatic property creation II The same as before but this time the implementation redefines new class MetaAutoProp(type): def __new__(mcl, classname, bases, dict): props = set(name[5:] for name in dict.iterkeys() if name.startswith(quot;_get_quot;) or name.startswith(quot;_set_quot;)) for name in props: fget = dict.get(quot;_get_%squot; % name) fset = dict.get(quot;_set_%squot; % name) dict[name] = property(fget, fset) super_ = super(MetaAutoProp, mcl) return super_.__new__(mcl, classname, bases, dict) class AutoProp(object): __metaclass__ = MetaAutoProp class UseX(AutoProp): def __init__(self): self.__x = 0 def _get_x(self): return self.__x def _set_x(self, x): self.__x = x Deciding which way to go is not clearly defined J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 11 / 21
    • How classes are created Metaclass Programming Automatic property creation II The same as before but this time the implementation redefines new class MetaAutoProp(type): def __new__(mcl, classname, bases, dict): props = set(name[5:] for name in dict.iterkeys() if name.startswith(quot;_get_quot;) or name.startswith(quot;_set_quot;)) for name in props: fget = dict.get(quot;_get_%squot; % name) fset = dict.get(quot;_set_%squot; % name) dict[name] = property(fget, fset) super_ = super(MetaAutoProp, mcl) return super_.__new__(mcl, classname, bases, dict) class AutoProp(object): __metaclass__ = MetaAutoProp class UseX(AutoProp): def __init__(self): self.__x = 0 def _get_x(self): return self.__x def _set_x(self, x): self.__x = x Deciding which way to go is not clearly defined J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 11 / 21
    • How classes are created Metaclass Programming Automatic property creation II The same as before but this time the implementation redefines new class MetaAutoProp(type): def __new__(mcl, classname, bases, dict): props = set(name[5:] for name in dict.iterkeys() if name.startswith(quot;_get_quot;) or name.startswith(quot;_set_quot;)) for name in props: fget = dict.get(quot;_get_%squot; % name) fset = dict.get(quot;_set_%squot; % name) dict[name] = property(fget, fset) super_ = super(MetaAutoProp, mcl) return super_.__new__(mcl, classname, bases, dict) class AutoProp(object): __metaclass__ = MetaAutoProp class UseX(AutoProp): def __init__(self): self.__x = 0 def _get_x(self): return self.__x def _set_x(self, x): self.__x = x Deciding which way to go is not clearly defined J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 11 / 21
    • How classes are created Metaclass Programming Automatic Initialization of Instance Attributes import inspect class auto_attr(object): def __init__(self, factory, *args, **kwargs): self.creation_data = (factory, args, kwargs) def is_auto_attr(attr): return isinstance(attr, auto_attr) class MetaAutoAttr(type): def __call__(cls, *args, **kwargs): obj = super(MetaAutoAttr, cls).__call__(*args, **kwargs) for attr, value in inspect.getmembers(cls, is_auto_attr): factory, a, k = value.creation_data setattr(obj, attr, factory(*a, **k)) return obj class AutoAttr(object): __metaclass__ = MetaAutoAttr class Recorder(AutoAttr): count = 0 # is immutable so no shared among instances events = auto_attr(list) def record(self, event): self.count += 1 self.events.append((self.count, event)) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 12 / 21
    • How classes are created Metaclass Conflicts But, sometimes, conflicts happen Imagine one wants a class with both behaviours. If one tries: from autoprop import AutoProp from autoattr import AutoAttr, auto_attr class Both(AutoProp, AutoAttr): __x = auto_attr(list) def _get_x(self): return self.__x def _set_x(self, v): self.__x = v One gets: TypeError: Error when calling the metaclass bases metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases The problem is that python needs to find a metaclass that brings both behaviours at the same time (This is the application of the Liskov Substitution Principle applied to metaclasses) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 13 / 21
    • How classes are created Metaclass Conflicts But, sometimes, conflicts happen Imagine one wants a class with both behaviours. If one tries: from autoprop import AutoProp from autoattr import AutoAttr, auto_attr class Both(AutoProp, AutoAttr): __x = auto_attr(list) def _get_x(self): return self.__x def _set_x(self, v): self.__x = v One gets: TypeError: Error when calling the metaclass bases metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases The problem is that python needs to find a metaclass that brings both behaviours at the same time (This is the application of the Liskov Substitution Principle applied to metaclasses) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 13 / 21
    • How classes are created Metaclass Conflicts But, sometimes, conflicts happen Imagine one wants a class with both behaviours. If one tries: from autoprop import AutoProp from autoattr import AutoAttr, auto_attr class Both(AutoProp, AutoAttr): __x = auto_attr(list) def _get_x(self): return self.__x def _set_x(self, v): self.__x = v One gets: TypeError: Error when calling the metaclass bases metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases The problem is that python needs to find a metaclass that brings both behaviours at the same time (This is the application of the Liskov Substitution Principle applied to metaclasses) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 13 / 21
    • How classes are created Metaclass Conflicts But, sometimes, conflicts happen Imagine one wants a class with both behaviours. If one tries: from autoprop import AutoProp from autoattr import AutoAttr, auto_attr class Both(AutoProp, AutoAttr): __x = auto_attr(list) def _get_x(self): return self.__x def _set_x(self, v): self.__x = v One gets: TypeError: Error when calling the metaclass bases metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases The problem is that python needs to find a metaclass that brings both behaviours at the same time (This is the application of the Liskov Substitution Principle applied to metaclasses) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 13 / 21
    • How classes are created Metaclass Conflicts But, sometimes, conflicts happen Imagine one wants a class with both behaviours. If one tries: from autoprop import AutoProp from autoattr import AutoAttr, auto_attr class Both(AutoProp, AutoAttr): __x = auto_attr(list) def _get_x(self): return self.__x def _set_x(self, v): self.__x = v One gets: TypeError: Error when calling the metaclass bases metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases The problem is that python needs to find a metaclass that brings both behaviours at the same time (This is the application of the Liskov Substitution Principle applied to metaclasses) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 13 / 21
    • How classes are created Metaclass Conflicts But, sometimes, conflicts happen Imagine one wants a class with both behaviours. If one tries: from autoprop import AutoProp from autoattr import AutoAttr, auto_attr class Both(AutoProp, AutoAttr): __x = auto_attr(list) def _get_x(self): return self.__x def _set_x(self, v): self.__x = v One gets: TypeError: Error when calling the metaclass bases metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases The problem is that python needs to find a metaclass that brings both behaviours at the same time (This is the application of the Liskov Substitution Principle applied to metaclasses) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 13 / 21
    • How classes are created Metaclass Conflicts Solving the metaclass conflict To ensured it, the metaclass to use must be a subclass of all those of the bases of the class (Technically it must be minimal in the inheritance subgraph of the metaclasses of the bases considered as a lattice) Some languages create an on-the-fly this minimal metaclass if needed Python needs you to solve the problem , so: from autoprop import MetaAutoProp from autoattr import MetaAutoAttr, auto_attr class MetaBoth(MetaAutoAttr, MetaAutoProp): pass class Both(object): __metaclass__ = MetaBoth __x = auto_attr(list) def _get_x(self): return self.__x def _set_x(self, value): self.__x = value (A recipe exists in the Python Cookbook that solves this problem by defining a metaclass factory method which creates the appropriate metaclass when needed) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 14 / 21
    • How classes are created Metaclass Conflicts Solving the metaclass conflict To ensured it, the metaclass to use must be a subclass of all those of the bases of the class (Technically it must be minimal in the inheritance subgraph of the metaclasses of the bases considered as a lattice) Some languages create an on-the-fly this minimal metaclass if needed Python needs you to solve the problem , so: from autoprop import MetaAutoProp from autoattr import MetaAutoAttr, auto_attr class MetaBoth(MetaAutoAttr, MetaAutoProp): pass class Both(object): __metaclass__ = MetaBoth __x = auto_attr(list) def _get_x(self): return self.__x def _set_x(self, value): self.__x = value (A recipe exists in the Python Cookbook that solves this problem by defining a metaclass factory method which creates the appropriate metaclass when needed) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 14 / 21
    • How classes are created Metaclass Conflicts Solving the metaclass conflict To ensured it, the metaclass to use must be a subclass of all those of the bases of the class (Technically it must be minimal in the inheritance subgraph of the metaclasses of the bases considered as a lattice) Some languages create an on-the-fly this minimal metaclass if needed Python needs you to solve the problem , so: from autoprop import MetaAutoProp from autoattr import MetaAutoAttr, auto_attr class MetaBoth(MetaAutoAttr, MetaAutoProp): pass class Both(object): __metaclass__ = MetaBoth __x = auto_attr(list) def _get_x(self): return self.__x def _set_x(self, value): self.__x = value (A recipe exists in the Python Cookbook that solves this problem by defining a metaclass factory method which creates the appropriate metaclass when needed) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 14 / 21
    • How classes are created Metaclass Conflicts Solving the metaclass conflict To ensured it, the metaclass to use must be a subclass of all those of the bases of the class (Technically it must be minimal in the inheritance subgraph of the metaclasses of the bases considered as a lattice) Some languages create an on-the-fly this minimal metaclass if needed Python needs you to solve the problem , so: from autoprop import MetaAutoProp from autoattr import MetaAutoAttr, auto_attr class MetaBoth(MetaAutoAttr, MetaAutoProp): pass class Both(object): __metaclass__ = MetaBoth __x = auto_attr(list) def _get_x(self): return self.__x def _set_x(self, value): self.__x = value (A recipe exists in the Python Cookbook that solves this problem by defining a metaclass factory method which creates the appropriate metaclass when needed) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 14 / 21
    • How classes are created Metaclass Conflicts Solving the metaclass conflict To ensured it, the metaclass to use must be a subclass of all those of the bases of the class (Technically it must be minimal in the inheritance subgraph of the metaclasses of the bases considered as a lattice) Some languages create an on-the-fly this minimal metaclass if needed Python needs you to solve the problem , so: from autoprop import MetaAutoProp from autoattr import MetaAutoAttr, auto_attr class MetaBoth(MetaAutoAttr, MetaAutoProp): pass class Both(object): __metaclass__ = MetaBoth __x = auto_attr(list) def _get_x(self): return self.__x def _set_x(self, value): self.__x = value (A recipe exists in the Python Cookbook that solves this problem by defining a metaclass factory method which creates the appropriate metaclass when needed) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 14 / 21
    • How classes are created Metaclass Conflicts Solving the metaclass conflict To ensured it, the metaclass to use must be a subclass of all those of the bases of the class (Technically it must be minimal in the inheritance subgraph of the metaclasses of the bases considered as a lattice) Some languages create an on-the-fly this minimal metaclass if needed Python needs you to solve the problem , so: from autoprop import MetaAutoProp from autoattr import MetaAutoAttr, auto_attr class MetaBoth(MetaAutoAttr, MetaAutoProp): pass class Both(object): __metaclass__ = MetaBoth __x = auto_attr(list) def _get_x(self): return self.__x def _set_x(self, value): self.__x = value (A recipe exists in the Python Cookbook that solves this problem by defining a metaclass factory method which creates the appropriate metaclass when needed) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 14 / 21
    • More Examples Avoiding multiple initialization of Singletons The Singleton class that was presented before needed init to be idempotent. Changing its metaclass solves it: # Singleton classes are only init’ed once class Singleton(object): class __metaclass__(type): _initialized = set() def __call__(cls, *args, **kwargs): inits = Singleton.__metaclass__._initialized obj = cls.__new__(cls, *args, **kwargs) if isinstance(obj, cls) and cls not in inits: inits.add(cls) obj.__init__(*args, **kwargs) return obj _singletons = {} def __new__(cls, *args, **kwds): if cls not in cls._singletons: s = super(Singleton, cls) cls._singletons[cls] = super(Singleton, cls).__new__(cls, *args, **kwds) return cls._singletons[cls] J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 15 / 21
    • More Examples Avoiding multiple initialization of Singletons The Singleton class that was presented before needed init to be idempotent. Changing its metaclass solves it: # Singleton classes are only init’ed once class Singleton(object): class __metaclass__(type): _initialized = set() def __call__(cls, *args, **kwargs): inits = Singleton.__metaclass__._initialized obj = cls.__new__(cls, *args, **kwargs) if isinstance(obj, cls) and cls not in inits: inits.add(cls) obj.__init__(*args, **kwargs) return obj _singletons = {} def __new__(cls, *args, **kwds): if cls not in cls._singletons: s = super(Singleton, cls) cls._singletons[cls] = super(Singleton, cls).__new__(cls, *args, **kwds) return cls._singletons[cls] J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 15 / 21
    • More Examples Enforcing naming rules We don’t want classes with attributes that are not lowercase to be ever created !!!! class InvalidAttribName(TypeError): pass class MetaEnsureAttribNames(type): def __new__(mcl, name, bases, attrs): invalids = [attr for attr in attrs if not attr.islower()] if invalids: msg = quot;Invalid Attributes: quot; + quot;, quot;.join(invalids) raise InvalidAttribName, msg super_ = super(MetaEnsureAttribNames, mcl) return super_.__new__(mcl, name, bases, attrs) class EnsureAttribNames(object): __metaclass__ = MetaEnsureAttribNames (You can experiment with different rules for methods, rules for class names, etc.) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 16 / 21
    • More Examples Enforcing naming rules We don’t want classes with attributes that are not lowercase to be ever created !!!! class InvalidAttribName(TypeError): pass class MetaEnsureAttribNames(type): def __new__(mcl, name, bases, attrs): invalids = [attr for attr in attrs if not attr.islower()] if invalids: msg = quot;Invalid Attributes: quot; + quot;, quot;.join(invalids) raise InvalidAttribName, msg super_ = super(MetaEnsureAttribNames, mcl) return super_.__new__(mcl, name, bases, attrs) class EnsureAttribNames(object): __metaclass__ = MetaEnsureAttribNames (You can experiment with different rules for methods, rules for class names, etc.) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 16 / 21
    • More Examples Enforcing naming rules We don’t want classes with attributes that are not lowercase to be ever created !!!! class InvalidAttribName(TypeError): pass class MetaEnsureAttribNames(type): def __new__(mcl, name, bases, attrs): invalids = [attr for attr in attrs if not attr.islower()] if invalids: msg = quot;Invalid Attributes: quot; + quot;, quot;.join(invalids) raise InvalidAttribName, msg super_ = super(MetaEnsureAttribNames, mcl) return super_.__new__(mcl, name, bases, attrs) class EnsureAttribNames(object): __metaclass__ = MetaEnsureAttribNames (You can experiment with different rules for methods, rules for class names, etc.) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 16 / 21
    • More Examples Checking Whether Interfaces are Implemented We want to extend python capabilities to respresent the idea of an interface and to ensure that a class that declares implementing one, actually does it Interfaces are represented by simple classes class IConnectable(object): def send(self, msg): pass def receive(self): pass Declaring an interface is done with a class’ attribute and is ensured by a metaclass class Channel(object): __metaclass__ = MetaInterfaceChecker __implements__ = IConnectable def send(self, msg): .... def receive(self): .... J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 17 / 21
    • More Examples Checking Whether Interfaces are Implemented We want to extend python capabilities to respresent the idea of an interface and to ensure that a class that declares implementing one, actually does it Interfaces are represented by simple classes class IConnectable(object): def send(self, msg): pass def receive(self): pass Declaring an interface is done with a class’ attribute and is ensured by a metaclass class Channel(object): __metaclass__ = MetaInterfaceChecker __implements__ = IConnectable def send(self, msg): .... def receive(self): .... J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 17 / 21
    • More Examples Checking Whether Interfaces are Implemented We want to extend python capabilities to respresent the idea of an interface and to ensure that a class that declares implementing one, actually does it Interfaces are represented by simple classes class IConnectable(object): def send(self, msg): pass def receive(self): pass Declaring an interface is done with a class’ attribute and is ensured by a metaclass class Channel(object): __metaclass__ = MetaInterfaceChecker __implements__ = IConnectable def send(self, msg): .... def receive(self): .... J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 17 / 21
    • More Examples Checking Whether Interfaces are Implemented We want to extend python capabilities to respresent the idea of an interface and to ensure that a class that declares implementing one, actually does it Interfaces are represented by simple classes class IConnectable(object): def send(self, msg): pass def receive(self): pass Declaring an interface is done with a class’ attribute and is ensured by a metaclass class Channel(object): __metaclass__ = MetaInterfaceChecker __implements__ = IConnectable def send(self, msg): .... def receive(self): .... J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 17 / 21
    • More Examples Checking Whether Interfaces are Implemented We want to extend python capabilities to respresent the idea of an interface and to ensure that a class that declares implementing one, actually does it Interfaces are represented by simple classes class IConnectable(object): def send(self, msg): pass def receive(self): pass Declaring an interface is done with a class’ attribute and is ensured by a metaclass class Channel(object): __metaclass__ = MetaInterfaceChecker __implements__ = IConnectable def send(self, msg): .... def receive(self): .... J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 17 / 21
    • More Examples Checking Whether Interfaces are Implemented The following metaclass checks if all the methods in all declared interfaces are defined in the class (The implementation is na¨ so you can enhance it. hint: use module ıve, inspect) import set class InterfaceOmission(TypeError): pass class MetaInterfaceChecker(type): def __init__(cls, classname, bases, classdict): super(MetaInterfaceChecker, cls).__init__(classname, bases, classdict) cls_defines = set(dir(cls)) for interface in cls.__implements__: itf_requires = set(dir(interface)) if not itf_requires.issubset(cls_defines): raise (InterfaceOmission, list(itf_requires - cls_defines)) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 18 / 21
    • More Examples Checking Whether Interfaces are Implemented The following metaclass checks if all the methods in all declared interfaces are defined in the class (The implementation is na¨ so you can enhance it. hint: use module ıve, inspect) import set class InterfaceOmission(TypeError): pass class MetaInterfaceChecker(type): def __init__(cls, classname, bases, classdict): super(MetaInterfaceChecker, cls).__init__(classname, bases, classdict) cls_defines = set(dir(cls)) for interface in cls.__implements__: itf_requires = set(dir(interface)) if not itf_requires.issubset(cls_defines): raise (InterfaceOmission, list(itf_requires - cls_defines)) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 18 / 21
    • More Examples Checking Whether Interfaces are Implemented The following metaclass checks if all the methods in all declared interfaces are defined in the class (The implementation is na¨ so you can enhance it. hint: use module ıve, inspect) import set class InterfaceOmission(TypeError): pass class MetaInterfaceChecker(type): def __init__(cls, classname, bases, classdict): super(MetaInterfaceChecker, cls).__init__(classname, bases, classdict) cls_defines = set(dir(cls)) for interface in cls.__implements__: itf_requires = set(dir(interface)) if not itf_requires.issubset(cls_defines): raise (InterfaceOmission, list(itf_requires - cls_defines)) J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 18 / 21
    • Concluding Remarks Conclusions Metaclasses must not be abused they put you dangerously near to the dark side if there’s a simple way to perform the same, don’t use them but sometimes they simplify things or lead to more efficient solutions But understanding them shows you the whole picture of python’s OO gives you new ways to think about solutions And they are fun !!! J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 19 / 21
    • Concluding Remarks Conclusions Metaclasses must not be abused they put you dangerously near to the dark side if there’s a simple way to perform the same, don’t use them but sometimes they simplify things or lead to more efficient solutions But understanding them shows you the whole picture of python’s OO gives you new ways to think about solutions And they are fun !!! J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 19 / 21
    • Concluding Remarks Conclusions Metaclasses must not be abused they put you dangerously near to the dark side if there’s a simple way to perform the same, don’t use them but sometimes they simplify things or lead to more efficient solutions But understanding them shows you the whole picture of python’s OO gives you new ways to think about solutions And they are fun !!! J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 19 / 21
    • Concluding Remarks Conclusions Metaclasses must not be abused they put you dangerously near to the dark side if there’s a simple way to perform the same, don’t use them but sometimes they simplify things or lead to more efficient solutions But understanding them shows you the whole picture of python’s OO gives you new ways to think about solutions And they are fun !!! J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 19 / 21
    • Concluding Remarks Conclusions Metaclasses must not be abused they put you dangerously near to the dark side if there’s a simple way to perform the same, don’t use them but sometimes they simplify things or lead to more efficient solutions But understanding them shows you the whole picture of python’s OO gives you new ways to think about solutions And they are fun !!! J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 19 / 21
    • Concluding Remarks Conclusions Metaclasses must not be abused they put you dangerously near to the dark side if there’s a simple way to perform the same, don’t use them but sometimes they simplify things or lead to more efficient solutions But understanding them shows you the whole picture of python’s OO gives you new ways to think about solutions And they are fun !!! J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 19 / 21
    • Concluding Remarks Conclusions Metaclasses must not be abused they put you dangerously near to the dark side if there’s a simple way to perform the same, don’t use them but sometimes they simplify things or lead to more efficient solutions But understanding them shows you the whole picture of python’s OO gives you new ways to think about solutions And they are fun !!! J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 19 / 21
    • Concluding Remarks Conclusions Metaclasses must not be abused they put you dangerously near to the dark side if there’s a simple way to perform the same, don’t use them but sometimes they simplify things or lead to more efficient solutions But understanding them shows you the whole picture of python’s OO gives you new ways to think about solutions And they are fun !!! J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 19 / 21
    • Concluding Remarks Conclusions Metaclasses must not be abused they put you dangerously near to the dark side if there’s a simple way to perform the same, don’t use them but sometimes they simplify things or lead to more efficient solutions But understanding them shows you the whole picture of python’s OO gives you new ways to think about solutions And they are fun !!! J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 19 / 21
    • Bibliography Bibliography Shalahb Chaturvedi, Python Types and Objects Mike Fletcher, Metaclasses, Who, Why, When, Python Conference (Pycon) 2004. Ira R. Forman and Scott Danforth, Putting Metaclasses to Work. Addison-Wesley, 1999. Alex Martelli, Python in a Nutshell (2nd Edition), O’Reilly Media Inc, 2006. Alex Martelli, Python Metaclasses Alex Martelli, Anna Martelli, Python Cookbook (2nd Edition), O’Reilly Media Inc, 2005. The recipes are based on those in ActiveState Python Cookbook. David Mertz, A Primer on Python Metaclass Programming Guido Van Rossum, Unifying types and classes in Python 2.2 J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 20 / 21
    • License License Aquesta obra est` subjecta a una llic`ncia Reconeixement-Compartir amb a e la mateixa llic`ncia 2.5 Espanya de Creative Commons. e Per veure’n una c`pia, visiteu o http://creativecommons.org/licenses/by-sa/2.5/es/ o envieu una carta a Creative Commons 559 Nathan Abbott Way Stanford California 94305 USA J.M.Gimeno (jmgimeno@diei.udl.cat) Metaclasses December 2008 21 / 21