Python中单/双下划线使用

来源:互联网 发布:自动分辨率软件 编辑:程序博客网 时间:2024/06/01 03:59

转载自:http://blog.csdn.net/my2010sam/article/details/10949717

出处:http://blog.chinaunix.net/uid-1721137-id-266703.html
在Python编程中经常会遇到函数(function),方法(method)及属性(attribute)以下划线'_'作为前缀,这里做个总结。
主要存在四种情形
        [python] view plain copy
        1. <span style="font-family:SimSun; font-size:18px">1. object # public  
        2.   
        3.   
        4. 2. __object__ # special, python system use, user should not define like it  
        5.   
        6.   
        7. 3. __object # private (name mangling during runtime)  
        8.   
        9.   
        10. 4. _object # obey python coding convention, consider it as private  
        11. </span>  

        通过上面的描述,1和2两种情形比较容易理解,不多做解释,最迷惑人的就是3和4情形。
      在解释3和4情形前,首先了解下python有关private的描述,python中不存在protected的概念,要么是public要么就是private,但是python中的private不像C++, Java那样,它并不是真正意义上的private,通过name mangling(名称改编,下面例子说明)机制就可以访问private了。

      针对 3:
       
      [python] view plain copy
      1. <span style="font-family:SimSun; font-size:18px">class Foo():  
      2.   
      3.     def __init__():  
      4.   
      5.         ...  
      6.   
      7.       
      8.   
      9.     def public_method():  
      10.   
      11.         print 'This is public method'  
      12.   
      13.   
      14.   
      15.     def __fullprivate_method():  
      16.   
      17.         print 'This is double underscore leading method'  
      18.   
      19.   
      20.   
      21.     def _halfprivate_method():  
      22.   
      23.         print 'This is one underscore leading method'  
      24. </span>  

        然后我们实例化Foo的一个对象,看看结果就很清晰了:
        [python] view plain copy
        1. <span style="font-family:SimSun; font-size:18px">f = Foo()  
        2.   
        3.   
        4.   
        5. f.public_method() # OK  
        6.   
        7.   
        8.   
        9. f.__fullprivate_method() # Error occur  
        10.   
        11.   
        12.   
        13. f._halfprivate_method() # OK  
        14. </span>  

          上文已经说明了,python中并没有真正意义的private,见以下方法便能够访问__fullprivate_method()
          1. [python] view plain copy
            1. <span style="font-family:SimSun; font-size:18px">f._Foo__fullprivate()_method() # OK</span>  
          2. [python] view plain copy
            1. <span style="font-size:18px">  
            2.   
            3. </span>  
            [python] view plain copy
            1. <ol><li><span style="font-size:18px"><span style="font-family:SimSun"><span style="color:#0000ff">print</span> dir<span style="color:#0000cc">(</span>f<span style="color:#0000cc">)</span>  
            2. </span></span></li></ol>  

            ['_Foo__fullprivate_method','_halfprivate_method','public_method',...]

          所谓的name mangling就是将__fullprivate_method替换成了_Foo__fullprivate_method,目的就是以防子类意外重写基类的方法或者属性。


          允许通过类内部方法访问其他私有方法,如下:



          针对4:
          从上面的例子可以看出,f._halfprivate_method()可以直接访问,确实是。不过根据python的约定,应该将其视作private,而不要在外部使用它们,(如果你非要使用也没辙),良好的编程习惯是不要在外部使用它咯。
          同时,根据Python docs的说明,_object和__object的作用域限制在本模块内,见以下示例:
              1. [python] view plain copy
                1. <span style="font-family:SimSun; font-size:18px">''''' 
                2.  
                3. A.py 
                4.  
                5. '''  
                6.   
                7. def _nok(): # __nok() same as _nok()  
                8.   
                9.    ...  
                10.   
                11. def ok():  
                12.   
                13.     ...  
                14. </span>  

              2. [python] view plain copy
                1. ''''' 
                2.  
                3. <span style="font-family:SimSun; font-size:18px">B.py 
                4.  
                5. '''  
                6.   
                7. from A import *  
                8.   
                9.   
                10. ok() # work well  
                11.   
                12.   
                13. _nok() # error occur  
                14.   
                15.   
                16. __nok() # error occur  
                17. </span>  


               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
              通过上面的例子就能很好地把握有关下划线的细节了,平时还是需要多动手练练。