2

I have a code with responsibility division:

  1. Standard classes which are getting they defenition (inherit) from a dataclasses.
  2. Dataclasses themselves.

How I can combine a default class with dataclass to get methods from class and "entity" (self definition) from a dataclass?

Currently I'm getting an error.

Code:

# data_classes.py
from dataclasses import dataclass


@dataclass(slots=True)
class User:
    tg_user_id: int


@dataclass(slots=True)
class NewUser(User):
    username: str
    gender: str
    age: int
    location: str
    comment: str
    moto_drive_style: str
    moto_type: str
    moto_hp: int
    moto_brand: str

#classes.py
import data_classes


class User(data_classes.User):
    __slots__ = ('_cursor', 'last_function', )

    def __init__(self, tg_user_id: int):
        super().__init__(tg_user_id)
        self._cursor = GLOBAL_CONNECTION.cursor()
        self.last_function = None

    def __repr__(self):
        return {'tg_user_id': self.tg_user_id}

    def _convert_profile_text(self) -> dict:
    """
    Should be executed after db insertion
    """
        # noinspection PyUnresolvedReferences
        converted_data_with_none = {
            # Don't forget to use parse_mode="HTML" if you are using links
            'Имя': f"<a href='tg://user?id={self.tg_user_id}'>{self.username}</a>",
            'Пол': self.gender,
            'Возраст': self.age,
            'Откуда': f'{self.country}, {self.city}',
            'Комментарий': self.comment,
            'Стиль вождения': self.moto_drive_style,
            'Класс мототехники': self.moto_type,
            'Лошадиные силы': self.moto_hp,
            'Марка и модель': self.moto_brand,
        }

        return {k: v for k, v in converted_data_with_none.items() if str(None) not in str(v)}

    def show_profile(self, show_to_id: int, ) -> MessageId:
        ...


class NewUser(User, data_classes.NewUser):
    def __init__(self, tg_user_id: int):
        super().__init__(tg_user_id)
    ...

Error:

    class NewUser(User, data_classes.NewUser):
TypeError: multiple bases have instance lay-out conflict
python-BaseException
salius
  • 918
  • 1
  • 14
  • 30
  • 1
    I'm pretty sure it's the same fundamental problem as e.g. with `__slots__`: https://stackoverflow.com/questions/53060607/. – Karl Knechtel Jan 11 '22 at 14:43
  • 1
    This would be a problem without `__slots__`, as you are eventually going to call `NewUser.__init__` with too few arguments. – chepner Jan 11 '22 at 14:49
  • There really is no material difference between your "standard class" and a "data class". A "dataclass" is just a *standard class* created by the `dataclasses.dataclass` class factory. There are some attributes that are added, e.g. `__dataclass_fields__`. Your problem here is your usage of `__slots__` and you would have this problem regardless of whether or not you used the `dataclasses.dataclass` class factory – juanpa.arrivillaga Jan 11 '22 at 14:51
  • To be pedantic, it is a code-generator/class factory (a class factory when you use `slots=True`) – juanpa.arrivillaga Jan 11 '22 at 14:59
  • 1
    Also, be sure to read [Notes on using `__slots__`](https://docs.python.org/3/reference/datamodel.html#notes-on-using-slots) and [Python's `super()` considered super!](https://rhettinger.wordpress.com/2011/05/26/super-considered-super/) (which has advice on using `super` in `__init__` and methods that augment type signatures in general). – chepner Jan 11 '22 at 15:09

0 Answers0