jeudi 27 avril 2023

How to add methods dynamically to an instance of SQLModel class

I am trying to add functionality for conversion of timeseries data from one format to another based on the value type of the Element object, here, I am abstracting all that and just trying to print the type of conversion, I'd like to modify the Element class such that methods could be added dynamically based on the value type of an Element instance during the object instanciation. assuming all conversions are possible except to itself, I created a functions mapper dictionary to index search the respective function and add it using the setattr method, instead of using a mapper for functions, it seemed better to directly set the functions using types.MethodType(locals()[f"{self.value_type}_{conversion_method}"], self), in both cases, the code raises no errors but also doesn't add the methods as I wanted to, wondering where am I going wrong here.

from uuid import UUID, uuid4
from sqlmodel import Field, SQLModel


def a_to_b_function():
    print("A to B")


def a_to_c_function():
    print("A to C")


def b_to_a_function():
    print("B to A")


def b_to_c_function():
    print("B to C")


def c_to_a_function():
    print("C to A")


def c_to_b_function():
    print("C to B")


VALUE_TYPE_CONVERSION_MAPPER = {
    "A_to_B": a_to_b_function,
    "A_to_C": a_to_c_function,
    "B_to_A": b_to_a_function,
    "B_to_C": b_to_c_function,
    "C_to_A": c_to_a_function,
    "C_to_B": c_to_b_function,
}


class AllBase(SQLModel):
    id: UUID = Field(default_factory=uuid4, primary_key=True)


class Element(AllBase, table=True):
    """
    interacts with elements table
    """


    value_type: str = Field(default=None)  # A, B, C - possible values

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        all_types = [
            "A",
            "B",
            "C",
        ]
        for value_type in all_types:
            if value_type != self.value_type:
                conversion_method = f"to_{value_type}"
                setattr(
                    self,
                    conversion_method,
                    VALUE_TYPE_CONVERSION_MAPPER[
                        f"{self.value_type}_{conversion_method}"
                    ]
                    # types.MethodType(locals()[f"{self.value_type}_{conversion_method}"], self),
                )

Aucun commentaire:

Enregistrer un commentaire