我正在尝试使用吸引人模块创建模型类。在我的脚本中,CollectionModel类是在User类中继承的。因此,从逻辑上讲,CollectionModel中的所有属性都应该在User中可用。但是,在尝试从字典中创建用户的新实例时(使用attrs是可能的),这表明CollectionModel的属性不存在于User中。
我的剧本:
from bson import ObjectId
from attrs import asdict, define, field, validators, Factory
import time
@define
class CollectionModel:
""" Base Class For All Collection Schema"""
_id : str = field(converter=str, default=Factory(ObjectId))
_timestamp : float = field(default=Factory(time.time))
def get_dict(self):
return asdict(self)
def update(self):
self._timestamp = time.time()
@define
class User(CollectionModel):
username : str = field(factory = str, validator=validators.instance_of(str))
userType : str = field(factory = str, validator=validators.instance_of(str))
password : str = field(factory = str, validator=validators.instance_of(str))
user_object = User()
new_user_object = User(**asdict(user_object))在这里,我试图从user_object创建一个新的用户对象。它显示了以下错误。
TypeError: User.__init__() got an unexpected keyword argument '_id'我猜想父类一开始并不是初始化的。因此,我尝试用super()函数启动它,并且根据attrs文档,它应该用__attrs_pre_init__来完成。从文件中:
__attrs_pre_init__存在的唯一原因是为了给用户调用super().__init__()的机会,因为一些基于子类的API需要这样做。
所以修改后的子类会变成这样。
@define
class User(CollectionModel):
username : str = field(factory = str, validator=validators.instance_of(str))
userType : str = field(factory = str, validator=validators.instance_of(str))
password : str = field(factory = str, validator=validators.instance_of(str))
def __attrs_pre_init__(self):
super().__init__()但问题仍然存在。我是不是做错了?还是仅仅是attrs模块的一个bug?
发布于 2022-02-17 20:58:56
我解决了这个问题,有两个问题。第一个在python中,在属性名使其为私有属性之前下划线。因此,在从字典中创建新实例时,_id是一个意外的键。
第二个问题是,在使用_id时,我确实需要一个MongoDB字段。在MongoDB文档中,保留_id作为主键使用。
现在,第一个问题可以通过将_id替换为id_来解决(是的,在对面下划线,因为id实际上是python中变量名的糟糕的选择 )。
对于第二个问题,我已经搜索了很多,以便为id_字段创建一个别名。但是,在使用attrs模块时,这并不简单。因此,我对get_dict()方法进行了修改,以便在将数据放入MongoDB集合之前获得一个完美的字典。
下面是修改后的CollectionModel类和User类:
@define
class CollectionModel:
""" Base Class For All Collection Schema"""
id_: ObjectId = field(default=Factory(ObjectId))
timestamp : float = field(default=Factory(time.time))
def get_dict(self):
d = asdict(self)
d["_id"] = d["id_"]
del d["id_"]
return d
def update(self):
self.timestamp = time.time()
@define
class User(CollectionModel):
username : str = field(factory = str, validator=validators.instance_of(str))
userType : str = field(factory = str, validator=validators.instance_of(str))
password : str = field(factory = str, validator=validators.instance_of(str))现在打印一个实例:
user_object = User()
print(user_object.get_dict())输出:
{'timestamp': 1645131182.421929, 'username': '', 'userType': '', 'password': '', '_id': ObjectId('620eb5ae10f27b87de5be3a9')}https://stackoverflow.com/questions/71145126
复制相似问题