Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

référence à une variable

10 réponses
Avatar
Xavier
Bonjour,

Dans le code suivant je voudrais mettre à jour les chaînes a, b et c si
le nom de celles-ci sont dans d.
Pour celà je crée vars qui associe le nom 'a' à la variable a, ainsi
dans f() j'aimerais affecter a via ce que j'ai noté vars['a'] et qui
donc est faux.
Quelle est la forme correcte et y a t'il plus simple (sans passer par
vars) ?
Un lien vers de la lecture sur le sujet m'interesse aussi.


def f(d = {}):
for k in d.keys():
if k in vars:
# XXX
vars[k] = d[k]

a = 'a'
b = 'b'
c = 'c'
vars = { 'a': a, 'b': b, 'c': c }

d = { 'toto': 1, 'a': 'chaine a', 'c': 'chaine c' }
f(d)
print a, b, c
# jvoudrais bien:
# chaine a b chaine c

10 réponses

Avatar
MC
Bonsoir !

En modifiant très peu ton code :
def f(d = {}):
for k in d.keys():
if k in globals():
# XXX
globals()[k] = d[k]

a = 'a'
b = 'b'
c = 'c'
d = { 'toto': 1, 'a': 'chaine a', 'c': 'chaine c' }
f(d)
print a, b, c







--
@-salutations

Michel Claveau
Avatar
MC
Re !

Et, si on accepte de créer la variable globale "toto" :

def f(d):
globals().update(d)

a, b, c = 'a', 'b', 'c'
d={'toto': 1, 'a': 'chaine a', 'c': 'chaine c' }
f(d)
print a, b, c, toto









--
@-salutations

Michel Claveau
Avatar
Bruno Desthuilliers
Bonjour,

Dans le code suivant je voudrais mettre à jour les chaînes a, b et c si
le nom de celles-ci sont dans d.
Pour celà je crée vars qui associe le nom 'a' à la variable a, ainsi
dans f() j'aimerais affecter a via ce que j'ai noté vars['a'] et qui
donc est faux.
Quelle est la forme correcte et y a t'il plus simple (sans passer par
vars) ?
Un lien vers de la lecture sur le sujet m'interesse aussi.


def f(d = {}):


Attention, les arguments par défaut ne sont évalués *qu'une seule fois*,
lors de la définition de la fonction.
def toto(d=[]):
... d.append('WTF?')



... print d
...
toto()
['WTF?']



toto()
['WTF?', 'WTF?']



toto()
['WTF?', 'WTF?', 'WTF?']



toto()
['WTF?', 'WTF?', 'WTF?', 'WTF?']









for k in d.keys():
if k in vars:
# XXX
vars[k] = d[k]

a = 'a'
b = 'b'
c = 'c'
vars = { 'a': a, 'b': b, 'c': c }

d = { 'toto': 1, 'a': 'chaine a', 'c': 'chaine c' }
f(d)
print a, b, c
# jvoudrais bien:
# chaine a b chaine c


MC t'a donné une solution fonctionnelle. Ceci étant, sur le fond, ce que
tu veux faire (modifier des variables globales depuis une fonction) est
*généralement* une très mauvaise idée. Si tu est sûr ce que tu faits,
très bien, sinon tu devrais peut-être réfléchir à d'autres solutions
(comme par exemple un objet encapsulant les variables d'état et les
fonctions les utilisant...)

Mes deux centimes...



Avatar
Xavier
Bonjour,

merci pour vos réponses. Effectivement je ne veux pas particulièrement
modifier des variables globales, mon exemple était simplifié.

J'ai donc une fonction qui parse et qui construit un dictionnaire,
certaines infos me sont utiles (ou pas). L'idée est ensuite de pouvoir
affecter des variables si celle-ci existent (a, b ou c de A ou e ou f de B).

def myparse(file):
dico = {}
# des trucs
# dico = {'a': 1, 'c': 'chaine c', 'e': 5}
return dico

class A(object):
a = 0
b = ''
c = ''
knownvars = [ 'a', 'b', 'c' ]

def __init__(self, d):
for k in d.keys():
if k in self.knownvars:
# affecte self.labonnevariable

class B(object):
e = 0
f = ''
knownvars = [ 'e', 'f' ]

...

ret = myparse(fichier)
A(ret)


C'était peut être une approche un peu trop naïve :) et voulais savoir
si il y avait une méthode élégante, simple et rapide de faire ça.
J'ai remplacé par...

class A(object):
a = 0
b = ''
c = ''

def __init__(self, d):
if 'a' in d:
self.a = d['a']
if 'b' in d:
self.b = d['b']
if 'c' in d:
self.c = d['c']




def f(d = {}):
Attention, les arguments par défaut ne sont évalués *qu'une seule fois*,

lors de la définition de la fonction.


Ha, merci.


(comme par exemple un objet encapsulant les variables d'état et les
fonctions les utilisant...)


Aurais-tu un lien vers du code à lire qui aille dans ce sens ?


Avatar
Bruno Desthuilliers
Bonjour,

merci pour vos réponses. Effectivement je ne veux pas particulièrement
modifier des variables globales, mon exemple était simplifié.

J'ai donc une fonction qui parse


qui parse quoi ?-)

et qui construit un dictionnaire,
certaines infos me sont utiles (ou pas). L'idée est ensuite de pouvoir
affecter des variables si celle-ci existent (a, b ou c de A ou e ou f de
B).

def myparse(file):
dico = {}
# des trucs
# dico = {'a': 1, 'c': 'chaine c', 'e': 5}
return dico

class A(object):
a = 0
b = ''
c = ''
knownvars = [ 'a', 'b', 'c' ]


Attention, tous les attributs ci-dessus sont des attributs de classe. Si
c'est pour fournir une valeur par défaut, c'est une approche possible,
mais autant savoir ce qu'on fait... Par exemple, si une de ces variables
est mutable et qu'elle est mutée, cela sera visible dans toutes les
instances:

class Machin(object):
... toto = []



...
m1 = Machin()
m2 = Machin()
m1.toto.append(1)
m2.toto
[1]









def __init__(self, d):
for k in d.keys():
if k in self.knownvars:
# affecte self.labonnevariable

(snip)

ret = myparse(fichier)
A(ret)


C'était peut être une approche un peu trop naïve :) et voulais savoir
si il y avait une méthode élégante, simple et rapide de faire ça.
J'ai remplacé par...

class A(object):
a = 0
b = ''
c = ''

def __init__(self, d):
if 'a' in d:
self.a = d['a']
if 'b' in d:
self.b = d['b']
if 'c' in d:
self.c = d['c']




class A(object):
_defaults = dict(a=0, b='', c='')

def __init__(self, **kw):
for k in self._defaults:
setattr(self, k, kw.get(k, self._defaults[k]))



(comme par exemple un objet encapsulant les variables d'état et les
fonctions les utilisant...)



Aurais-tu un lien vers du code à lire qui aille dans ce sens ?


La bibliothèque standard est probablement un bon début !-)



Avatar
Xavier
[...]

C'est qu'on en apprend des choses ici, faut que je poste plus souvent !

La bibliothèque standard est probablement un bon début !-)


Ha oui bon, ça semble en effet s'imposer :)

X

Avatar
Bruno Desthuilliers
[...]

C'est qu'on en apprend des choses ici, faut que je poste plus souvent !


Pas de problème, plus on est de fous etc... !-)


La bibliothèque standard est probablement un bon début !-)


Ha oui bon, ça semble en effet s'imposer :)


Je ne sais pas pourquoi, mais il semble que pas mal de personnes
oublient cet intérêt majeur du logiciel libre : on peut lire les sources...


Avatar
Méta-MCI \(MVP\)
Salut !

cet intérêt majeur du logiciel libre : on peut lire les sources...


Bof ! Lire des dizaines de milliers de lignes en C, ça ressemble
plutôt à du somnifère (libre), qu'à une activité intéressante.


@+

MCI

Avatar
Laurent Pointal
Salut !

cet intérêt majeur du logiciel libre : on peut lire les sources...


Bof ! Lire des dizaines de milliers de lignes en C, ça ressemble
plutôt à du somnifère (libre), qu'à une activité intéressante.


Dans les librairies standard de Python, tout n'est pas en C, il y en a
pas mal en Python.

Par contre, ça n'est pas toujours évident au premier abord, certaines
choses ne sont pas triviales (car rendues souples et portables... mais
moins lisibles/compréhensibles par un pécun).


Avatar
Bruno Desthuilliers
Salut !

cet intérêt majeur du logiciel libre : on peut lire les sources...


Bof ! Lire des dizaines de milliers de lignes en C, ça ressemble
plutôt à du somnifère (libre), qu'à une activité intéressante.


Eh oui, mon petit Michel... Dans ce monde, il y a 10 sortes de
personnes: ceux qui lisent du code et les autres !-)

Ok, -------->[]