zoukankan      html  css  js  c++  java
  • Python基础:15私有化

            默认情况下,属性在Python 中都是“public”。

     

    1:双下划线(__)

            Python 为元素(属性和方法)的私有性提供初步的形式。由双下划线开始的属性在运行时被“混淆”,所以直接访问是不允许的。实际上,会在名字前面加上下划线和类名。

    class pubpri(object):
            def __init__(self, num):
                   self._num= num
                   self.__num = num
                   self.__num__= num
                   self.pubnum = num
    
    >>> n1 = pubpri(3)
    
    >>> n1._num
    3
    
    >>> n1.__num__
    3
    
    >>> n1.pubnum
    3
    
    >>>n1.__num
    Traceback(most recent call last):
    File"<stdin>", line 1, in <module>
    AttributeError:'pubpri' object has no attribute '__num'
    
    >>>n1._pubpri__num
    3

     

            尽管这样做提供了某种层次上的私有化,但算法处于公共域中,并且很容易被破解。

            这种名字混淆的另一个目的,是为了保护__XXX 变量不与父类名字空间相冲突。如果在类中有一个__XXX 属性,它将不会被其子类中的__XXX 属性覆盖。使用__XXX,子类的代码就可以安全地使用__XXX,而不必担心它会影响到父类中的__XXX。

     

    2:单下划线(_)

            在一个模块中以单下划线开头的变量和函数被默认当作内部函数,如果使用from a_module import * 导入时,这部分变量和函数不会被导入。不过值得注意的是,如果使用 import a_module 这样导入模块,仍然可以用a_module._some_var 这样的形式访问到这样的对象。比如,假设test.py内容如下:

    import  sys
    _modulenum = 3
    __modulenum = 3
    __modulenum__ = 3
    pubnum = 3
    
    def  _fun():
           print 'this is',sys._getframe().f_code.co_name
    
    def  __fun():
           print'this is ', sys._getframe().f_code.co_name
    
    def  __fun__():
           print'this is ', sys._getframe().f_code.co_name
    
    def  fun():
           print'this is ', sys._getframe().f_code.co_name
    
    
    >>> from  test import  *
    >>>_modulenum
    ...
    NameError: name'_modulenum' is not defined
    
    >>>__modulenum
    ...
    NameError: name'__modulenum' is not defined
    
    >>>__modulenum__
    ...
    NameError: name'__modulenum__' is not defined
    
    >>>pubnum
    3
    
    >>> _fun()
    ...
    NameError: name'_fun' is not defined
    
    
    >>> __fun()
    ...
    NameError: name'__fun' is not defined
    
    
    >>>__fun__()
    ...
    NameError: name'__fun__' is not defined
    
    
    >>> fun()
    this  is  fun
    
    
    >>> import test
    >>>test._modulenum
    3
    
    >>>test.__modulenum
    3
    
    >>>test.__modulenum__
    3
    
    >>>test.pubnum
    3
    
    >>>test._fun()
    this  is  _fun
    
    >>>test.__fun()
    this  is __fun
    
    >>>test.__fun__()
    this  is __fun__
    
    >>>test.fun()
    this  is  fun

            双下划线开头双下划线结尾的是一些 Python 的特殊对象,如类成员的 __init__、__del__、__add__、__getitem__等。 Python 官方推荐永远不要将这样的命名方式应用于自己的变量或函数,而是按照文档说明来使用。

     

            注意,私有化都是针对外部而言,在类内部,依然可以使用正常的访问方式,在类的外部就必须进行“混淆”了。比如:

    class test(object):
           __cversion =1.1
    
           def __init__(self):
                  self.__iversion = 1.2
    
           def fun(self):
                  print self.__iversion
                  print test.__cversion
                  print self._test__iversion
                  print self._test__cversion
    
    >>> from test import test
    >>> t1 = test()
    >>> t1.fun()
    1.2
    1.1
    1.2
    1.1
    
    >>> t1.__iversion
    Traceback (most recent call last):
      File"<stdin>", line 1, in <module>
    AttributeError: 'test' object has no attribute'__iversion'
    
    >>> t1._test__iversion
    1.2
    
    >>> t1.__cversion
    Traceback (most recent call last):
      File"<stdin>", line 1, in <module>
    AttributeError: 'test' object has no attribute'__cversion'
    
    >>> t1._test__cversion
    1.1

     

    参考:

    http://www.zhihu.com/question/19754941

     

  • 相关阅读:
    2020寒假简记
    感知神经网络模型与学习算法
    信息检索模型与评估
    Diffie-Hellman密钥交换
    RSA密码体制
    MySQL基准测试(benchmark)
    MySQL数据引擎
    MySQL 多版本并发控制(MVCC)
    MySQL事务管理
    利用dotnet restore 导入本地 .nupkg 包
  • 原文地址:https://www.cnblogs.com/gqtcgq/p/7247200.html
Copyright © 2011-2022 走看看