19. Classes¶
19.1. Définition d’une classe¶
>>> class MyClass:
pass
19.2. Variable de classe¶
>>> class MyClass:
... value = "foobar"
...
... def hello(self):
... return ('Hello world')
...
19.3. Instanciation d’un objet¶
>>> my_object = MyClass() >>> my_object <__main__.MyClass instance at 0x10fed1cb0>
19.4. Accès à un attribut¶
>>> my_object.value
"foobar"
19.5. Création et modification d’un attribut¶
>>> my_object.other_value = 123
>>> my_object.other_value
123
19.6. Appel d’une méthode (invocation)¶
>>> my_object.hello()
'Hello world'
>>> my_object.value
'foobar'
19.7. Initialisation¶
>>> class MyClass:
... def __init__(self):
... self.value = "foobar"
...
...
...
>>> my_object = MyClass()
>>> my_object.value
'foobar'
19.8. Initialisation avec paramètres¶
>>> class Circle:
... def __init__(self, radius):
... self.radius = radius
...
... def area(self):
... return 3.14 * self.radius ** 2
...
...
...
>>> circle = Circle(10)
>>> c.area
<bound method Circle.area of <__main__.Circle instance at 0x10fd7de18>>
>>> circle.area()
314.0
Notez l’appel à self.radius
19.9. Avec une variable de classe¶
>>> class Circle:
... pi = 3.14
... def __init__(self):
... self.radius = 10
... def area(self):
... return self.pi * self.radius**2
...
...
...
>>> c= Circle()
>>> c.area()
314.0
19.10. Méthodes statiques¶
>>> class Foo:
... @staticmethod
... def display(): #pas de self
... print ('bar')
...
...
...
>>> Foo.display()
bar
19.11. Un example de méthode statique¶
>>> class Shape:
... all_shapes =[]
...
... def __init__(self, name):
... self.name = name
... self.__class__.all_shapes.append(self)
... @staticmethod
... def count():
... return len(Shape.all_shapes)
...
...
...
>>> my_rectangle = Shape('rectangle')
>>> my_sqaure = Shape('square')
>>> my_circle = Shape('circle')
>>> Shape.count()
3
19.12. Class Methods¶
>>> class Shape:
... all_shapes =[]
...
... def __init__(self, name):
... self.name = name
... self.__class__.all_shapes.append(self)
... @classmethod
... def count(cls):
... return len(cls.all_shapes)
...
...
...
>>> my_rectangle = Shape('rectangle')
>>> my_sqaure = Shape('square')
>>> my_circle = Shape('circle')
>>> Shape.count()
La classe est passée implicitement
19.13. Héritage¶
>>> class Shape:
... def __init__(self, x, y):
... self.x = x
... self.y = y
...
>>> class Circle(Shape):
... def __init__(self,x, y, radius):
... self.x = x
... self.y = y
... self.radius = radius
...
...
...
>>> c=Circle(1,2, 20)
19.14. New style classes¶
>>> class Shape(object):
19.15. Héritage avec super()¶
>>> class Shape(object):
... def __init__(self, x, y):
... self.x = x
... self.y = y
...
...
...
>>> class Circle(Shape):#python 2.X
... def __init__(self,x, y, radius):
... super(Circle, self).__init__(x, y)
...
...
...
>>> c = Circle(1,2,3)
>>> class Square(Shape):# python 3.X
... def __init__(self,x,y,side):
... super().__init__(x,y)
... self.side = side
19.16. Monkey patching¶
Remplacer un attribut à la volée.
>>> def what(): ... return "a monkeypatch" ... ... >>> c.what = what >>> c.what() 'a monkeypatch'
A éviter autant que possible.
19.17. Variables privées¶
>>> class Foo(object):
... def __init__(self):
... self.name = "bar"
... self.__private = "baz"
...
... def print_private(self):
... print (self.__private)
...
...
...
>>> f=Foo()
>>> f.print_private()
baz
>>> f.name
'bar'
>>> f.__private
Traceback (most recent call last):
File "<input>", line 1, in <module>
AttributeError: 'Foo' object has no attribute '__private'
19.18. Name Mangling¶
>>> dir(f)
['_Foo__private', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__',
'__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__s
tr__', '__subclasshook__', '__weakref__', 'name', 'print_private']
>>> f._Foo__private
'baz'
__private –> “_Foo__private”
19.19. Getters et setters¶
Pas de getter et setters en python
class Length(object):
def __init__(self):
self._length_inches = 0
@property
def length(self):
return self._length_inches * 2.54
@length.setter
def length(self, new_length):
self._length_inches = new_length / 2.54
@property
def inchlength(self):
return self._length_inches
@inchlength.setter
def inchlength(self, new_length):
self._length_inches = new_length
l = Length()
l.length = 10
print(l.length)
print(l.inchlength)
l.inchlength= 44
print(l.inchlength)
print(l.length)
On peut utiliser getter, setter, deleter
class C(object):
def __init__(self):
self._x = None
@property
def x(self):
"""I'm the 'x' property."""
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
19.20. Destructeurs¶
On s’en sert rarement. On utilise la méthode __del__()
>>> class A(object):
... def __del__(self):
... print ('destruction')
...
...
...
>>> def foo():
... a = A()
...
...
>>> foo()
destruction
19.21. Context manager: with¶
file = open(« /tmp/foo.txt ») data = file.read() file.close()
Avec with
with open(« /tmp/foo.txt ») as file: data = file.read()
Implémentation: méthodes __enter__ et __exit__
>>> class Sample:
... def __enter__(self):
... print "In __enter__()"
... return "Foo"
...
... def __exit__(self, type, value, trace):
... print "In __exit__()"
...
>>> def get_sample():
... return Sample()
...
...
>>> with get_sample() as sample:
... print ('sample: ', sample)
...
...
In __enter__()
('sample: ', 'Foo')
In __exit__()