访问python中的对象时返回默认成员

时间:2009-04-10 12:41:36

标签: python dynamic-data

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

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%的变量操作都带有“value”成员。所以我必须这样写:

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 个答案:

答案 0 :(得分:3)

两个一般性说明。

  1. 请使用大写字母名称。

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

  3. 现在回答你的问题。

    让我们说你做了

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

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

    您想要以下行为吗?

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

    • 有时x表示x.value

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

答案 1 :(得分: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

答案 2 :(得分:2)

我个人只会使用两个词典,一个用于值,一个用于描述。你对魔法行为的渴望并不是非常恐怖的。

话虽如此,你可以实现自己的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'

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

答案 3 :(得分:1)

我认为你必须做很多努力来制作一个奇特的捷径这一事实表明你正在反对这个问题。你在做什么违反了LSP;这是违反直觉的。

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

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