我有一个类似字典的对象,用于存储描述符:
class MyDict(object):
def __init__(self):
dict.__init__(self)
def __getitem__(self, key):
v = dict.__getitem__(self, key)
if hasattr(v, '__get__'):
return v.__get__(None, self)
return v
class MyDescriptor(object):
def __init__(self, value, attrib={}):
self.__value = value
self.attrib= attrib
def __get__(self, instance, owner):
return self.__value
def __set__(self, instance, value):
self.__value = value
我希望能够做到以下几点:
d = MyDict()
d['1'] = MyDescriptor("123", {"name": "val"})
print d['1'] # prints "123"
print d['1'].attrib["name"] # prints "val"
我的班级不起作用。你能帮我吗?
答案 0 :(得分:1)
我不确定这是否能解决您的使用案例,但就实现您所声明的结果而言,您只需删除MyDict
课程并使用普通的dict
:
d = {}
然后,在返回__str__
的{{1}}课程中添加MyDescriptor
方法,您将获得您所描述的结果。
self.__value
答案 1 :(得分:1)
您的解决方案看起来不必要地解决您的问题,除非显示更多内容。为什么不简单地这样做:
class MyObject(object):
def __init__(value, attrib=None):
self.__value = value
self.attrib {} if attrib is None else attrib
def __str__(self):
return __value
d = {}
d['1'] = MyObject("123", {"name": "val"})
print d['1'] # prints "123"
print d['1'].attrib["name"] # prints "val"
至于为什么你的代码不起作用,有一些明显的问题。
通过__dict__
的各种特殊方法调用,MyDict
似乎是dict
的子类,因此定义应为:
class MyDict(dict):
...
虽然不是不正确,但更好的做法是使用super
而不是引用
直接使用基类,因此dict.__init__(self)
将变为super(MyDict, self).__init__()
而dict.__getitem__(self, key)
变为super(MyDict, dict).__getitem__(key)
。
您对获取窗台的调用工作正常,但与方法规范不符。你应该
将其称为v.__get__(self, MyDict)
。但是,你使用它的方式实际上会使__get__
变得多余,我认为这是主要问题所在的用法。
在课程MyDescriptor
中,early binding会为attrib
提供意外结果。请参阅上面的示例,以获得更好的声明方式。
我怀疑代替描述,你真正想要的是一个看起来像字符串的对象(对于“看起来像”的某些定义),但有一个属性attrib
。为此,不需要尝试创建描述符,该描述符完全用于不同的用例。我上面的例子给出了一个类,它满足了一个“看起来像”一个字符串的对象的要求,其中“看起来像”意味着它打印一个字符串,但这里有另一个可能更像你想要的字符串:
class MyString(str):
def __init__(self, value, attrib=None):
super(MyString, self).__init__(value)
self.attrib = {} if attrib is None else attrib