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

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视为要初始化的配置属性。其中一些可能是其他基类构造函数的参数,所以我需要能够区分它们。
那么,有没有一种方法可以以通用和安全的方式提供这种功能呢?

最佳答案

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

另一方面,为了进一步自动化此过程,可以引入一个映射配置参数->type并动态创建和填充属性:
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])

关于python - 如何在Python中使用自定义描述符为类生成__init__?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30140020/

10-12 18:51