2016-07-26 17 views
-2
class Myclass(object): 
    def get_val(self): 
     return 100 

my_obj = MyClass() 
data = { 
    'key_1': my_obj, 
    ... # other fields 
} 

Später muss ich das Objekt ändern, um es Wert ist, konnte ich nur das Wörterbuch wie diese iterieren, vielleicht rekursiv:Python: Ist es möglich, dass sich ein Objekt in etwas anderes verwandelt?

for key in data: 
    if type(data[key]) is MyClass: 
     data[key] = data[key].get_val() 

Aber ist es möglich, sich diese über my_obj zu tun?

Ich denke nicht, denn in Python können Sie Zeiger nicht manipulieren, wie Sie in c tun können, aber gibt es bessere Möglichkeiten?

+0

Das Objekt kann das nicht selbst tun, obwohl eine Unterklasse des Dictionary es außer Kraft setzen kann, wie es die 'data [key]' - Suche recht einfach handhabt. –

+0

Wie bereits erwähnt, gibt es eine Vielzahl von magischen Methoden, die Sie in Ihrer Klasse überschreiben können, um einen bestimmten Wert zurückzugeben. –

+2

Warum müssen Sie das überhaupt machen? –

Antwort

0

Objekte können keine/alle Referenzen von sich selbst durch etwas anderes ersetzen. Zeitraum.

Allerdings, wenn Sie einen Wörterbuch der Zeiger Objekte haben müssen (eine Form von .get() Methode hat die aktuellen Daten zurück), dann überschreibt nur die __getitem__ Methode einer dict Unterklasse Sie in der entsprechenden Logik hinzufügen lassen, wenn das Abrufen von Daten aus das Wörterbuch:

class MyDict(dict): 
    def __getitem__(self,item): 
     value = dict.__getitem__(self,item) #may raise error 
     if isinstance(value, Myclass): 
      return value.get_val() 
     else: 
      return value 

my_obj = Myclass() 

data = MyDict({ 
    'key_1': my_obj, 
    # other fields 
}) 

assert data["key_1"] == 100 

Obwohl beachten, dass dies nur Änderungen, die ein Verfahren zum Nachschlagen, mit .items() oder .get() usw. nicht das modifizierte __getitem__ so eine vollständigere Umsetzung nutzen könnte mit collections.MutableMapping erfolgen:

import collections 

class MyDict(collections.MutableMapping): 
    __slots__ = ["raw_dict"] 
    def __init__(self,*args,**kw): 
     self.raw_dict = dict(*args,**kw) 

    def __getitem__(self,item): 
     value = self.raw_dict[item] 
     if isinstance(value, Myclass): 
      return value.get_val() 
     return value 

    def __setitem__(self,item, value): 
     self.raw_dict[item] = value 
    def __delitem__(self, item): 
     del self.raw_dict[item] 
    def __len__(self): 
     return len(self.raw_dict) 
    def __iter__(self): 
     return iter(self.raw_dict) 

Dann werden alle anderen Methoden wie .get und .pop und .items etc. sind alle von den hier definierten erstellt. Und die ursprünglichen Zeigerobjekte sind immer noch über data.raw_dict["key_1"] zugänglich, so dass nichts verborgen bleibt.