2017-04-25 70 views
0

我有一個Event對象,可以有很多屬性,其中一些是單一值,其中一些是值列表。如果一個對象的屬性可能是一個列表或一個單值,應該如何訪問它?

class Event(object): 
    pass 

event = Object() 
event.b = [10, 20, 30] 
event.c = 15 

我試圖訪問所有這些,我結束了很多單一值的屬性,在某種程度上有點像這樣:

print(Variable(event = event, name = "b[0]") 
print(Variable(event = event, name = "b[1]") 
print(Variable(event = event, name = "b[2]") 
print(Variable(event = event, name = "c" ) 

爲了做到這一點,我已經創建了一個Variable類:

class Variable(object): 

    def __init__(
     self, 
     name = None, 
     value = None, 
     event = None, 
     ): 

     self._name = name 
     self._value = value 
     self._event = event 

     if self._value is None: 
      # add magic here 
      self._value = getattr(self._event, self._name) 

    def name(
     self 
     ): 

     return self._name 

    def value(
     self 
     ): 

     return self._value 

我想這個變量類明白,像「[2]」在指定的名稱結束意味着屬性是一個列表並且應該訪問其索引2的元素並將其設置爲變量實例的單個值。什麼是這樣做的好方法?

請注意,這是我正在做的簡化版本 - 事實上,我正在處理數百萬個事件和數千個屬性,並且我正在儘量減少必須編寫的代碼量(並且隨後更改)通過使變量類變聰明。

+1

你可以用'isinstance(var,list)'來做一些測試,以確定它是一個列表還是'getattr(var,'__iter __')'來確定對象是否可迭代。 – danielunderwood

+0

@danielunderwood感謝您的評論。看,它需要知道要訪問的迭代屬性的哪個元素,所以它必須能夠解釋已經給出的名稱(例如'「b [2]」'),我不確定是否有一種優雅的方式做這件事。 – BlandCorporation

回答

1

我不知道一個優雅的方式來做到這一點,但你可以使用一個事實,即正常的變量不應該有括號索引分離,然後寫,基本上與檢查支架包裝getattr功能:

# Get a variable, index tuple if the name contains an index 
def pair_from_name(name): 
    if '[' in name: 
     parts = name.split('[') 
     var = parts[0] 
     index = int(parts[-1].split(']')[0]) 
     return var, index 
    else: 
     return None 

# Basically getattr, but will process indices 
def get_var(name, obj): 
    pair = index_from_name(name) 
    if pair: 
     name, index = pair 
     iterable = getattr(obj, name) 
     return iterable[index] 
    else: 
     return getattr(obj, name) 

這並不是真正意義上的處理極端名稱案件或錯誤,但它會希望把你放在正確的軌道。

+0

感謝您的解決方案。是的,這在概念上是有道理的。 – BlandCorporation

相關問題