关于python:我需要定义__setattr__来分配没有属性的字段,但是对于定义了属性的字段使用setter / getter函数

I need to define __setattr__ for assignment of fields without properties, but use the setter/getter functions for fields with a property defined

定义__setattr__将覆盖我在类中定义的所有setter方法/属性。如果字段存在属性,我希望在属性中使用定义的setter方法,否则使用self.__dict__[name] = value

救命!我找到了一个使用__setitem__的解决方案,但这对我不起作用。

python类中的属性存储在哪里?如何访问它们?

如何定义__setattr__,以便它使用定义了setter方法的字段的属性?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class test(object):

def _get_gx(self):
    print"get!"
    return self.__dict__['gx']

def _set_gx(self, gx):
    print"set!"
    self.__dict__['gx'] = gx
    gx = property(_get_gx, _set_gx)

def __setattr__(self, name, value):
    self.__dict__[name] = value

def __init__(self):
    pass

也,

为什么是"得到!"我印了两次,

1
2
3
4
5
6
7
8
9
x = test()
x.gx = 4
x.gx

prints:

  "gets!"
  "gets!"
   4


您需要重写您的__setattr__函数。根据文档,新样式类应该使用baseclass.__setattr__(self, attr, value),而不是self.__dict__[attr] = value。前者将查找任何描述符,而后者将直接分配给dict。

所以把你的方法改写为

1
2
def __setattr__(self, name, value):
    object.__setattr__(self, name, value)

1
2
def __setattr__(self, name, value):
    super(Test, self).__setattr__(name, value)

你会没事的。代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Test(object):
    @property
    def gx(self):
        print"getting gx"
        return self.__dict__['gx']

    @gx.setter
    def gx(self, value):
        print"setting gx"
        self.__dict__['gx'] = value

    def __setattr__(self, attr, value):
        print"using setattr"            
        object.__setattr__(self, attr, value)

t = Test()
t.gx = 4
t.dummy = 5
print t.gx
print t.dummy

print dir(Test)

输出

1
2
3
4
5
6
7
using setattr
setting gx
getting gx
using setattr
4
5
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'gx']

我不知道你的版本为什么要打两次电话给getter。这一个没有。而且,要回答关于描述符在哪里的问题,您可以很明显地将其视为类dict中的最后一个条目。

值得注意的是,您不需要__setattr__来做您在示例中想要做的事情。无论foo.__dict__中是否有条目,python都会将赋值foo.bar = x写入foo.__dict__['bar'] = x__setattr__用于转换值或记录分配或类似的情况。