python中 _、__、__xx__() 區別及使用場景

PRO_Z 發表於 2020-06-29

 1、訪問許可權(private、public)與繼承方式(只有public繼承)

  在物件導向程式語言中,類的屬性與方法都會設定訪問控制許可權,從而滿足我們的設計需求。一般而言,我們通常會將物件的屬性設定為私有的(private)或受保護的(protected),簡單的說就是不允許外界訪問,而物件的方法通常都是公開的(public),因為公開的方法就是物件向外界提供的介面。在Python中,屬性和方法的訪問許可權只有兩種,也就是公開的和私有的,如果希望屬性是私有的,在給屬性命名時可以用兩個下劃線作為開頭,下面的程式碼可以驗證這一點。

class Test:
    def __init__(self, foo):
        self.__foo = foo      # 私有屬性

    # 定義私有函式,外界不可以直接訪問,但是可以通過【_類名__函式名】去呼叫私有函式
    def __bar(self):
        print(self.__foo)
        print('__bar')

def main():
    """
    test = Test('hello')
    # AttributeError: 'Test' object has no attribute '__bar'
    test.__bar()
    # AttributeError: 'Test' object has no attribute '__foo'
    print(test.__foo)
    """
    
    # 使用以下這種方式就可以在類的外部呼叫類的私有屬性與方法
    test._Test__bar()
    print(test._Test__foo)

if __name__ == "__main__":
    main()

  在實際開發中,我們並不建議將屬性設定為私有的,因為這會導致子類無法訪問。所以大多數Python程式設計師會遵循一種命名慣例,就是讓屬性名以單下劃線開頭來表示屬性是受保護的,本類之外的程式碼在訪問這樣的屬性時應該要保持慎重。這種做法並不是語法上的規則,單下劃線開頭的屬性和方法外界仍然是可以訪問的,所以更多的時候它是一種暗示或隱喻,讓呼叫者知道這是不應該直接訪問的屬性或方法,而且這樣做並不影響子類去繼承這些東西。

2、__xx__() 的使用

  • 在python中,方法名如果是__xx__()的話,那麼就有特殊的功能,因此叫做“魔法”方法;
  • 當使用print輸出物件的時候,只要自己定義了__str__(self)方法,那麼就會列印從在這個方法中return的資料;
  • __str__()方法需要返回一個字串,當做這個物件的描寫。

 案例:定義一個類描述數字時鐘

import time

class Clock(object):
    """數字時鐘"""

    def __init__(self, hour=0, minute=0, second=0):
        """初始化方法

        :param hour: 時
        :param minute: 分
        :param second: 秒
        """
        self._hour = hour
        self._minute = minute
        self._second = second

    def run(self):
        """走字"""
        self._second += 1
        if self._second == 60:
            self._second = 0
            self._minute += 1
            if self._minute == 60:
                self._minute = 0
                self._hour += 1
                if self._hour == 24:
                    self._hour = 0

    def __str__(self):
        """顯示時間"""
        return '%02d:%02d:%02d' %(self._hour, self._minute, self._second)


def main():
    clock = Clock(23, 59, 58)
    while True:
        print(clock)
        time.sleep(1)
        clock.run()

if __name__ == '__main__':
    main()

   注意:Python類中的那些魔法方法,如__str__、__repr__等,這些方法並不是私有成員哦,雖然它們以雙下劃線開頭,但是他們也是以雙下劃線結尾的,這種命名並不是私有成員的命名,

最新文章