如何在Python中使用自定义描述符为类生成__init__?

时间:2015-05-09 12:37:41

标签: python descriptor

我为配置选项创建了一个自定义描述符,可用于创建这样的类:

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

真实实例包含更多属性。问题是我希望有__init__允许我在构造时初始化我想要的任何属性,如下所示:

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

由于实际上还有更多属性,因此难以维护,并且由于此处的模式非常规则,我想知道是否有办法自动提供此功能。

我的第一稿是这堂课:

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)

这就是我想要的,但在某些情况下甚至更多,因为它还初始化非配置属性的属性,这可能会导致其他基类出现问题。我不知道如何解决这个问题。 type(getattr(self, key))不会产生ConfigurationProperty,而是产生当前值的类型。

此外,它会将所有kwargs视为要初始化的配置属性。其中一些可能是其他基类构造函数的参数,所以我需要能够区分它。

那么,有没有办法以通用的方式和安全的方式提供这种功能?

1 个答案:

答案 0 :(得分:0)

只需使用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)

另一方面,为了进一步自动化该过程,可以引入映射配置参数 - >键入并动态创建和填充属性:

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])