LINUX.ORG.RU

копировать данные между объектами классов

 ,


0

1

Имеются классы.

@dataclass
class A:
    x: int
    y: str
    z: float


class B:
    x: int
    y: str
    u: str

    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)

    def __repr__(self):
        return str(self.__dict__)

Нужно написать мэпперы, которые помогут копировать данные между объектами этих классов. Представим что методов много, и банальный перебор полей не хотелось бы делать и поддерживать:

a = A(x=1, y='a', z=2.2)
b = B(x=a.x, y=a.y, u='b')

Какие паттерны тут существуют?

Словарь распаковывать или что-то еще есть?

b = B(**{k:v for k,v in a.__dict__.items() if k in ['x', 'y']}, u='b')

А можно организовать волшебный метод, который может организовать присвоение:

b=a
или
b=B(a)
?



Последнее исправление: scientistpython (всего исправлений: 3)

Представим что методов много

где много?

b = B(x=a.x, y=a.y, u=‘b’)

А что не нравится то?

можно организовать волшебный метод, который может организовать присвоение:

Можно. Разрешаю. Но, скорее всего, ненужно.

qaqa ★★
()
Последнее исправление: qaqa (всего исправлений: 1)

b = B(**{k:v for k,v in a.dict.items() if k in [‘x’, ‘y’]}, u=‘b’)

items = a.__dict__.copy()
items['u'] = 'b'
b = B(**items)

b=B(a)

Конечно можно

class B:
    def __init__(self, a):
        items = a.__dict__.copy()
        items['u'] = 'b'
        for k, v in items.items():
            setattr(self, k, v)
Aswed ★★★★★
()
Последнее исправление: Aswed (всего исправлений: 1)
@dataclass 
class X: 
    x: int 
    y: int 


@dataclass 
class Y: 
    x: 1 
    y: 2 
    z: 3 
    @classmethod 
    def from_x(cls, x, **kwargs): 
        x = x.__dict__.copy() 
        x.update(**kwargs) 
        return cls(**x) 


x = X(x=1, y=2)
Y.from_x(x, z=2) # Y(x=1, y=3, z=2)
Aswed ★★★★★
()
Ответ на: комментарий от qaqa

но, cls.__annotations__.keys() позволит не париться и не набирать поля классов + самое главное, не редактировать from_x при изменении полей )))

scientistpython
() автор топика
Последнее исправление: scientistpython (всего исправлений: 1)
Ответ на: комментарий от scientistpython

Это все да.

_dict = dataclasses.asdict(x)
_dict['u'] = u
cls(**_dict)

Но если не надо менять данные x, я бы лучше сделал

@dataclasses.dataclass(frozen=True)
class X:

и передавал бы x в конструктор Y без перекладывания.

qaqa ★★
()
Ответ на: комментарий от qaqa

Почему-то после применения декоратора к sqlalchemy классу - последний перестает работать - выборки пустые, ошибок нет

from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

@dataclass
class A:
    id = Column(Integer, primary_key=True)
    x = Column(String, nullable=False)
    ...

убираешь датакласс, набиваешь __init__, __repr__ - все пашет

scientistpython
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.