Mehdi Zare
Mehdi Zare

Reputation: 1381

Access a function inside a python class using a variable

I'm trying to develop a class that cleans a dictionary based on field types incorporated into the class init function.

Its structure is something like this, but it doesn't work right now, as I can't figure out how to get a variable from the class instance dynamically, and how to apply the function to each variable:

class Cleaner:
    def __init__(self):
        self.int_fields = ['field_1', 'field_2']
        self.float_fields = ['field_3', 'field_4']
        self.field_types = [('int_fields', int), ('float_fields', float)]

    def get_clean_dict(self, dict):
        cleaned_dict = {}
        for field_type in self.field_types:
            for field_name, transform_func in getattr(self, field_type):
                try:
                    cleaned_dict[field_name] = transform_func(dict.get(field_name))
                except Exception:
                    cleaned_dict[field_name] = None
        return cleaned_dict

Here's how I expect it to behave:


sample_dict = {
    'field_1': 234,
    'field_2': 'Invalid',
    'field_3': 45.32345,
    'field_4': 'Invalid'
}

cleaner_inst = Cleaner()

cleaned_dict = cleaner_inst.get_clean_dict(sample_dict)

cleaned_dict = {
    'field_1': int(234),
    'field_2': None,
    'field_3': float(45.32345),
    'field_4': None
}

Upvotes: 3

Views: 82

Answers (2)

Phoenix
Phoenix

Reputation: 4274

You can use a dict to map fields name to fields transformer class,

class Cleaner:
    _field_desire_type_map = {
        'field_1': int,
        'field_2': int,
        'field_3': float,
        'field_4': float
    }

    def get_clean_dict(self, _dict):
        cleaned_dict = {}

        for _key, _value in _dict.items():
            try:
                transform_func = self._field_desire_type_map.get(_key)
                cleaned_dict[_key] = transform_func(_value)
            except Exception:
                cleaned_dict[_key] = None

        return cleaned_dict

Input:

dirty_dict = {
    'field_1': 234,
    'field_2': 'Invalid',
    'field_3': 45.32345,
    'field_4': 'Invalid'
}

Cleaner().get_clean_dict(dirty_dict) 

Output:

{'field_1': 234, 'field_2': None, 'field_3': 45.32345, 'field_4': None}

Caution: Try not to use dict as a variable name, it'll cause some unpredictable exception due to conflict with dict python reserve name.

Upvotes: 0

Elisha
Elisha

Reputation: 23770

The issue seems to be in the line getting the transform_func. The values in field_types are tuples of name and transformer, but this tuple is used as a parameter to getattr instead of the name only:

def get_clean_dict(self, dict):
    cleaned_dict = {}
    # transform_func belongs to self.field_types
    for field_type, transform_func in self.field_types:
        for field_name in getattr(self, field_type):
            try:
                cleaned_dict[field_name] = transform_func(dict.get(field_name))
            except Exception:
                cleaned_dict[field_name] = None
    return cleaned_dict

Upvotes: 4

Related Questions