const

Le
JBB
Je cherche un moyen de faire l'équivalent d'un const en C/C++.
ceci afin d'éviter la modification de certains objets par d'autres.

ex:
class Maclass(object):
def __init__(self):
self.x = 1
def reset(self):
self.x = 0

def f(i):
i.reset()

x = Maclasse()
f(x)
#j'aimerais être sur que l'appel de f ne modifie pas x
et donc empêcher que f appelle reset()

Voici l'état de mes réflexions:
Je peux faire de Maclasse un type 'terminal' comme str ou tupple que l'on ne peut pas modifier, mais je trouve cette solution
contraignante.
Soit je passe a f un copie de x ( ce que je trouve contraignant aussi, en plus d'être peut performant), de plus ça n'empêchera
pas f de modifier ma copie (pour rien).
Soit avant d'appeler f je supprime la methode reset() de x et je la remet après (?)
Sinon, à la Java je pourrais passer a f seulement une interface sur x ( mais cela ne doit pas avoir de sens en Python)

Bref je cherche une solution à la fois propre et performante.
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
hg
Le #601960
JBB wrote:

Je cherche un moyen de faire l'équivalent d'un const en C/C++.
ceci afin d'éviter la modification de certains objets par d'autres.

ex:
class Maclass(object):
def __init__(self):
self.x = 1
def reset(self):
self.x = 0

def f(i):
i.reset()

x = Maclasse()
f(x)
#j'aimerais être sur que l'appel de f ne modifie pas x
et donc empêcher que f appelle reset()

Voici l'état de mes réflexions:
Je peux faire de Maclasse un type 'terminal' comme str ou tupple que l'on
ne peut pas modifier, mais je trouve cette solution contraignante.
Soit je passe a f un copie de x ( ce que je trouve contraignant aussi, en
plus d'être peut performant), de plus ça n'empêchera pas f de modifier ma
copie (pour rien). Soit avant d'appeler f je supprime la methode reset()
de x et je la remet après (?) Sinon, à la Java je pourrais passer a f
seulement une interface sur x ( mais cela ne doit pas avoir de sens en
Python)

Bref je cherche une solution à la fois propre et performante.


Je me suis souvent posé cette question.

Une situation analogue qu'on voit souvent est que self._private ou
self.__private ne sont pas privées ... et que quand la question est posée,
la réponse des gourous est en général "...if a guy is stupid enough to
access a self._xxxx ... let him ! ...."

Ce qui nous rammène aux règles de codage.

Ma solution: mes "constantes" sont toutes en lettres capitales ... comme ça
je sais qu'il ne faut pas y toucher.


hg

hg
Le #605016
Philippe Bouige wrote:

In article
JBB wrote:

Je cherche un moyen de faire l'équivalent d'un const en C/C++.
ceci afin d'éviter la modification de certains objets par d'autres.



A voir sur le Web :

http://all4dev.libre-entreprise.org/index.php/Des_constantes_en_python
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65207

Cordialement Philippe


Merci,

Je note une petite coquille
http://all4dev.libre-entreprise.org/index.php/Des_constantes_en_python
"if attr in Const._items: # En python 2.1, écrire if attr in
Const.__items.keys()"

Par contre pour moi l'intérêt est de partager les constantes d'un module à
l'autre ce qui ne semble pas fonctionner avec cette implémentation ... mais
je rate puet-être quelque chose:
"""
t1.py
"""
import consts
import t2
class toto:
def __init__(self):
l_c = consts.Const()

l_c.C1 = 'tata'
print l_c.C1
l_t = t2.titi()




l= toto()
"""
t2.py
"""
import consts


class titi:
def __init__(self):
l_c = consts.Const()
# print 'ICI ', l_c.C1
print l_c.C1



pbouige
Le #605015
In article
JBB wrote:

Je cherche un moyen de faire l'équivalent d'un const en C/C++.
ceci afin d'éviter la modification de certains objets par d'autres.



A voir sur le Web :

http://all4dev.libre-entreprise.org/index.php/Des_constantes_en_python
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65207

Cordialement Philippe


Bruno Desthuilliers
Le #604850
Je cherche un moyen de faire l'équivalent d'un const en C/C++.
ceci afin d'éviter la modification de certains objets par d'autres.

ex:
class Maclass(object):
def __init__(self):
self.x = 1
def reset(self):
self.x = 0

def f(i):
i.reset()

x = Maclasse()
f(x)
#j'aimerais être sur que l'appel de f ne modifie pas x
et donc empêcher que f appelle reset()


Pourquoi appeller cette méthode alors ?????



Voici l'état de mes réflexions:
Je peux faire de Maclasse un type 'terminal'


immutable.

comme str ou tupple que
l'on ne peut pas modifier, mais je trouve cette solution contraignante.

Soit je passe a f un copie de x ( ce que je trouve contraignant aussi,
en plus d'être peut performant), de plus ça n'empêchera pas f de
modifier ma copie (pour rien).
Soit avant d'appeler f je supprime la methode reset() de x et je la
remet après (?)


T'a pas l'impression de te compliquer un peu la vie ?

Sinon, à la Java je pourrais passer a f seulement une interface sur x (
mais cela ne doit pas avoir de sens en Python)


Non. Mais tu peux utiliser un proxy:

class RestrictiveProxy(object):
def __init__(self, obj, *dont_proxy):
self.__obj = obj
self.__dont_proxy = dont_proxy

def __check(self, name):
if name in self.__dont_proxy:
raise AttributeError("access to %s is restricted")

def __getattr__(self, name):
self.__check(name)
return getattr(self.__obj, name)

# je zappe le __setattr__ parce qu'il est
# un peu plus compliqué et que ce n'est pas
# nécécessaire pour l'exemple


x = MaClasse()
try:
f(RestrictiveProxy(x, 'reset'))
except AttributeError, e:
print "semble ok ? %s" %e
else:
print "marche pas..."

(NB : pas testé)

Bref je cherche une solution à la fois propre et performante.


La solution "propre et performante" est de ne pas appeler x.reset, ou de
ne pas passer x à f.

tool69
Le #604849
Bonsoir,

J'essaye depuis quelques temps de parser des strucutures du genre :

"du texte ici ${1:truc} du texte là ${2:machin}"

En sortie, il me faudrait :

- l'index du début de chaque tag
- le numero du tag correspondant
- le contenu du tag (qui se trouve derrière le délimiteur ':')

Pour le premier tag, cela donnerait donc [13,1,'truc'].

J'ai bien réussi à faire ça avec des regexps, le problème arrive
évidemment lorsque je veux parser des strucutres imbriquées comme celle-ci :

"du texte ici ${1:truc} du texte là ${2:${3:truc} ${4:truc}}"

Dans ce cas, il me faudra pour chaque tag rencontré les 3 points
précédemment cités, ainsi qu'un quatrième : le niveau d'imbrication.

A part écrire des choses à la main (ce que j'ai fait) avec des
string.find ou string.index, qu'auriez-vous à me proposer ? idées,
modules (j'ai déjà essayé PyParsing, et l'auteur est très sympas
d'ailleurs, mais ça ne convient pas).

D'avance merci,

Kib².
Mihamina (R12y) Rakotomandimby
Le #604848
tool69 -
Bonsoir,


Bonsoir,

J'essaye depuis quelques temps de parser des strucutures du genre :
[...]

"du texte ici ${1:truc} du texte là ${2:${3:truc} ${4:truc}}"


- Je vois mal le rapport avec les "const". Mais bon tu as dû te tromper de
bouton (Follow-up au lieu de New)

- Est-ce que tu dois vraiment le faire en Python?

Mihamina (R12y) Rakotomandimby
Le #604847
tool69 -
Bonsoir,


Bonsoir,

J'essaye depuis quelques temps de parser des strucutures du genre :
[...]

"du texte ici ${1:truc} du texte là ${2:${3:truc} ${4:truc}}"


- Je vois mal le rapport avec les "const". Mais bon tu as dû te tromper de
bouton (Follow-up au lieu de New)
- Est-ce que tu dois vraiment le faire en Python?
- Si tu arrive à le faire pour "un niveau d'imbrication" en utilisant la
recursivité, tu devrais pouvoir le faire sur "plusieurs niveaux". Mais il y
a des langages très bien adaptés pour utiliser la recursivité, d'ou ma
question précédente.
- Tu aurais pu donner un exemple de ce que tu as trouvé et qui marche
partiellement.

tool69
Le #604846
Désolé pour le bouton, depuis que je suis passé à cet écran Wide, j'ai
un peu de mal avec les caractères tout petits.

Bon, sinon voilà un des scripts que j'ai écris :

---------------------
#!/usr/bin/env python
# -*- coding: latin1 -*-

import string

STARTER = "${"
ENDER = "}"

def parse(template):
state = 0
opened_brack = 0
static = ""
fields = []
starts = []
j=0
print 'Examining n', template,'n'
for c in template :
i=j
#print 'examine',c,'starts',starts,i
if c == '$' :
state = 1
elif c == '{' and state == 1 :
opened_brack += 1
starts.append(i-1)
elif c == '}' :
st = starts.pop()
fields.append( [st, template[st+len(STARTER):i] ,
opened_brack-1])
opened_brack -= 1
state = 0
else :
if state == 0 :
static += c
j += 1
print 'Static Textnt',static,'n'
return fields

tpl = "Un ${1:truc} avec son ${2:${3:bidule} dans un
${4:${5:${6:machin}}}}."

for el in parse(tpl) : print el
---------------------

Ca marche, mais bon, je trouve ça un peu 'bidouille'
Mihamina (R12y) Rakotomandimby
Le #604845
tool69 -
Bon, sinon voilà un des scripts que j'ai écris :


Je voulais te le nettoyer un peu, mais apres bientot 3 mois de cure de PHP
sans rien avoir écrit en Python, je me retrouve incapable d'écrire un bout
de code décent (et pourtant je suis assez peu rigoureux).
Bon ben faut que je m'invente des petits trucs à faire en Python...

Bruno Desthuilliers
Le #604844
Désolé pour le bouton, depuis que je suis passé à cet écran Wide, j'ai
un peu de mal avec les caractères tout petits.

Bon, sinon voilà un des scripts que j'ai écris :

---------------------
#!/usr/bin/env python
# -*- coding: latin1 -*-

import string

STARTER = "${"
ENDER = "}"

def parse(template):
state = 0
opened_brack = 0
static = ""
fields = []
starts = []
j=0
print 'Examining n', template,'n'
for c in template :
i=j
#print 'examine',c,'starts',starts,i
if c == '$' :
state = 1
elif c == '{' and state == 1 :
opened_brack += 1
starts.append(i-1)
elif c == '}' :
st = starts.pop()
fields.append( [st, template[st+len(STARTER):i] ,
opened_brack-1])
opened_brack -= 1
state = 0
else :
if state == 0 :
static += c
j += 1
print 'Static Textnt',static,'n'
return fields

tpl = "Un ${1:truc} avec son ${2:${3:bidule} dans un
${4:${5:${6:machin}}}}."

for el in parse(tpl) : print el
---------------------

Ca marche,


Tel que, ça ne correspond pas à ton cahier des charges.

mais bon, je trouve ça un peu 'bidouille'


Le fait de faire le parsing à la mano, dans un cas aussi simple, n'est
pas nécessairement de la bidouille en soi. Par contre, ton code est AMHA
inutilement compliqué.

START = "${"
END = "}"

_start_len = len(START)
_end_len = len(END)

def parse(template):
fields = []
fields_starts = []

for position, _ in enumerate(template):
if template[position:position + _start_len] == START:
fields_starts.append(position)
elif template[position:position + _end_len] == END:
depth = len(fields_starts)
if depth:
start = fields_starts.pop()
key, content =
template[start + _start_len:position].split(':', 1)
fields.append((start, int(key), content, depth-1))
return fields

tpl = """
Un ${1:truc} avec son ${2:${3:bidule} dans un ${4:${5:${6:machin}}}}.
"""
for field in parse(tpl):
print field

(3, 1, 'truc', 0)
(26, 3, 'bidule', 1)
(54, 6, 'machin', 3)
(50, 5, '${6:machin}', 2)
(46, 4, '${5:${6:machin}}', 1)
(22, 2, '${3:bidule} dans un ${4:${5:${6:machin}}}', 0)

HTH

Publicité
Poster une réponse
Anonyme