[gull] Subtilité de C n° 2 : type de retour de malloc

Daniel Cordey dc at mjt.ch
Fri Apr 4 15:52:05 CEST 2008


On Thursday 03 April 2008, Leopoldo Ghielmetti wrote:

> Oui, mais comment tu fais pour éviter de mettre un mauvais objet dans
> une liste qui n'est pas forcement prévue pour l'accueillir? Il faudrait
> remplir le code de isinstance avant toute opération sur les listes.
> Mais ça ne risque pas de trop alourdir le code?

Non, isinstance est tres valable si tu veux simplement teste l'appartenance a 
une classe (cela gere aussi les "heritages"). Toutefois, quand tu dois tester 
entre plusisurs classes, il faut comparer le 'type' au contenu d'une liste 
predefinie. On peut aussi utiliser self.__class__ mais par principe d'evite 
d'utiliser des variables que l'on devrait considerer comme privees. Il est 
donc plus "popre" d'utiliser une methode y accedant.

> Sinon il faut commencer à écrire le code en ajoutant des isinstance
> partout pour ensuite refaire une passe et les effacer une fois le code
> débuggé.

Ci-joint un petit exemple de definition de classe, super-class (ou sous...) de 
la classe liste. CAD que j'herite de l'integralite des attributs de la classe 
list, et je redefini les methodes qui m'interesse. je redefinis aussi 
certains operateurs (operator overloading). Je precise qu'il s;agit d'un 
exemple simple et je n'ai pas redefini toutes les classes necesaires (comme 
__imul__, slice, etc.), mais il me semble que presque tous les cas de figures 
sont defini.

#!/usr/bin/python

import sys

class mylist(list) :
    def __init__(self,
                 newl = None) :
        list.__init__(self)
        self.allowed = set([type(1),
                            type(1.2),
                            type('a')])
        if newl :
            self.__add__(newl)

    def __check_type__(self,
                       elem) :
        ret = True
        xtype = type(elem)
        if xtype not in self.allowed :
            print 'Adding type %s not allowed' % xtype
            ret = False
        return ret
    

    def append(self,
               elem) :
        if self.__check_type__(elem) :
            list.append(self,
                        elem)


    def __add__(self,
                newl) :
        for elem in newl :
            if self.__check_type__(elem) :
                list.append(self,
                            elem)
        return self
    

    def __iadd__(self,
                 right) :
        return self.__add__(right)


    def insert(self,
               elem) :
        if self.__check_type__(elem) :
            list.insert(self,
                        elem)

    def __setslice__(self,
                     s,
                     e,
                     newl) :
        xelem = []
        for elem in newl :
            if self.__check_type__(elem) :
                xelem.append(elem)
            else :
                e -= 1

        if len(xelem) > 0 :
            list.__setslice__(self,
                              s,
                              e,
                              xelem)
            
# Debut de l;execution

y = ['toto']
x = mylist(y)
for elem in (1, 2.3, 'www', y) :
    x.append(elem)

print x
x += ['python shines', 'C too']
print x
x = x + (23, 'xxx')
print x
x[2:4] = [7, 4]
print x

################ output #######

Adding type <type 'list'> not allowed
['toto', 1, 2.2999999999999998, 'www']
['toto', 1, 2.2999999999999998, 'www', 'python shines', 'C too']
['toto', 1, 2.2999999999999998, 'www', 'python shines', 'C too', 23, 'xxx']
['toto', 1, 7, 4, 'python shines', 'C too', 23, 'xxx']


L'adjonction de ce test pour toute adjonction a la liste existante n'est pas 
couteux et peut-etre considere comme negligeable. On voit que ce genre de 
classe est tres facile a realiser et apporte une grande surete lorsque l'on 
doit controler le contenu d'un objet de ce type. On peut tout aussi 
surclasser un dictionnaire ou tout autre type/class en Python. D'autre part, 
la possibilite de redefinir tous les operateurs de la classe offre une tres 
grande souplesse. 

> Il ne me semble pas qu'il y a des macros en Python, donc on ne 
> peut pas juste avoir un #define DEBUG on/off qui va bien.

Oui, cela reste un langage interprete... Neanmoins, je debug de la maniere 
classique avec des :

	if debug > N :
		print ...

Pas extraordinaire et tres eloigne des possibilites du C/C++, mais on fait 
avec ce que l'on a...

> C'est justement le problème. Tant qu'on n'a pas assimilé le style de
> programmation Python on risque des erreurs de débutant. Malheureusement
> je suis encore débutant en Python et je n'ai pas beaucoup de
> possibilités d'expérimentations car au boulot on ne l'utilise pas.

Toute question obteindra une reponse sur cette liste (ou en prive).

dc






More information about the gull mailing list