通过_setattr赋值时,Python属性设置未赋值正确的实例属性(前导下划线)__
在工厂方法中通过通过_setattr赋值时,Python属性设置未赋值正确的实例属性(前导下划线)__,python,Python,在工厂方法中通过setattr设置实例属性时,我无法设置实例的正确属性 给定以下代码,其中数据是一个简单的dict,包含例如{“age”:“64”,…} def factory(data): obj = MyClass() for k, v in data.items(): setattr(obj, k, v) return obj class MyClass(object): def __init__(self): self
setattr
设置实例属性时,我无法设置实例的正确属性
给定以下代码,其中数据
是一个简单的dict,包含例如{“age”:“64”,…}
def factory(data):
obj = MyClass()
for k, v in data.items():
setattr(obj, k, v)
return obj
class MyClass(object):
def __init__(self):
self._age = None
# more...
@property
def age(self):
return self._age
@age.setter
def age(self, value):
some_validation(value)
self._age = value
def __setattr__(self, name, value):
object.__setattr__(self, name, value)
def __getitem__(self, item):
return self.__dict__.get(item, None)
def __getattr__(self, item):
self.__dict__[item] = None
return None
def __str__(self):
return json.dumps(self, default=lambda o: o.__dict__)
c = factory(data)
print(c)
打印创建的对象时,我始终获得以下输出:
{"_age": "64", ...}
但是我需要
{"age": "64", ...}
为什么
setattr
方法会指定前导下划线?您试图实现的一些功能会混淆,例如想要打印可读的表示形式的\uuuu dict\uuuu
,但使用私有属性作为属性。让我们从头开始,看看如何正确实现您的类
您正在尝试实现一个类,该类的属性可以作为键和属性访问。这很好,可以用更简洁的方式完成
class MyClass:
...
def __getitem__(self, item):
return self.__getattribute__(item)
def __setitem__(self, key, value):
return self.__setattr__(key, value)
当属性不存在时,您还希望返回None
。\uuuu getattr\uuuu
涵盖了这一点,它在属性不存在时被准确调用
def __getattr__(self, _):
return None
然后,您需要使用属性
向某些属性添加一些验证。这确实是正确的做法
@property
def age(self):
return self._age
@age.setter
def age(self, value):
# some validation here
self._age = value
最后,您希望能够获得实例的良好字符串表示。我们必须小心,因为我们必须添加一些我们不想打印的私有属性
我们要做的是实现一个方法keys
,以允许强制转换到dict
。此方法将仅返回非私有或非方法的属性的键
def keys(self):
return [k for k in dir(self) if not k.startswith('_') and not callable(self[k])]
def __str__(self):
return json.dumps(dict(self))
这是正确的做法
obj = MyClass()
obj.age = 3
print(obj)
# prints: {"age": 3}
…因为您的
age.setter
设置\u age
您传递给工厂的数据是什么?请提供更多代码,因为有些东西不匹配,举例来说,当你打印你的对象时,它会在它的字典上打印一个dict?@OlivierMelanç,例如{“age”:“64”,…}
@OlivierMelançon添加了\uuu str\uuu
方法和输入数据example@kindall如果我在setter中将它设置为self.age=value
,我会得到一个递归错误