metaprogramming in python
roberto bampi @ trenta3dev
things that make me happy
( things I'm going to talk about)
- objects in python (introduction to oop)
- new style classes
- getattr, setattr, hasattr
- classes as objects
- __init__ and __new__
- metaclasses
THINGS THAT MAKE ME SAD
(things I'm not going to talk about)
- old style classes
oop: Object oriented python
class Foobar(object):
def __init__(self, baz):
self.baz = baz
But, unlike other languages,
everything
in python is a object
let's talk about new style classes
Known to python programmers as
"the way classes should always have worked"
(they did not)
New style classes always have object
at the top of their inheritance chain
>>> class Foo(object): pass
>>> Foo.__mro__
(Foo, object)
dynamism
python is a dynamic language
>>> class Foobar(object):
pass
>>> myobj = Foobar()
>>> myobj.my_custom_var = 123
>>> myobj.my_custom_var
123
>>> Foobar.my_custom_var
AttributeError: type object 'Foobar' has no attribute 'my_custom_var'
we can not be sure of what members
an instance will have at any given time
tools to deal with dynamism
- getattr(obj, name, [default])
- hasattr(obj, name)
- setattr(obj, name, value)
>>> class Foobar(object):
def __init__(self):
self.i_exist = 'i really do'
>>> foo_inst = Foobar()
>>> hashattr(foo_inst, 'i_exist')
True
>>> getattr(foo_inst, 'i_exist')
'i really do'
>>> hasattr(foo_inst, 'i_do_not_exist')
False
>>> getattr(foo_inst, 'i_do_not_exist', 'i am the default')
'i am the default'
>>> setattr(foo_inst, 'i_do_not_exist', 'i exist now')
>>> getattr(foo_inst, 'i_do_not_exist')
'i exist now'
CLasses as objects
>>> int.__class__
type
used to build concrete instances that can then be used
let's find out how this works !
__NEW__ and __init__
whenever we want to build an instance
of an object two things happen:
- a new object of the desired type is created: __new__
- the new object can then be initialized: __init__
creation of an instance
>>> class MyClass(object):
def __new__(cls):
print "in __new__"
return super(MyClass, cls).__new__(cls)
def __init__(self):
print "in __init__"
self.bar = 123
>>> myinstance = MyClass()
in __new__
in __init__
metaclasses
since classes are `just objects`
metaclasses are the way to customize
their creation
the base metaclass is type
type's type is type
what does a metaclass do anyway
a metaclass can be any class that
inherits from type
class MyMeta(type):
def __new__(cls, name, parents, dct):
# this method has the responsability to
# create and return a new instance of type
# the only way to do so is to call type itself (or any subclass)
print "A new class named " + name + " is going to be created"
return super(MyMeta, cls).__new__(cls, name, parents, dct)
and overrides either __new__ or __init__
to provide custom behavior
How it is used
a custom metaclass can be explicitly
set on the class itself like so
class MyClass(object):
__metaclass__ = MyMeta
The lookup order for a metaclass is as follows:
on the class
in the parents
in the package
use with care
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
DEMO TIME !
That's all folks !
and thank you for listening to me.
- bampi.roberto@gmail.com
- github.com/gigaroby
metaprogramming in python
By gigaroby
metaprogramming in python
- 13,226