2016-05-23 76 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)