Je veux que form.data['field']
et form.field.value
aient toujours la même valeur
C'est faisable, car cela implique des noms décorés et de l'indexation -- c'est-à-dire des constructions complètement différentes des noms seuls a
et b
dont vous parlez, et pour lesquelles votre demande est totalement impossible. Pourquoi demander quelque chose d'impossible et totalement différent de la chose (possible) que vous voulez réellement ?!
Peut-être que vous ne réalisez pas à quel point les noms seuls et les noms décorés sont radicalement différents. Lorsque vous faites référence à un nom seul a
, vous obtenez exactement l'objet auquel a
était lié en dernier dans cette portée (ou une exception s'il n'était pas lié dans cette portée) -- c'est un aspect si profond et fondamental de Python qu'il ne peut être détourné. Lorsque vous faites référence à un nom décoré x.y
, vous demandez à un objet (l'objet auquel x
fait référence) de fournir "l'attribut y
" -- et en réponse à cette demande, l'objet peut effectuer des calculs totalement arbitraires (et l'indexation est assez similaire: elle permet également d'effectuer des calculs arbitraires en réponse).
Maintenant, votre exemple de "véritables désidératas" est mystérieux car dans chaque cas, deux niveaux d'indexation ou d'obtention d'attributs sont impliqués, donc la subtilité que vous recherchez pourrait être introduite de plusieurs manières. Quels autres attributs form.field
est censé avoir, par exemple, en plus de value
? Sans ces calculs supplémentaires en .value
, les possibilités pourraient inclure:
class Form(object):
...
def __getattr__(self, name):
return self.data[name]
et
class Form(object):
...
@property
def data(self):
return self.__dict__
La présence de .value
suggère de choisir le premier exemple, plus un wrapper un peu inutile :
class KouWrap(object):
def __init__(self, value):
self.value = value
class Form(object):
...
def __getattr__(self, name):
return KouWrap(self.data[name])
Si des affectations telles que form.field.value = 23
doivent également définir l'entrée dans form.data
, alors le wrapper doit effectivement devenir plus complexe, et pas si inutile que cela :
class MciWrap(object):
def __init__(self, data, k):
self._data = data
self._k = k
@property
def value(self):
return self._data[self._k]
@value.setter
def value(self, v)
self._data[self._k] = v
class Form(object):
...
def __getattr__(self, name):
return MciWrap(self.data, name)
Le dernier exemple est à peu près ce qui se rapproche le plus, en Python, du sens d'un "pointeur" tel que vous semblez le vouloir -- mais il est crucial de comprendre que de telles subtilités ne peuvent jamais fonctionner qu'avec des index et/ou des noms décorés, jamais avec des noms seuls comme vous l'avez demandé initialement !
30 votes
Peut-être que je peux poser une question similaire à celle de S.Lott (mais plus productive) : pouvez-vous nous montrer un vrai code où vous vouliez faire cela ? Peut-être même dans une autre langue qui correspond davantage à vos goûts ? Il est probable que le problème que vous essayez de résoudre se prête à une solution plus pythonique, et se concentrer sur "je veux des pointeurs" obscurcit la vraie réponse.
10 votes
Il ne faut pas beaucoup d'imagination; je peux penser à des dizaines de raisons pour vouloir le faire. Ce n'est tout simplement pas comme ça que cela se passe dans les langages sans pointeur comme Python; vous devez l'encadrer dans un conteneur qui n'est pas invariant, comme dans la réponse de Matt.
0 votes
@Ned : Question mise à jour. Un autre exemple serait pour une fonction,
swap(a, b)
. Pas que j'en ai besoin tout de suite.21 votes
Vous ne voudriez pas écrire une fonction d'échange en Python. Vous écririez
a, b = b, a
.4 votes
-1: La construction dans la question est (a) sans fondement et (b) personne ne semble pouvoir fournir un exemple qui la rende sensée. Dire qu'il y a "des dizaines de raisons" n'est pas la même chose que de poster un exemple.
0 votes
@Mark: donner un alias à une variable est totalement absurde. Je demande un exemple de comment ou pourquoi un alias pourrait être autre que de la confusion totale et absolue. Ton exemple de deux noms qui ne correspondent pas pour la même variable me laisse perplexe. Pourquoi rendre les choses plus complexes? Pourquoi ajouter la complexité des alias? Beaucoup de programmeurs se trompent avec les pointeurs en C. Pourquoi essayer d'ajouter ce problème propice aux erreurs en Python?
0 votes
@Mark : "Pourquoi les forcer à passer par...?" Parce que c'est ainsi que les choses sont. Je ne vois pas où est le problème. Vous pouvez attribuer
a= form.field.widget
puis fairea.value
. Je ne vois pas où est le problème.1 votes
@Mark : De plus, je ne "suis pas en désaccord". Je suis confus. Je pose une question, cherchant un moyen de comprendre ce que c'est et pourquoi vous pensez que c'est si important.
0 votes
@Mark: Je ne comprends pas le cas d'utilisation. J'essaie d'éviter tout commentaire sur l'importance. Je cherche un exemple d'alias qui est utile ou rend le code plus compréhensible. Je suis toujours à la recherche. En l'absence d'un exemple, je suggère que la question n'est pas une bonne question sur Python car elle semble demander une fonction qui n'a pas de valeur. Veuillez mettre à jour la question avec un exemple d'alias (ou "pointeur") qui ne crée pas de nouvelles formes de confusion.
0 votes
@Mark: Je ne suis pas en « désaccord ». Je cherche une explication. Et je n'en ai pas. Il semble que vous ayez convenu de ne pas fournir d'explication. Par conséquent, je suis amené à « accepter » de cesser de demander une explication.
0 votes
@ Mark : Je ne peux pas suivre "une variable qui est utilisée à deux endroits différents de manière extensive, je n'aime pas que l'une d'elles soit extrêmement verbeuse". C'est une variable. Comment une variable peut-elle être verbeuse ?
0 votes
@mpen J'ai restauré le
form.data['field'] is form.field.value
car plusieurs réponses faisaient référence à cela.0 votes
@AnttiHaapala Pas de problème. Parfois, j'aime supprimer les informations superflues, mais si vous pensez que c'est utile, c'est bien.
0 votes
@Mark : Je pense que tu veux dire 'reference faible' (au sens de Python), pas 'variable'.
0 votes
@smci Je pense que j'avais plus quelque chose comme un 'hardlink' en tête dans Linux. Les weakrefs meurent quand le référent n'est plus en vie.