1

我正在编写一个“环境”,其中每个变量都由一个值和一个描述组成:

class my_var:
   def __init__(self, value, description):
      self.value = value
      self.description = description

创建变量并将其放入字典中:

my_dict["foo"] = my_var(0.5, "A foo var")

这很酷,但 99% 的变量操作都是使用“值”成员。所以我必须这样写:

print my_dict["foo"].value + 15  # Prints 15.5

或者

my_dict["foo"].value = 17

我希望对象 my_dict["foo"] 上的所有操作都可以默认为“value”成员。换句话说,我想写:

print my_dict["foo"] + 15     # Prints 5.5

和类似的东西。

我发现的唯一方法是重新实现所有下划线成员(eq、add、str 等),但我觉得这是错误的方式。有没有我可以使用的神奇方法?

一种解决方法是拥有更多字典,如下所示:

my_dict_value["foo"] = 0.5
my_dict_description["foo"] = "A foo var"

但我不喜欢这个解决方案。你有什么建议吗?

4

4 回答 4

3

两个一般说明。

  1. 请使用大写的类名。

  2. 请(除非使用 Python 3.0)子类对象。 class My_Var(object):, 例如。

现在回答你的问题。

假设你这样做

x= My_Var(0.5, "A foo var")

python如何区分x复合对象和x的值(x.value)?

你想要以下行为吗?

  • 有时x表示整个复合对象。

  • 有时x意味着x.value

你如何区分这两者?你将如何告诉 Python 你的意思?

于 2009-04-10T12:59:31.350 回答
2

您可以通过在http://docs.python.org/reference/datamodel.html的“模拟数字类型”部分中实现运算符来创建一个主要行为类似于“值”但具有附加属性“描述”的对象

class Fooness(object):
    def __init__(self,val, description):
        self._val = val
        self.description = description

    def __add__(self,other):
        return self._val + other

    def __sub__(self,other):
        return self._val - other

    def __mul__(self,other):
        return self._val * other

    # etc

    def __str__(self):
        return str(self._val)


f = Fooness(10,"my f'd up fooness")
b = f + 10
print 'b=',b
d = f - 7
print 'd=',d

print 'f.description=',f.description

产生:

b= 20
d= 3
f.description= my f'd up fooness
于 2009-04-10T13:03:45.927 回答
2

我个人只会使用两本字典,一本用于值,一本用于描述。你对魔法行为的渴望不是很 Pythonic。

话虽如此,您可以实现自己的 dict 类:

class DescDict(dict):
    def __init__(self, *args, **kwargs):
        self.descs = {}
        dict.__init__(self)

    def __getitem__(self, name):
        return dict.__getitem__(self, name)

    def __setitem__(self, name, tup):
        value, description = tup
        self.descs[name] = description
        dict.__setitem__(self, name, value)

    def get_desc(self, name):
        return self.descs[name]

您将按如下方式使用此类:

my_dict = DescDict()
my_dict["foo"] = (0.5, "A foo var")  # just use a tuple if you only have 2 vals
print my_dict["foo"] + 15            # prints 15.5
print my_dict.get_desc("foo")        # prints 'A foo var'

如果您决定走魔术行为路线,那么这应该是一个很好的起点。

于 2009-04-10T13:06:11.600 回答
1

我认为你必须做这么多工作来制作一个花哨的捷径这一事实表明你正在违背常规。你在做什么违反了 LSP;这是违反直觉的。

my_dict[k] = v;
print my_dict[k] == v # should be True

即使是两个单独的字典也比改变字典的含义更可取。

于 2009-04-10T12:58:38.637 回答