How do I generate __init__ for a class with custom descriptors in Python?

I created my own descriptor for the configuration parameters that can be used to create classes like this:

class Configuration(SomeSpecificBackend):
    basedir = ConfigurationProperty('basedir', int)
    logfile = ConfigurationProperty('logfile', Path)

      

Real instances contain many more properties. The problem is that I would like to have __init__

one that allows me to initialize whatever properties I want when I build, for example:

    def __init__(self, basdir=None, logfile=None):
        if basedir is not None:
            self.basedir = basedir
        if logfile is not None:
            self.logfile = logfile

      

Since there are many other properties in practice, this becomes difficult to maintain, and since the pattern is very regular here, I'm wondering if there is a way to automatically provide this functionality.

My first project was this class:

class ConfigurationBase():
    def __init__(self, **kwargs):
        super().__init__()
        for key, value in kwargs.items():
            if hasattr(self, key): # don't create new attributes
                setattr(self, key, value)

      

This does what I want, but even more in some cases, as it also initializes attributes that are not configuration properties, which can cause problems with other base classes. I don't know how to fix this. type(getattr(self, key))

does not give ConfigurationProperty

, but the type of the current value.

Also, it treats everything kwargs

as configuration properties that need to be initialized. Some of them might be arguments to other base class constructors, so I would need to differentiate that.

So, is there a way to provide this functionality in a general and secure way?

+3


source to share


1 answer


Just use locals

:

def __init__(self, basdir=None, logfile=None):
    for name, value in locals().items():
        if values is not None and hasattr(self, name):
            setattr(self, name, value)

      



On the other hand, to further automate this process, one can enter the config -> type configuration parameter and create and populate properties dynamically:

class Configuration(SomeSpecificBackend):
    CONFIGURATION_PROPERTIES = {
        'basedir': int,
        'logfile': Path,
    }
    for name, type_ in CONFIGURATION_PROPERTIES.items():
        locals()[name] = ConfigurationProperty(name, type_)

    def __init__(self, **properties):
        for name in self.CONFIGURATION_PROPERTIES:
            if name in properties:
                setattr(self, name, properties[name])

      

0


source







All Articles