2010-10-03 7 views
4

Je veux avoir aa référence qui se lit comme « quelle que soit la variable du nom « x » est pointant vers » avec ints pour qu'il se comporte comme:Howto faire référence à ints par nom en Python

>>> a = 1 
>>> b = 2 
>>> c = (a, b) 
>>> c 
(1, 2) 
>>> a = 3 
>>> c 
(3, 2) 

Je sais Je pouvais faire quelque chose de similaire avec des listes en faisant:

>>> a = [1] 
>>> b = [2] 
>>> c = (a, b) 
>>> c 
([1], [2]) 
>>> a[0] = 3 
>>> c 
([3], [2]) 

mais cela peut être facilement perdu si l'on attribue un ou b à quelque chose au lieu de leurs éléments.

Existe-t-il un moyen simple de faire cela?

+0

Je pense que vous avez déjà indiqué le plus proche que vous obtiendrez. Si cela est au cœur de ce que vous faites, peut-être un langage différent conviendrait-il. – JoshD

Répondre

4

Non, il n'y a pas de moyen direct de faire cela en Python. La raison en est que les deux valeurs scalaires (nombres) et tuples sont immuable. Une fois que vous avez établi une liaison d'un nom à une valeur immuable (par exemple le nom c avec le nip (1, 2)), rien de ce que vous faites, sauf la réaffectation c, peut changer la valeur à laquelle il est lié.

Notez que dans votre second exemple, bien que le tuple lui-même soit immuable, il contient des références à des valeurs mutables. Donc, il apparaît comme si le tuple change, mais l'identité du tuple reste constante et seules les parties mutables changent.

+0

En effet l'utilisation du tuple peut être trompeuse, puisque je suis après la mutabilité indirecte après tout. Même si la référence elle-même devrait être immuable. – Unode

2

Quelle que soit la solution que vous venez avec la deuxième ligne dernière sera toujours détruire:

a = 3 

Cela assignera un tout nouveau contenu à la variable. À moins que a représente une propriété d'un objet ou quelque chose (ou une clé dans une liste, comme vous l'avez fait dans votre propre exemple), vous ne serez pas en mesure d'avoir une relation entre le premier et le dernier a.

+0

+1 pour utiliser @property bien que la référence devienne l'appel de la fonction et non l'int. – Unode

1

Il n'y a pas un moyen en Python, non seulement parce que les nombres sont immuables, mais aussi parce que vous n'avez pas de pointeurs. Envelopper la valeur dans une liste simule que vous avez des pointeurs, donc c'est ce que vous pouvez faire de mieux.

0

Vous pouvez essayer de créer votre propre classe de pointeurs et votre propre objet de stockage de pointeur pour émuler la pile interne du système.

+0

Je pense que l'émulation des pointeurs en utilisant le list-wrap est plus facile – Claudiu

+0

Vous avez tout à fait raison si cela ne vous dérange pas d'utiliser un style de programmation inhabituel et de ne pas pouvoir faire de l'arithmétique de pointeur. –

2

Si vous avez juste besoin des valeurs actuelles pour être placées dans un tuple à la volée, vous pouvez utiliser un lambda. Vous devrez appeler c, pas seulement le retourner ou l'utiliser, mais cela peut être acceptable dans votre situation. Quelque chose comme ceci:

>>> a = 1 
>>> b = 2 
>>> c = lambda: (a, b) 
>>> c() 
(1, 2) 
>>> a = 3 
>>> c() 
(3, 2) 
1
class ByRefValue(object): 
    def __init__(self, value): 
     self.value = value 

passe autour de partout où vous voulez, se rappeler que vous devez accéder au membre value plutôt que l'objet entier.


Sinon, globals().get('a', 0) retourne la valeur de a si elle est dans l'espace de noms global (ou zéro si ce n'est pas).


Enfin:

import threading 
tls = threading.local() 

tls.a = 1 

Si vous importez tls dans chaque module où vous en avez besoin, vous aurez accès à la même valeur pour asur chaque fil. Selon la façon dont votre programme est mis en place, cela peut être acceptable, idéal ou inutile.

Questions connexes