[Python] 單底線與雙底線

[code lang=”python”]#single_double.py
class Parent(object):
def _single(self):
print("Parent single underscore")
def __double(self):
print("Parent double underscore")

class Child(Parent):
pass

c = Child()
c._single() #Parent single underscore
#Python並沒有類似C的protected member
#單底線的member在執行行並沒有實際差異
#但單底線的member表示此member不應該被其他人或是Child使用

print(dir(c))
#[‘_Parent__double’, ‘__class__’, … ‘__weakref__’, ‘_single’]

#c.__double() AttributeError: ‘Child’ object has no attribute ‘__double’
c._Parent__double()
#雙底線的member在child是沒辦法被直接存取
#Python並沒有所謂的private function,但可以用雙底線達到類似的效果
[/code]

[code lang=”python”]
def _single():
pass

def foo():
pass[/code]

>>> dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
>>> from single_double import *
...
>>> dir() #foo被import 但_single_double沒有
['Child', 'Parent', '__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'c', 'foo']
>>> from single_double import _single
>>> dir()
['Child', 'Parent', '__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', '_single', 'c', 'foo']
>>> 

若是用from xx import *的方式import
單底線的member不會被import
但還是可以用from xx import _single的方式強制import

底線開頭加結尾的member
例如上例執行dir()跑出來的’annotations‘, ‘builtins‘, ‘doc‘, ‘loader‘ …
這種member代表有特殊意思
除非了解他的用途 否則不應該隨意取這種名稱

[code lang=”python”]#single_double.py

""" need module docstring"""

class Parent(object):
""" need class docstring"""
def _single(self):
print("Parent single underscore")

def __double(self):
print("Parent double underscore")

def open(self):
""" method docstring"""
pass

def _single():
pass

def foo():
""" function docstring"""
pass[/code]

執行pep8或是pylink
會發現他們要求所有的公開method都需要docstring
但單底線及雙底線開頭的method都不會要求docstring

發表留言

這個網站採用 Akismet 服務減少垃圾留言。進一步瞭解 Akismet 如何處理網站訪客的留言資料