2014-09-25 89 views
0

我想將一個對象表示爲一個字符串,以便它既可以作爲字典鍵也可以作爲對象本身來訪問。即Python,將非字符串對象表示爲字符串?

class test(object): 
def __init__(self, name, number_array): 
    self.name = name 
    self.number_array = number_array 
    self.graph= barChart(number_array) 

sample_obj = test('test_object', [(x1,y1), (x2,y2)etc.]) 

但讓{sample_obj: another_object}看起來像{'test_object': another_object}

,同時還使得這樣的可能:

for key, val in sample_dict.items(): print(key.name, key.graph) 

還有:

>>> sample_dict['test_object'] 
another_object 
+0

目前沒有辦法提供這樣的關鍵別名,所以'dict'會將''test_object''視爲'some_object'的別名。參見[PEP-455](http://legacy.python.org/dev/peps/pep-0455/)提供了一個可以添加一個新類型的'dict'的提案。 – chepner 2014-09-25 13:22:25

+0

是否可以更改訪問字典中對象的默認方法?因此,而不是說,D ['foo']檢查t .__ eq __('foo')是否檢查t.name .__ eq __('foo')?可以覆蓋__getitem__嗎? – user3467349 2014-09-25 13:38:17

+1

Chepner錯了。有可能做你想做的事。 – haael 2014-09-25 13:54:26

回答

1

你必須定義eq th在返回用字符串即比較時正:

def __eq__(self, other): 
    if self.name == other: 
     return True 
    ... continue with comparison ... 

您還必須定義哈希返回相同的哈希值作爲比較字符串:

def __hash__(self): 
    return hash(self.name) 

UPDATE:下面的代碼究竟是幹什麼的筆者想:

class test(object): 
    def __init__(self, name, number_array): 
     self.name = name 
     self.number_array = number_array 
     #self.graph= barChart(number_array) 

    def __eq__(self, other): 
     try: 
      return (self.name == other.name) and (self.number_array == other.number_array) 
     except AttributeError: 
      return self.name == other 

    def __hash__(self): 
     return hash(self.name) 

sample_obj = test('test_object', [(0, 1), (2, 3)]) 

dict1 = {sample_obj: "Hurray"} 
print("dict1[sample_obj]", dict1[sample_obj]) 
print("dict1['test_object']", dict1['test_object']) 

dict2 = {'test_object': "Yippie"} 
print("dict2[sample_obj]", dict2[sample_obj]) 
print("dict2['test_object']", dict2['test_object']) 
+0

這將要求'str .__ eq__',而不是'test .__ eq__',被覆蓋。 – chepner 2014-09-25 13:23:10

+0

沒關係。默認的str .__ eq__將返回NotImplemented,那麼Python會嘗試使用字符串作爲第二個參數的.__ eq__。 – haael 2014-09-25 13:35:13

1

使用類作爲字典鍵,實現__hash____eq__。爲了改變在打印詞典將其如何出現,實現__repr__

class Test(object): 

    def __init__(self, name, number_array): 
     self.name = name 
     self.number_array = number_array 
     self.graph = barChart(number_array) 

    def __eq__(self, other): 
     return self.name == other.name and self.number_array == other.number_array 

    def __hash__(self): 
     return hash(self.name)^hash(self.number_array) 

    def __repr__(self): 
     return "test_object" 

在使用中:

>>> t = Test("foo", (1, 2, 3)) 
>>> d = {t: [1, 2, 3]} 
>>> t 
test_object 
>>> d 
{test_object: [1, 2, 3]} 
>>> d[t] 
[1, 2, 3] 

注意,這意味着,無論是namenumber_array屬性必須是可哈希 - 我有使用一個字符串和一個元組來確保這一點。另外,如果__repr__更接近於代表實際的對象,則更好。

def __repr__(self): 
    return "Test({0.name!r}, {0.number_array!r})".format(self) 
+0

這不會解決第二部分(使用字符串'test_object'作爲訪問映射到對象的元素的鍵),但我不認爲這樣的事情是可能的,至少不使用提議的'TransformDict'類。 – chepner 2014-09-25 13:18:16

+0

我得到它使用def __repr __(self):return str(self.name)和def __eq __(self,other):return self.name == other - 但我不確定這是不錯的編程實踐,因爲現在不是隻有d ['foo']會工作,但t =='foo'現在也會返回true - 這看起來很危險。 – user3467349 2014-09-25 13:24:27

+0

@ user3467349是的,我不確定這是個好主意。此外,它意味着所有'Test'實例在功能上都是相同的,即使它們包含不同的數據。你目前的方法背後的理由是什麼? – jonrsharpe 2014-09-25 13:26:25