【问题标题】:Access class properties in the form of dict python django以dict python django的形式访问类属性
【发布时间】:2016-05-23 18:17:46
【问题描述】:

我是 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 must be a mapping

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

中被提及

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

让我知道是否有可能或有办法做到这一点。 提前感谢您的帮助。我将不胜感激。

【问题讨论】:

  • 这听起来不是个好主意。为什么需要将折扣函数存储为字符串?
  • @DanielRoseman eval 以字符串形式占用第一个参数。所以,这里的 discount_function 是一个规则,它根据第三个参数中传递的 dict 进行评估。
  • 我不是这个意思。你为什么要使用 eval 呢?避免它几乎总是更好。
  • @DanielRoseman 另一种方法是什么?请告诉我如何解决它
  • 我正在尝试使用它来评估将由用户输入的输入表达式。所以我想为用户提供多个选项来定义该规则。有没有更好的方法?

标签: python class dictionary eval python-internals


【解决方案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())

【讨论】:

  • 非常感谢您将我引向正确的方向。
【解决方案2】:

这就是解决方案。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-13
    • 2020-08-09
    • 1970-01-01
    • 1970-01-01
    • 2023-01-10
    • 2016-03-13
    • 1970-01-01
    • 2019-04-02
    相关资源
    最近更新 更多