以dict python django的形式访问类属性

时间:2016-05-23 18:17:46

标签: python class dictionary eval python-internals

我是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"

但是在这里,它会抛出这个错误。 TypeError:locals必须是映射

如果我尝试传递 context_obj .__ dict __ ,那么它只会实例化 self.order和self.availability,因为它们在 init

中提到

我希望在没有初始化的情况下实例化所有这些属性,因为它不会使用我的用例。 我想只在eval()需要时调用每个属性。

让我知道是否可行或有办法实现。 在此先感谢您的帮助。我将不胜感激任何帮助。

2 个答案:

答案 0 :(得分:1)

问题是eval期待映射。映射是dict的抽象父类,它具有特定的接口。制作自己的Mapping的最简单方法是使用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())

答案 1 :(得分:0)

这是解决方案。

我在课堂上添加了这个。现在eval查找密钥并访问相应的属性。

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