J'ai écrit la classe simple suivante comme un moyen de pointer efficacement en python :
class Parameter:
"""Sucre syntaxique pour une paire getter/setter
Usage:
p = Parameter(getter, setter)
Définir la valeur du paramètre :
p(valeur)
p.val = valeur
p.set(valeur)
Récupérer la valeur du paramètre :
p()
p.val
p.get()
"""
def __init__(self, getter, setter):
"""Créer un paramètre
Paramètres positionnels requis :
getter: appelé sans argument, récupère la valeur du paramètre.
setter: appelé avec une valeur, définit le paramètre.
"""
self._get = getter
self._set = setter
def __call__(self, val=None):
if val is not None:
self._set(val)
return self._get()
def get(self):
return self._get()
def set(self, val):
self._set(val)
@property
def val(self):
return self._get()
@val.setter
def val(self, val):
self._set(val)
Voici un exemple d'utilisation (à partir d'une page du cahier jupyter) :
l1 = list(range(10))
def l1_5_getter(lst=l1, number=5):
return lst[number]
def l1_5_setter(val, lst=l1, number=5):
lst[number] = val
[
l1_5_getter(),
l1_5_setter(12),
l1,
l1_5_getter()
]
Out = [5, None, [0, 1, 2, 3, 4, 12, 6, 7, 8, 9], 12]
p = Parameter(l1_5_getter, l1_5_setter)
print([
p(),
p.get(),
p.val,
p(13),
p(),
p.set(14),
p.get()
])
p.val = 15
print(p.val, l1)
[12, 12, 12, 13, 13, None, 14]
15 [0, 1, 2, 3, 4, 15, 6, 7, 8, 9]
Il est bien sûr également facile de faire fonctionner cela pour des éléments de dict ou des attributs d'un objet. Il existe même un moyen de faire ce que l'OP a demandé, en utilisant globals() :
def setter(val, dict=globals(), key='a'):
dict[key] = val
def getter(dict=globals(), key='a'):
return dict[key]
pa = Parameter(getter, setter)
pa(2)
print(a)
pa(3)
print(a)
Cela affichera 2, suivi de 3.
L'interaction avec l'espace de noms global de cette manière est en quelque sorte une idée terrible, mais cela montre qu'il est possible (bien qu'inconseillé) de faire ce que l'OP a demandé.
L'exemple est bien sûr assez inutile. Mais j'ai trouvé cette classe utile dans l'application pour laquelle je l'ai développée : un modèle mathématique dont le comportement est régi par de nombreux paramètres mathématiques définissables par l'utilisateur, de types divers (qui, étant donné qu'ils dépendent de arguments en ligne de commande, ne sont pas connus au moment de la compilation). Et une fois que l'accès à quelque chose a été encapsulé dans un objet Parameter, tous ces objets peuvent être manipulés de manière uniforme.
Bien que cela ne ressemble pas beaucoup à un pointeur C ou C++, cela résout un problème que j'aurais résolu avec des pointeurs si j'avais écrit en C++.
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.