Imagine I have two dataclasses:
class A:
x: int
y: int
class B:
x:int
y:int
And I have a list of class a:
a_list = [A(x=1, y=2), A(x=3,y=4), ...]
What would be an elegant way of creating a list of class B from this list (copying the properties over in each case)?
CodePudding user response:
Give B a class method that produces an instance of B given an instance of A:
class B
x: int
y: int
@classmethod
def from_A(cls, a):
return cls(a.x, a.y)
Then you can write
bs = [B.from_A(a) for a in a_list]
There's a bit of an asymmetry here: B knows details about A, but A knows nothing about B. You could reverse this and let instances of A produce instances of B:
class A:
x: int
y: int
def to_B(self):
return B(self.x, self.y)
bs = [a.to_B() for a in a_list]
Or, you could decide that neither A nor B should be "privileged" to know details about the other, instead having a third "omniscient" entity that knows how to go in one direction or the other. (This is at least symmetrical.)
def b_from_a(a):
return B(a.x, a.y)
bs = [b_from_a(a) for a in a_list]
How you decide to encapsulate the creation of a B from an A is up to you; other factors in your code may help you decide which of the three options is most reasonable.
CodePudding user response:
Assuming both are dataclasses and all of the names match up, you can pass A as keyword arguments to B's constructor using asdict.
my_b_object = B(**asdict(my_a_object))
and, of course, to apply it over a list, use a list comprehension.
b_list = [B(**asdict(a)) for a in a_list]
CodePudding user response:
Access the attributes directly and feed them into B:
b_list = [B(a.x, a.y) for a in a_list]
