1. Page d'accueil
  2. Informatique
  3. Bouts de code
  4. Python

Sous-ensemble d'une chaîne

SubData

Objectif

Le but est de créer un objet dont le champ data contient un ensemble d’octets, lus par exemple depuis un fichier, puis de créer un ou des sous-objets, décrits par un sous-ensemble des octets précédemment lus. Il peut être utile de pouvoir accéder aux octets qui définissent un sous-objet particulier, toutefois, afin de ne pas dupliquer plusieurs fois ces octets en mémoire, ce qui l’on ferait en copiant objet.data[m:n] dans sous-objet.data, la méthode choisie consiste à créer une classe qui se comporte à peu près comme une chaîne de caractères (elle possède des méthodes __len__, __getitem__ et __repr__) mais qui en fait récupère les données directement depuis le champ data de l’objet conteneur. D’autre part avec cette méthode les champs data des sous-objets resteront à jour à tout moment même après modification du champ data de l’objet conteneur.

Le code

 
import sys
 
class SubData:
    def __init__(self,owner,container):
        self.owner=owner
        self.container=container
 
    def __len__(self):
        if self.owner.end==0: return len(self.container.data)-self.owner.start
        else: return self.owner.end+1-self.owner.start
 
    def __getitem__(self, key):
        if isinstance(key,int):
            if key > self.owner.end and self.owner.end != 0: raise IndexError
            if key>=0: return self.container.data[key+self.owner.start]
            else: return self.container.data[self.owner.end+1+key]
        if isinstance(key,slice):
            start=key.start+self.owner.start
            if key.stop == sys.maxint:
                if self.owner.end==0: stop=key.stop
                else: stop=self.owner.end
            else:
                stop=key.stop+self.owner.start
                if stop > self.owner.end and self.owner.end != 0: raise IndexError
            step=key.step
            print repr(key.start),repr(key.stop),repr(key.step)
            return self.container.data[slice(start,stop,step)]
 
    def __repr__(self):
        start=self.owner.start
        if self.owner.end==0: stop=sys.maxint
        else: stop=self.owner.end
        return repr(self.container.data[slice(start,stop)])
 

Utilisation

 
class Object:
    def __init__(self):
        self.data=''
 
    def activate(self):
        self.subobject=SubObject(self)
 
class SubObject:
    def __init__(self,obj):
        self.start=0
        self.end=0
        self.data=SubData(self,obj)
 
myobject=Object()
myobject.activate()
myobject.data="It's rainy today,isn't it?"
print "object.data = %s" % myobject.data
print "By default object.subobject.data = %s" % myobject.subobject.data
myobject.subobject.start=3
print "Changing object.subobject.start to %i" % myobject.subobject.start
print "Now object.subobject.data = %s" % myobject.subobject.data
myobject.data="I don't think so. It is rather sunny."
print "Changing object.data to %s" % myobject.data
print "Now object.subobject.data = %s" % myobject.subobject.data
myobject.subobject.end=15
print "Changing object.subobject.end to %i" % myobject.subobject.end
print "Now object.subobject.data = %s" % myobject.subobject.data
myobject.subobject.end=0
print "Changing object.subobject.end to %i" % myobject.subobject.end
print "Now object.subobject.data = %s" % myobject.subobject.data
 

# Publié le 07-06-2007 à 16:45 par Christophe Garrigue.
Dans la rubrique Python.

Add a comment



Mention légale

Mention légale

Ce site personnel me sert principalement pour regrouper en un seul endroit tout ce que je publie sur Internet, ainsi que mes dessins et les quelques dossiers que j'ai eu l''occasion de faire au cours de mes études.
Tout le contenu de ce site est ma propriété exclusive et ne peut être réutilisé sans en faire la demande, sauf mention contraire (article sous une des licenses Creative Common par exemple). Il est toutefois possible de citer des parties des articles ici publiés comme le prévoit le code pénal français.
Police de bannière par Caffeen.