考虑以下课程:
class Token:
def __init__(self):
self.d_dict = {}
def __setattr__(self, s_name, value):
self.d_dict[s_name] = value
def __getattr__(self, s_name):
if s_name in self.d_dict.keys():
return self.d_dict[s_name]
else:
raise AttributeError('No attribute {0} found !'.format(s_name))
在我的代码中Token有一些其他函数(比如get_all()返回d_dict,has(s_name)告诉我我的令牌是否有特定的属性)。
无论如何,我认为他们的计划存在缺陷,因为它不起作用:当我创建一个新实例时,python尝试调用__setattr__('d_dict', '{}')
。
我怎样才能实现类似的行为(可能以更加pythonic的方式?)而不必编写类似Token.set(name,value)和get(name)的东西,我想设置或获取令牌的属性
关于设计缺陷和/或愚蠢的批评欢迎:)
谢谢!
答案 0 :(得分:3)
你需要特殊情况d_dict。
虽然当然,在上面的代码中,你所做的就是复制任何对象已经用__dict__
做的事情,所以这是毫无意义的。如果您打算在特殊情况下使用某些属性并对其进行实际使用方法,我是否正确猜测?
在这种情况下,您可以使用属性。
class C(object):
def __init__(self):
self._x = None
@property
def x(self):
"""I'm the 'x' property."""
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
答案 1 :(得分:3)
__dict__
的特殊外壳是这样的:
def __init__(self):
self.__dict__['d_dict'] = {}
没有必要使用新式的类。
答案 2 :(得分:2)
问题似乎是在__init__方法中评估您的代码时。 你可以定义__new__方法并在那里初始化d_dict变量而不是__init__。 这有点hackish但它的确有效,请记住,虽然几个月后它会被评论为完全神奇。
>>> class Foo(object):
... def __new__(cls, *args):
... my_cls = super(Foo, cls).__new__(cls, *args)
... my_cls.d_dict = {}
... return my_cls
>>> f = Foo()
>>> id(f.d_dict)
3077948796L
>>> d = Foo()
>>> id(d.d_dict)
3078142804L
解释为什么我认为这样的hackish:调用__new__返回 class 的新实例,然后 d_dict 初始化中有 static ,但每次类“创建”时,它都会使用新的字典实例进行初始化,因此一切都可以根据需要运行。
答案 3 :(得分:1)
解决方案,不是非常pythonic但有效。正如Lennart Regebro指出的那样,你必须为d_dict使用特殊情况。
class Token(object):
def __init__(self):
super(Token,self).__setattr__('d_dict', {})
def __getattr__(self,name):
return self.a[name]
def __setattr__(self,name,value):
self.a[name] = value
您需要使用新的样式类。
答案 4 :(得分:1)
值得记住的是,__getattr__
仅在对象中不存在属性时被调用,而__setattr__
始终被调用。
答案 5 :(得分:0)
如果你解释它的目的,我想我们可以对你班级的整体设计说些什么。例如,
# This is a class that serves as a dictionary but also has user-defined methods
class mydict(dict): pass
# This is a class that allows setting x.attr = value or getting x.attr:
class mysetget: pass
# This is a class that allows setting x.attr = value or getting x.attr:
class mygetsethas:
def has(self, key):
return key in self.__dict__
x = mygetsethas()
x.a = 5
print(x.has('a'), x.a)
我认为最后一堂课最接近你的意思,我也喜欢用语法练习并从中获得很多乐趣,但不幸的是,这不是一件好事。为什么不建议使用对象属性重新实现字典的原因:您不能使用x.3
,与x.has()
冲突,您必须在has('a')
中添加引号等等。