2016-05-23 55 views
1

我是python/Django的新手。請幫我解決這個問題。 我想實例化這些類屬性,但我無法做到這一點。以字典形式訪問類屬性python django

這是我的課

class PricingContext(object): 
    def __init__(self, order=None, availability=False): 
     self.order = order 
     self.availability = availability 

    @property 
    def available_suites(self): 
     if self.availability: 
      availability = calculate_available_suites(self.order) 
      return availability 

    @property 
    def price_codes(self): 
     return self.order.get('price_codes') 

    @property 
    def purchased_date(self): 
     return self.order.order_items[0].get('purchased_date') 

    @property 
    def suite_type(self): 
     return self.order.order_items[0]['item_name'] 

,我試圖實例化這樣

context_obj = PricingContext(context, availability) 
eval(self.discount_function, None, context_obj) 

假設self.discount = "'PRICE_CODE' in context_obj.price_codes"

但在這裏,它拋出這個錯誤。 類型錯誤:當地人必須是一個映射

如果我試圖通過context_obj .__ dict__那麼僅實例 self.order和self.availability因爲它們在初始化提到

我希望所有這些屬性都可以在不初始化的情況下實例化,因爲它不會與我的用例一起使用。 我只想在eval()需要時調用每個屬性。

讓我知道是否有可能或有辦法做到這一點。 在此先感謝您的幫助。我將不勝感激任何幫助。

+0

這聽起來不是一個好主意。爲什麼你需要將折扣函數存儲爲字符串? –

+0

@DanielRoseman eval以字符串的形式佔用第一個參數。所以,這裏的discount_function是一個基於第三個參數傳遞的字典進行評估的規則。 – Shagun

+1

這不是我的意思。你爲什麼要使用eval?避免它幾乎總是更好。 –

回答

1

問題是eval期待映射。映射是dict的抽象父類,它具有特定的接口。使自己的映射,最簡單的方法是使用collections.Mapping,例如是小寫字母映射爲大寫字母:

import collections 
from string import ascii_lowercase 

class toUpper(collections.Mapping): 
    def __getitem__(self, key): 
     if len(key) == 1 and key in ascii_lowercase: 
      return key.upper() 
     else: 
      raise KeyError 

    def __len__(self): 
     return 26 

    def __iter__(self): 
     return ((k, k.upper()) for k in ascii_lowercase) 

所有你需要做的就是讓自己的映射,其中的鍵是變量eval所需的名稱。每個密鑰的值可以隨時計算或根據需要存儲在某個緩存中。

只是爲了好玩:

eval('"".join([c, a, p, s, l, o, c, k])', None, toUpper()) 
+0

非常感謝您讓我走向正確的方向。 – Shagun

0

這是解決方案。

我在課堂上加了這個。現在eval會查找關鍵字並訪問相應的屬性。

def __getitem__(self, key): 
     return self.__getattribute__(key)