【问题标题】:is this code truly private? (python)这段代码真的是私人的吗? (Python)
【发布时间】:2012-04-28 16:00:57
【问题描述】:

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

谁能找到破解私有对象并从中获取值的方法?还有比这更好的方法吗?

python 2.7

#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 中没有多大意义......
  • 这段代码很吓人:(
  • 附注 - 不要使用niceDecorator。使用functools.wraps()
  • 我必须添加必填的Python is not Java 链接。
  • 好友...您不能在 Python 中将变量设为私有。时期。这是有原因的。习惯就好。

标签: python private


【解决方案1】:

简而言之:不要这样做。

There is no need to make things truly private in Python。使用您的软件的人可以看到某些东西是否被标记为私有(变量名称以_ 开头),所以他们知道。如果他们仍然想访问它,为什么要阻止他们?

我相信还有一种方法可以绕过您的代码 - Python 有大量的内省代码,而且修改类很容易。如果有人真的想得到它,几乎不可能锁定任何东西。

同样值得注意的是,在 Python 中,setter/getter 是没有意义的。目的是允许您在设置/获取属性时添加代码,python 允许您使用the property() builtin 来执行此操作。

【讨论】:

    【解决方案2】:

    这是一个有趣的想法,但是您用于装饰器的包装函数将在其func_closure 属性中引用“私有”对象。所以你的“私有”变量可以作为a.getValue.func_closure[0].cell_contents.test访问。 (您可以使用任何包装函数来获取您的“私有”对象,而不仅仅是getValue。)

    通常这种技术只会惹恼其他正在使用您的代码的程序员。

    【讨论】:

      【解决方案3】:

      在 Python 中总有一种方法可以解决问题,尤其是当您有原始源代码可供阅读时。使用 kindall 的示例,将这些行添加到文件的末尾:

      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 人们说“不要为私有变量烦恼”是有原因的。

      【讨论】:

        【解决方案4】:

        正如其他人所说,仍然有一种方法可以访问私有变量。但是,您仍然可以在 c++ 中访问私有变量。考虑这个 C++ 示例:

        class PrivateEye
        {
            private:
            int a;
            double b;
            char c;
        
            public:
            // ... public functions ...
        };
        
        PrivateEye detective;
        
        double privateB = *((double *) ((void *) &detective + sizeof(detective.a)));
        

        如您所见,访问私有变量需要做大量工作,因此执行此操作的人需要了解足够多的知识以了解风险。因此,如果您有程序员使用您的 _attribute 私有属性,那么您发布的解决方案将有效地让他们在弄乱私有属性之前考虑它。使用__attribute(双下划线)会导致一些名称修改,这同样会导致人们在决定访问“私有”属性之前做更多的思考。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-01-05
          • 2015-07-19
          • 1970-01-01
          • 2012-12-15
          • 1970-01-01
          相关资源
          最近更新 更多