[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,但可以用雙底線達到類似的效果

def _single():
    pass

def foo():
    pass
>>> 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代表有特殊意思
除非了解他的用途 否則不應該隨意取這種名稱

#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

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

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *