2016-03-27 1 views
0

Ich weiß Python funktioniert nicht mit Referenzen, im Gegensatz zu Perl und anderen, aber ist es möglich, eine einfache Variable, deren Werte verknüpft sind, da sie die gleiche Speicheradresse verweisen? Ich weiß, dass flache Kopien von Listen und Wörterbüchern Werte enthalten, die auf dieselbe Adresse verweisen.Zeigen Sie zwei Variablen auf den gleichen Wert in Python

>>> foo = 1 
>>> bar = foo 
>>> bar = 0 
>>> foo 
1 
>>> foo = [1,2] 
>>> bar = foo 
>>> bar[1] = 0 
>>> foo 
[0,2] 

Cf. in Perl

$ref = 1 
$foo = \$ref 
$bar = $foo 
print $$bar //gives 1 
$$foo = 0 
print $$bar //gives 0 

Der Grund dafür ist, dass ich bin gespannt, wie könnte es in Python getan/gehackt werden. Um ein konkretes Beispiel zu geben, hätte ich gern einer Klasse zwei "synonyme" Attribute gegeben. Ich nehme an, dass man so (ungetestet, sorry, wenn falsch) durch den zweiten Wert Maskieren ein shenanigan abziehen könnte:

class fake: 
    def __init__(self,template): 
     self.ref = template # keep alive 
     self.__dict___ = template.__dict__ 
     self.__class___ = template.__class__ 
    def __getitem__(self): 
     return self.ref.__getitem__ 
    def __setitem__(self,value): 
     self.ref.__setitem__(value) 

Aber das ist nicht ganz im Geist, was ich war neugierig, aber wenn ein Hack ist der einzige Weg, ich werde dafür gehen und würde gerne den besten Weg kennen.

+0

In Python Sie den Wert in einem Objekt speichern würde, die Sie verweisen können. Zum Beispiel könnten Sie es in eine Liste als das einzige Element, z.B. '[x]', dann verwenden Sie Verweise auf die Liste. Oder Sie könnten es in ein 'dict' setzen oder eine' Klasse' dafür erstellen. –

Antwort

0

Warum nicht einfach eine @property Funktion erstellen, die den zweiten Namen hat, sondern gibt den ersten Wert?

class C: 
    def __init__(self): 
     self.attr1 = 12345 

    @property 
    def synonym(self): 
     return self.attr1 

    @synonym.setter 
    def synonym(self, value): 
     self.attr1 = value 

Dies würde lassen Verweise auf synonym durch attr1 weitergegeben werden.

+0

Warum wurde diese Antwort abgelehnt? Ich nehme an, dass etwas nicht stimmt, aber ich kenne den @property-Dekorateur nicht allzu gut. –

+0

Ich endete mit dieser Lösung. Danke –

1

Sie können immutable Objekte nicht ändern. Sie können die Referenz nur neu zuweisen.

foo = bar = 1 
bar = 0 

Hier hat man nicht zerstören 1 im Speicher, ist es das, was Unveränderlichkeit über, sie bar Punkt 0 gerade neu zuweisen.

foo = bar = [1,2] 
bar[1] = 100 

Hier ändern Sie das referenzierte Objekt im Speicher.

>>> b = 1 
>>> id(b) 
15216984 
>>> b = 2 
>>> id(b) 
15216960 # reference points to another object 
>>> a = [1,2] 
>>> id(a) 
139917071841904 
>>> a[0] = 100 
>>> id(a) 
139917071841904 # object is the same, therefore all references pointed to it will show changes 
-1

Es gibt eine Möglichkeit, es mit Deepcopy zu "hacken".

from copy import deepcopy 
foo = [1,2] 
bar = deepcopy(foo) 
bar[1] = 0 
print bar, foo 

prüfen here zur Erklärung

+0

Keine Notwendigkeit für tiefe Kopie hier, sie werden immer noch auf die gleiche Liste verweisen – Fredrik