Python 以只读模式锁定ConfigParser

Python 以只读模式锁定ConfigParser,python,readonly,configparser,Python,Readonly,Configparser,是否有一个属性可以在只读模式下锁定ConfigParser对象 我正在使用一个项目范围的全局ConfigParser对象,我想防止代码修改该对象。我可以很容易地重写ConfigParser.set(section,option,value)以在调用该方法时引发错误,但我想知道我是否忽略了一个更简单的解决方案。我找到了这个问题的通用解决方案(使用Felix Kling在此处编写的这段奇妙的代码片段:)。 我的目标是简化调试器的工作,使用一些防御性编程,而不是防止对类的任何恶意访问 此外,这有点骇人

是否有一个属性可以在只读模式下锁定
ConfigParser
对象


我正在使用一个项目范围的全局
ConfigParser
对象,我想防止代码修改该对象。我可以很容易地重写
ConfigParser.set(section,option,value)
以在调用该方法时引发错误,但我想知道我是否忽略了一个更简单的解决方案。

我找到了这个问题的通用解决方案(使用Felix Kling在此处编写的这段奇妙的代码片段:)。 我的目标是简化调试器的工作,使用一些防御性编程,而不是防止对类的任何恶意访问

此外,这有点骇人听闻:常量成员和私有/受保护的访问与Python的理念(显式优于隐式,…)非常契合


第一阶段:区块设定器 首先,我们必须阻止ConfigParse中的任何设置程序:简单地说,我们只需要覆盖
set(self、section、option、value)

def set(self, section, option, value):
    raise SyntaxError("No modification authorized")

第二阶段:区块成员 这一部分有点问题:为了控制常量成员上的setter,我们必须使用
@property
装饰器将方法伪装为成员。
@常量
装饰器只是一个修改的
@属性
装饰器:

# Constant decorator
def constant(f):
    def fset(self, value):
        raise SyntaxError("Don't touch that !")
    def fget(self):
        return f(self)
    return property(fget, fset)

# Config Class. Notice the object name in the type of class FixedConfig has to derived from
# ( Python 2.xx and new-style class purpose) 
# (see more here : https://stackoverflow.com/questions/598077/why-does-foo-setter-in-python-not-work-for-me )

class FixedConfig( object, ConfigParser):
    def __init__(self):
        ConfigParser.__init__()
        self.read("filepath to config file")

    def set(self, section, option, value):
        raise SyntaxError("No modification authorized")

    #fake DNS service : map domain names to IP
    @constant
    def DNS(self):
        return { self.get("domain names", IP) : IP  \ 
                  for IP in self.options("domain names") )

第3阶段:块方法 最后,必须防止重写类方法(Python的猴子补丁的魔力)。这种修改并不常见,但可能发生(特别是在处理依赖项反转时)。在本例中,我们不希望重写
FixedConfig.set

config = FixedConfig()
print config.get("domain names", "127.0.0.1")
#>> 'localhost'
config.set = super(FixedConfig,self).set  # swap FixedConfig.set with ConfigParser.set
config.set("domain names", "127.0.0.1", "CommandAndControl") 
print config.get("domain names", "127.0.0.1")
#>> 'CommandAndControl'
要防止这种情况发生,只需使用
@constant
修饰
set
方法即可


同样,它并不能阻止恶意的人重写常量装饰器并覆盖set属性(我不认为我们在Python中可以有这种保护),但在整个项目中跟踪对常量装饰器的调用比跟踪对配置成员的调用要容易得多