0

Given a class, how can an instance of it be created from a dictionary of fields? Here is an example to illustrate my question:

from typing import Tuple, Mapping, Any


def new_instance(of: type, with_fields: Mapping[str, Any]):
    """How to implement this?"""
    return ...


class A:
    """Example class"""

    def __init__(self, pair: Tuple[int, int]):
        self.first = pair[0]
        self.second = pair[1]

    def sum(self):
        return self.first + self.second


# Example use of new_instance
a_instance = new_instance(
    of=A,
    with_fields={'first': 1, 'second': 2}
)
Stephane Bersier
  • 710
  • 7
  • 20
  • How is the dictionary `{'first': 1, 'second': 2}` supposed to map to the tuple `[int, int]`? – Barmar Feb 24 '20 at 23:29
  • @Barmar it's not supposed to map to the tuple. I would like to bypass the constructor, and directly initialize the fields. – Stephane Bersier Feb 24 '20 at 23:31
  • It would make more sense if the class were defined as `def __init__(self, first, second)`. Then you could just use `**with_fields` when calling the class. – Barmar Feb 24 '20 at 23:31
  • @Barmar I intentionally didn't define it like that, because in general the constructor may not just directly take a list of fields. I'm looking for a solution that works even in such cases. – Stephane Bersier Feb 24 '20 at 23:32
  • https://stackoverflow.com/questions/2168964/python-creating-class-instance-without-calling-initializer – Barmar Feb 24 '20 at 23:33
  • @Barmar Thanks! Now you just need to instantiate the fields from the dictionary to have a full answer. – Stephane Bersier Feb 24 '20 at 23:35
  • Does this answer your question? [How to create a class instance without calling initializer?](https://stackoverflow.com/questions/2168964/how-to-create-a-class-instance-without-calling-initializer) – AMC Feb 25 '20 at 00:20
  • @AMC See previous comments. – Stephane Bersier Feb 25 '20 at 16:30

1 Answers1

1

See How to create a class instance without calling initializer? to bypass the initializer. Then set the attributes from the dictionary.

def new_instance(of: type, with_fields: Mapping[str, Any]):
    obj = of.__new__(of)
    for attr, value in with_fields.items():
        setattr(obj, attr, value)
    return obj
Stephane Bersier
  • 710
  • 7
  • 20
Barmar
  • 741,623
  • 53
  • 500
  • 612