如何从邪恶的程序员那里保护python类变量?

Juh*_*uha 5 python dictionary private class protected

如何保护我的变量免受此类攻击:

MyClass.__dict__ = {}
MyClass.__dict__.__setitem__('_MyClass__protectedVariable','...but it is not')
Run Code Online (Sandbox Code Playgroud)

上面改变了变量字典,之后是孩子们玩改变所有变量.上线对于此工作至关重要.如果您的字典__setitem__被调整如下,则上述方法无效.

我想强制用户使用我的方法setProtectedVariable(value)来更改变量,但我似乎没有办法在Python 2.7中这样做.有任何想法吗?

如果您从下面的代码中找到其他类似的漏洞,我也很感激(我注意到我还应该在我的inspect.stack办理登机手续中添加文件名和行号myDict.__setitem__).

这是我到目前为止所尝试的:

import inspect

class ProtectionTest:

    __myPrivate = 0

    def __init__(self):
        md = myDict()
        setattr(self,'__dict__', md)

    def __setattr__(self, name, val):     
        if name == '__myPrivate':
            print "failed setattr attempt: __myPrivate"
            pass
        elif name == '_ProtectionTest__myPrivate':
            print "failed setattr attempt: _ProtectionTest__myPrivate"  
            pass
        elif name == '__dict__':
            print "failed setattr attempt: __dict__"
            pass
        else: 
            self.__dict__[name] = val             

    def getMyPrivate(self):
        return self.__myPrivate

    def setMyPrivate(self, myPrivate):
        #self.__dict__['_ProtectionTest__stack'] = inspect.stack()[0][1:]
        self.__dict__['_ProtectionTest__myPrivate'] = -myPrivate

class myDict(dict):

    def __init__(self):
        dict.__init__(self)

    def __setitem__(self, key, value):
        if inspect.stack()[1][3] == 'setMyPrivate':
            dict.__setitem__(self,key,value)
        else:
            print "failed dict attempt"
            pass

pt = ProtectionTest()

print "trying to change... (success: 1): "
pt.__myPrivate = 1
print pt.getMyPrivate(), '\n'

print "trying to change... (success: 2): "
pt._ProtectionTest__myPrivate = 2
print pt.getMyPrivate() , '\n'

print "trying to change... (success: 3): "
pt.__dict__['_ProtectionTest__myPrivate'] = 3
print pt.getMyPrivate() , '\n'

print "trying to change the function (success: 4): "
def setMyPrivate(self, myPrivate):
    self.__dict__['_ProtectionTest__myPrivate'] = 4
pt.setMyPrivate = setMyPrivate
pt.setMyPrivate(0)
print pt.getMyPrivate(), '\n'

print "trying to change the dict (success: 5): "
pt.__dict__ = {}
pt.__dict__.__setitem__('_ProtectionTest__myPrivate',5)
print pt.getMyPrivate(), '\n'

print "Still working (correct output = -input = -100): "    
pt.setMyPrivate(100)
print pt.getMyPrivate()  
Run Code Online (Sandbox Code Playgroud)

sen*_*rle 18

我觉得有一些深刻的困惑激发了这个问题.私人变量不是为了阻止邪恶的"黑客".它们与安全无关.他们在那里推广良好的编程实践,如保持低耦合.

如果"邪恶的程序员"可以访问您的源代码,他或她可以做任何他或她想要的事情.调用变量"private"不会改变它.如果说邪恶的程序员试图破坏你在另一个系统上执行的程序......调用变量"私有"对你没有好处.它不会改变程序在内存中存储和操作的方式.它只是强制(以不必要的复杂方式IMO)分离关注点.

此外,值得注意的是,在正常情况下,您不必经历所有这些恶作剧......

MyClass.__dict__ = {}
MyClass.__dict__.__setitem__('_MyClass__protectedVariable','...but it is not')
Run Code Online (Sandbox Code Playgroud)

...分配给受保护的var.你甚至不必覆盖__dict__.你可以这样做:

MyClass._MyClass__protectedVariable = '...but it is not'
Run Code Online (Sandbox Code Playgroud)

因为它真的不是.受保护,我的意思是.名称修改的主要目的是防止命名空间冲突.如果您只想要一个"私有"属性,只需在其前面加上一个下划线.期望您的用户尊重惯例,并期望您的滥用者无论您做什么都会打破它.


Ned*_*der 8

在Python中,您不能以这种方式"保护"属性.你为什么和你的来电者发生敌对关系?你和他需要就某些事情达成一致,这是其中之一.写出更好的文档,与他成为更好的朋友.我不知道你的真正问题是什么,但是用代码无法解决.

其他语言如Java和C++提供了分离private等等,但Python根本没有.事后你不能把它搞砸.

如果你告诉我们更多关于这个邪恶的程序员是谁,以及为什么你和他不同意你的代码应该如何使用,我们可能会给你其他解决方案的想法.

  • 至少在C++中,即使是`private`也可以通过一些不太依赖于平台的方式来规避:) (6认同)

Dou*_*gal 7

AFAIK在Python中没有办法做到这一点.无论你做什么,任何人都可以随时复制你的源并删除你的黑客,或者(在大多数情况下)从类继承并覆盖它或直接重新分配方法.

但是:你为什么这么关心?如果你把它命名为__whatever非常明确的文档,如果用户搞乱这个,那么发生的任何不好的事情都是他们自己该死的错误.