Python下劃線和私有變量

Python下劃線和私有變量

最近小組python氛圍濃厚,有同學發現自己在一個類裏定義了一個方法,但不能用getattr調用。我整理一下python中下劃線在命名時的特殊用法。

規範描述

根據PEP-0008的規範:

In addition, the following special forms using leading or trailing
underscores are recognized (these can generally be combined with any
case convention):

  • _single_leading_underscore: weak “internal use” indicator.
    E.g. from M import * does not import objects whose name starts
    with an underscore.

  • single_trailing_underscore_: used by convention to avoid
    conflicts with Python keyword, e.g. ::

         Tkinter.Toplevel(master, class_='ClassName')
    
  • __double_leading_underscore: when naming a class attribute,
    invokes name mangling (inside class FooBar, __boo becomes
    _FooBar__boo; see below).

  • __double_leading_and_trailing_underscore__: “magic” objects or attributes that live in user-controlled namespaces.
    E.g. __init__, __import__ or __file__. Never invent
    such names; only use them as documented.

是的,python中下劃線在命名時是有規範的。下面分別舉例說明。

單下劃線開頭

單下劃線開頭的命名,規範裏描述爲“弱內部引用”,一般對應“protect”。

##m.py
a = 1
_a = 2
__a = 3
##test.py
import m
from m import *
print a # 打印1
print _a # 異常,NameError: name '_a' is not defined
print m.a # 打印1
print m._a # 打印2

import *時不能導入單下劃線開頭命名的變量或方法。訪問的時候可以通過“模塊.變量”。這裏的protect並非嚴格的。

##c.py
class C(object):
    a = 1
    _a = 2
## test.py
from c import C
o = C()
print o.a  #打印1
print o._a #打印2
o._a = 3
print o._a #打印3

我們可以看到類中_a也是可以通過對象直接訪問的。這裏的“protect”是一種規範,我們應該按照規範來編寫代碼。

單下劃線結尾

單下劃線結尾的命名用來與python中有保留字段避免衝突,pep8給的例子

Tkinter.Toplevel(master, class_='ClassName')

雙下劃線開頭

雙下滑線開頭被認爲是私有的。python中的private並非像C++中那樣嚴格定義,而是通過改編命名,將雙下滑線開頭的命名前面加上單下劃線+類名。

##c.py
class C(object):
    a = 1
    _a = 2
    __a = 3

##test.py
from c import C

o = C()
print o.a #打印1
print o._a #打印2
print o.__a #異常,AttributeError: 'C' object has no attribute '__a'
print o._C__a #打印3

所以,雙下劃線開頭的命名用getattr(“__xxx”)是獲取不到的,但是用getattr(“_Class__xxx”)就可以訪問。不過這裏還是要提一個規範的問題。既然我們用雙下劃線開頭,就是希望作爲一個私有的變量或方法。那我們應該用私有的用法去使用。

雙下劃線開頭、雙下劃線結尾

像__init__,__new__,這種,作爲python class的特殊用法專用的標識,就不多舉例了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章