-------- Classes -------- Définition d'une classe ----------------------- >>> class MyClass: pass Variable de classe ------------------ >>> class MyClass: ... value = "foobar" ... ... def hello(self): ... return ('Hello world') ... Instanciation d'un objet ------------------------- ... ... >>> my_object = MyClass() >>> my_object <__main__.MyClass instance at 0x10fed1cb0> Accès à un attribut ------------------- >>> my_object.value "foobar" Création et modification d'un attribut ----------------------------------- >>> my_object.other_value = 123 >>> my_object.other_value 123 Appel d'une méthode (invocation) -------------------------------- >>> my_object.hello() 'Hello world' >>> my_object.value 'foobar' Initialisation -------------- >>> class MyClass: ... def __init__(self): ... self.value = "foobar" ... ... ... >>> my_object = MyClass() >>> my_object.value 'foobar' 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 > >>> circle.area() 314.0 Notez l'appel à self.radius 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 Méthodes statiques ------------------ >>> class Foo: ... @staticmethod ... def display(): #pas de self ... print ('bar') ... ... ... >>> Foo.display() bar 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 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 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) New style classes ------------------ >>> class Shape(object): 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 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. 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 "", line 1, in AttributeError: 'Foo' object has no attribute '__private' 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' 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 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 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__()