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

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

后来我需要改变它的值的对象,我只能遍历字典是这样,也许递归:Python:对象是否可以改变自己到别的东西?

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

但有可能通过my_obj本身做到这一点?

我不这么认为,因为在python中你不能操纵指针,就像你可以在c中做的一样,但是有没有更好的方法?

+0

该对象本身不能这样做,尽管字典的子类可以覆盖它很容易处理'data [key]'查找的方式。 –

+0

如前所述,您可以在班级中重复使用各种魔术方法返回特定值 – 2016-07-26 07:37:50

+2

为什么您需要首先执行此操作? –

回答

0

对象不能用其他东西替换任何/所有的自身引用。期。

不过,如果你需要有指针对象的字典(有某种形式的.get()方法返回的实际数据)然后就覆盖一个dict子类的__getitem__方法从检索数据时,将让你在适当的逻辑加字典:

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 

虽然注意,这仅是改变查找一个方法,使用.items().get()等将不使用修改后的__getitem__这样一个更完整的实现可以用collections.MutableMapping来完成:

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) 

然后将所有其它的方法,如.get.pop和和.items等,均应从这里定义的那些创建。原始指针对象仍然可以通过data.raw_dict["key_1"]访问,所以没有任何东西被隐藏/丢失。

相关问题