• Jobs
  • About Us
  • professionals
    • Home
    • Jobs
    • Courses and challenges
  • business
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

285
Views
Problema al iniciar la base con la clase secundaria mientras se trabaja con el módulo python-attrs

Estoy tratando de crear una clase de modelo con el módulo attrs . En mi script, la clase CollectionModel se hereda en la clase User . Entonces, lógicamente, todos los atributos en CollectionModel deberían estar disponibles en User . Pero al intentar crear una nueva instancia de Usuario desde el diccionario (es posible con attrs), muestra que los atributos de CollectionModel no están presentes en el User

Mi guión:

 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))

Aquí, estoy tratando de crear un nuevo objeto Usuario desde el user_object . Muestra el siguiente error.

 TypeError: User.__init__() got an unexpected keyword argument '_id'

Supuse que la clase principal no se inicia al principio. Así que traté de iniciarlo con la función super() y, de acuerdo con la documentación de attrs, debería hacerse con __attrs_pre_init__ . De la documentación:

La única razón de la existencia de __attrs_pre_init__ es dar a los usuarios la oportunidad de llamar a super().__init__() , porque algunas API basadas en subclases lo requieren.

Entonces la clase secundaria modificada se vuelve así.

 @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__()

Pero el problema aún permanece. ¿Estoy haciendo el OOP de forma incorrecta? ¿O es solo un error del módulo attrs ?

about 3 years ago · Santiago Trujillo
1 answers
Answer question

0

He resuelto ese problema y había dos problemas. El primero, en python, subrayado antes de un nombre de atributo lo convierte en un atributo privado. Entonces, al crear una nueva instancia desde el diccionario _id es una clave inesperada.

El segundo problema es que, de hecho, necesito un campo _id ya que estoy trabajando con MongoDB. En MongoDB, el documento _id está reservado para usar como clave principal.

Ahora, el primer problema se puede resolver reemplazando _id por id_ (sí, guión bajo en el lado opuesto ya que id es literalmente una mala elección para un nombre de variable en python).

Para el segundo problema, he buscado mucho para crear un alias para el campo id_ . Pero no es simplemente fácil trabajar con el módulo attrs . Así que modifiqué el método get_dict() para obtener un diccionario perfecto antes de incluir mis datos en la colección de MongoDB.

Aquí está la clase CollectionModel modificada y la clase 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))

Ahora imprimiendo una instancia:

 user_object = User() print(user_object.get_dict())

Producción:

 {'timestamp': 1645131182.421929, 'username': '', 'userType': '', 'password': '', '_id': ObjectId('620eb5ae10f27b87de5be3a9')}
about 3 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recommend me some offers
I have an error