Talk given to Sacramento Ruby Meetup for the September, 2010 meeting. Examples adapted from the great book Metaprogramming Ruby: Program Like the Ruby Pros by Paolo Perrotta
Talk given to Sacramento Ruby Meetup for the September, 2010 meeting. Examples adapted from the great book Metaprogramming Ruby: Program Like the Ruby Pros by Paolo Perrotta
Metaclasses – Python’s Object-Oriented Paradigm and Its MetaprogrammingInexture Solutions
Unleash the Power of Python Dynamic Class Creation and Instantiation! Learn about metaclasses, dynamic classes, and the fascinating process of object instantiation. Dive into Python's object-oriented paradigm to improve your coding skills.
Object oriented programming by timehubzone.com.
To understand the object-oriented features and how best to use them, it is helpful to understand the key concepts of object-oriented programming. This section is a brief introduction to object-oriented programming. It also compares these concepts with features of procedural programming used to accomplish the same goals
https://www.timehubzone.com/worldclock
The timehubzone.com is a web service that transforms, otherwise tricky, tasks like your assistant as you go and makes travel easy on tour, travel, international meeting into an intuitive, super-quick and painless experience.
https://www.timehubzone.com/holidays
A short tour into the python data modelling, dealing with classes, type-class unification, method resolution order in multiple inheritance, mixins and metaclasses
This presentation educates you about objectives of python with example syntax, OOP Terminology, Creating Classes, Creating Instance Objects, Accessing Attributes and Built-In Class Attributes.
This slide is based on Object Oriented Programming Language. Here is some details about object and class. You can easily understand about object and class.
6- What are the differences between objects and abstract data typesSol.docxdanielt47
6. What are the differences between objects and abstract data types
Solution
Differences between Objects and Abstract data types:
______________________________________________
Objects: Object is an instance of a class and it has states and behaviours of class.
Abstract data type: It is a data type of abstract and it hides the representation of class, and it is typically implemented as a class and each instance of Abstract data type is usually an object of that class.
Objects and Abstract data types are not the same. But these are not different with each other.
Objects are a kind of Abstract data types.
An Abstract data type is an interface.But objects are instance of a class, with its own copy of any non-static variables.
Abstract data type is a collection of methods but in case of objects it is not an interface.It is an representation of a class with new operator.
A class can have one or more Abstract data types in the same way class can have one or more objects also.
To understand you with clear for Example, Collection interface is Abstract data type, ArrayList is a class and you can make ArrayList object with new operator.
.
chapter 1: Lecture 2
Let’s think on concept of Class and Object
- Concept of Objects and classes
- UML Class Diagram
الكلية الجامعية للعلوم والتكنولوجيا - خان يونس
University college of science & technology
Metaclasses – Python’s Object-Oriented Paradigm and Its MetaprogrammingInexture Solutions
Unleash the Power of Python Dynamic Class Creation and Instantiation! Learn about metaclasses, dynamic classes, and the fascinating process of object instantiation. Dive into Python's object-oriented paradigm to improve your coding skills.
Object oriented programming by timehubzone.com.
To understand the object-oriented features and how best to use them, it is helpful to understand the key concepts of object-oriented programming. This section is a brief introduction to object-oriented programming. It also compares these concepts with features of procedural programming used to accomplish the same goals
https://www.timehubzone.com/worldclock
The timehubzone.com is a web service that transforms, otherwise tricky, tasks like your assistant as you go and makes travel easy on tour, travel, international meeting into an intuitive, super-quick and painless experience.
https://www.timehubzone.com/holidays
A short tour into the python data modelling, dealing with classes, type-class unification, method resolution order in multiple inheritance, mixins and metaclasses
This presentation educates you about objectives of python with example syntax, OOP Terminology, Creating Classes, Creating Instance Objects, Accessing Attributes and Built-In Class Attributes.
This slide is based on Object Oriented Programming Language. Here is some details about object and class. You can easily understand about object and class.
6- What are the differences between objects and abstract data typesSol.docxdanielt47
6. What are the differences between objects and abstract data types
Solution
Differences between Objects and Abstract data types:
______________________________________________
Objects: Object is an instance of a class and it has states and behaviours of class.
Abstract data type: It is a data type of abstract and it hides the representation of class, and it is typically implemented as a class and each instance of Abstract data type is usually an object of that class.
Objects and Abstract data types are not the same. But these are not different with each other.
Objects are a kind of Abstract data types.
An Abstract data type is an interface.But objects are instance of a class, with its own copy of any non-static variables.
Abstract data type is a collection of methods but in case of objects it is not an interface.It is an representation of a class with new operator.
A class can have one or more Abstract data types in the same way class can have one or more objects also.
To understand you with clear for Example, Collection interface is Abstract data type, ArrayList is a class and you can make ArrayList object with new operator.
.
chapter 1: Lecture 2
Let’s think on concept of Class and Object
- Concept of Objects and classes
- UML Class Diagram
الكلية الجامعية للعلوم والتكنولوجيا - خان يونس
University college of science & technology
Macroeconomics- Movie Location
This will be used as part of your Personal Professional Portfolio once graded.
Objective:
Prepare a presentation or a paper using research, basic comparative analysis, data organization and application of economic information. You will make an informed assessment of an economic climate outside of the United States to accomplish an entertainment industry objective.
Model Attribute Check Company Auto PropertyCeline George
In Odoo, the multi-company feature allows you to manage multiple companies within a single Odoo database instance. Each company can have its own configurations while still sharing common resources such as products, customers, and suppliers.
Operation “Blue Star” is the only event in the history of Independent India where the state went into war with its own people. Even after about 40 years it is not clear if it was culmination of states anger over people of the region, a political game of power or start of dictatorial chapter in the democratic setup.
The people of Punjab felt alienated from main stream due to denial of their just demands during a long democratic struggle since independence. As it happen all over the word, it led to militant struggle with great loss of lives of military, police and civilian personnel. Killing of Indira Gandhi and massacre of innocent Sikhs in Delhi and other India cities was also associated with this movement.
Francesca Gottschalk - How can education support child empowerment.pptxEduSkills OECD
Francesca Gottschalk from the OECD’s Centre for Educational Research and Innovation presents at the Ask an Expert Webinar: How can education support child empowerment?
Biological screening of herbal drugs: Introduction and Need for
Phyto-Pharmacological Screening, New Strategies for evaluating
Natural Products, In vitro evaluation techniques for Antioxidants, Antimicrobial and Anticancer drugs. In vivo evaluation techniques
for Anti-inflammatory, Antiulcer, Anticancer, Wound healing, Antidiabetic, Hepatoprotective, Cardio protective, Diuretics and
Antifertility, Toxicity studies as per OECD guidelines
Unit 8 - Information and Communication Technology (Paper I).pdfThiyagu K
This slides describes the basic concepts of ICT, basics of Email, Emerging Technology and Digital Initiatives in Education. This presentations aligns with the UGC Paper I syllabus.
MASS MEDIA STUDIES-835-CLASS XI Resource Material.pdf
Metaclass Programming in Python
1. 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
2. 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
3. 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
4. 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
5. 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
6. 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
7. 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
8. 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
9. 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
10. 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
11. 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
12. 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
13. 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
14. 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
15. 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
16. 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
17. 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
18. 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
19. 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
20. 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
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
22. 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
23. 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
24. 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
25. 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
26. 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
27. 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
28. 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
29. 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
30. 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
31. 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
32. 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
33. 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
34. 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
35. 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
36. 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
37. 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
38. 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
39. 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
40. 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
41. 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
42. 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
43. 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
44. 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
45. 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
46. 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
47. 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
48. 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
49. 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
50. 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
51. 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
52. 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
53. 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
54. 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
55. 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
56. 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
57. 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
58. 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
59. 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
60. 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
61. 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
62. 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
63. 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
64. 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
65. 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
66. 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
67. 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
68. 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
69. 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
70. 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
71. 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
72. 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
73. 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
74. 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
75. 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
76. 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
77. 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
78. 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
79. 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
80. 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
81. 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