pythonpython-3.xdictionarycastingsetattribute

Set attribute of class from Dict with cast


I'm trying to parse a Dict of [str,str] with key value pair into a object (class). The first contains the name of attributes and the second the value.

ex: [('CLIENT_ID','123456'), ('AUTO_COMMIT', 'False'), ('BROKER_URL', 'http://foo.bar')]

The code to parse is the next:

class KafkaSettings():
    BROKER_URL: str = None
    CLIENT_ID: str = None
    AUTO_COMMIT: bool = False

    def __init__(self, d: Dict[str, str]):
        if d is not None:
            for key, value in d.items():
                attr = self.__getattribute__(key)
                casted_value = cast(attr, value)
                self.__setattr__(key, casted_value)

The parser works but the type of the value is altered. For example, AUTO_COMMIT attr as type bool but with setattr the type changed into str. The cast of the value into the good type not work. I don't know the Python language.

How to resolve this problem ?

Thanks


Solution

  • You can solve this using below code,

    from typing import Dict
    
    
    class KafkaSettings():
        BROKER_URL: str = None
        CLIENT_ID: str = None
        AUTO_COMMIT: bool = False
    
        def __init__(self, d: Dict[str, str]):
            if d is not None:
                for key, value in d.items():
                    attr = self.__getattribute__(key)
                    
                    # change as follows
                    if key == "AUTO_COMMIT":
                        value = bool(value)
    
                    self.__setattr__(key, value)
    

    You can solve this issue by checking the key and if it is equal to AUTO_COMMIT then you can cast the string value to the bool value by using bool() method.

    But note that this is a specific solution for your code. So it is better to add the values with their actual type (as you needed) when making the dictionary. Then you do not need any casting.

    For an example, In this case, you can use this,

    [('CLIENT_ID','123456'), ('AUTO_COMMIT', False), ('BROKER_URL', 'http://foo.bar')]

    (store False as boolean instead of string)

    instead of this,

    [('CLIENT_ID','123456'), ('AUTO_COMMIT', 'False'), ('BROKER_URL', 'http://foo.bar')]