这段代码真的是私密的吗?

is this code truly private? (python)

我试图让python允许私有变量,所以我做了一个修饰器,你把它放在一个类的begging上,这样每个函数都会得到一个额外的私有参数,它们可以修改为他们想要的。据我所知,不可能从课堂外获得变量,但我不是专业人员。

有人能找到一种方法入侵这个私有对象并从中获取价值吗?有没有比这更好的方法?

Python2.7

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#this is a decorator that decorates another decorator. it makes the decorator
#not loose things like names and documentation when it creates a new function
def niceDecorator(decorator):
    def new_decorator(f):
        g = decorator(f)
        g.__name__ = f.__name__
        g.__doc__ = f.__doc__
        g.__dict__.update(f.__dict__)
        return g
    new_decorator.__name__ = decorator.__name__
    new_decorator.__doc__ = decorator.__doc__
    new_decorator.__dict__.update(decorator.__dict__)
    return new_decorator

@niceDecorator
#this is my private decorator
def usePrivate(cls):

    prv=type('blank', (object,), {})
    #creates a blank object in the local scope
    #this object will be passed into every function in
    #the class along with self which has been renamed
    #as pbl (public).

    @niceDecorator
    #this is the decorator that gets applied to every function
    #in the class. in makes it also accept the private argument
    def decorate(func):
        def run(pub, *args, **kwargs):
            return func(pub,prv, *args, **kwargs)
        return run

    #this loops through every function in the class and applies the decorator
    for func in cls.__dict__.values():
        if callable(func):
            setattr(cls, func.__name__, decorate(getattr(cls, func.__name__)))

    return cls

#this is the class we are testing the private decorator with.
#this is what the user would program
@usePrivate
class test():

    #sets the value of the private variable
    def setValue(pbl,prv,arg):
        #pbl (public) is another name for self
        #prv (private) acts just like self except its private
        prv.test=arg

    #gets the value of the private variable
    def getValue(pbl,prv):
        return prv.test
a=test()
a.setValue(3)
print a.getValue()


简而言之:不要这样做。

在Python中,没有必要让事情变得真正私有化。使用您的软件的人可以看到某个东西是否标记为私有(变量名以_开头),所以他们知道。如果他们仍然想要访问它,为什么要阻止他们?

我相信还有一种方法可以绕过代码——python有大量自省的代码,修改类很容易。如果有人真的想把任何东西锁起来,实际上是不可能的。

同样值得注意的是,在Python中,setter/getter是没有意义的。这样做的目的是允许您在设置/获取属性时添加代码,而Python允许您使用property()内置功能来实现这一点。


这是一个有趣的想法,但是您为decorator使用的包装函数将在它们的func_closure属性中引用"private"对象。所以您的"private"变量可以作为a.getValue.func_closure[0].cell_contents.test访问。(您可以使用任何包装函数来访问"private"对象,而不仅仅是getValue)。

一般来说,这种技术只会让使用您的代码的其他程序员感到恼火。


在Python中总是有一种方法来处理事情,特别是当您有原始的源代码要读的时候。使用Kindall的示例,将这些行添加到文件末尾:

1
2
3
print a.getValue.im_func.func_closure[0].cell_contents.test
a.getValue.im_func.func_closure[0].cell_contents.test = 17
print a.getValue()

真的,不要这样做。有一个原因,python人们会说,"不要为私有变量操心。"


正如其他人所说,还有一种方法可以得到私有变量。但是,您仍然可以在C++中获取私有变量。考虑这个C++例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class PrivateEye
{
    private:
    int a;
    double b;
    char c;

    public:
    // ... public functions ...
};

PrivateEye detective;

double privateB = *((double *) ((void *) &detective + sizeof(detective.a)));

正如您所看到的,访问私有变量需要大量的工作,因此进行此操作的人需要足够的了解风险。因此,如果您的程序员使用您的_attributeprivate属性,那么您发布的解决方案将有效地让他们在处理私有属性之前考虑它。使用__attribute(双下划线)会导致某些名称的混乱,这也会导致人们在决定访问"private"属性之前进行更多的思考。

编辑:根据访问私有成员的第二个答案,C++标准不能保证类中成员变量的顺序,因此,您可能需要实验一点才能访问上面C++实例中想要的私有变量。