Python - 物件導向程式設計 - 公共屬性、保護屬性、私有屬性

小菠蘿測試筆記發表於2021-08-29

公共屬性

在 Python 的類裡面,所有屬性和方法預設都是公共的

class PoloBlog:
    # 公共屬性
    sum = 0

    # 構造方法
    def __init__(self, name):
        self.name = name

    # 公共方法
    def test(self):
        ...

但Python也可以設定受保護、私有型別的變數or方法

 

私有型別的屬性、方法

  • 在實際開發中,物件的某些屬性或方法可能只希望在物件的內部被使用,而不希望在外部被訪問到
  • 私有屬性:就是物件不希望公開訪問的屬性
  • 私有方法:就是物件不希望公開訪問的方法

 

定義方式,類圖

在屬性、方法名前加兩個下劃線就是私有屬性、私有方法了

 

程式碼

# 私有屬性、方法
class Person:

    # 構造方法
    def __init__(self, name, age):
        self.name = name
        self.__age = age

    # 例項方法
    def pinrtMsg(self):
        print("name:", self.name, " age:", self.__age)

    # 私有方法
    def __getAge(self):
        print("age is ", self.__age)


person = Person("小菠蘿", 24)
# 直接呼叫私有屬性、私有方法 - 會報錯
print(person.__age)
print(person.__getAge)



# 輸出結果
    print(person.__age)
AttributeError: 'Person' object has no attribute '__age'

    print(person.__getAge)
AttributeError: 'Person' object has no attribute '__getAge'

 

看看 Pycharm 的程式碼聯想

壓根不會聯想,因為是私有屬性、私有方法,不允許在物件外部被使用

 

通過公共方法訪問私有屬性

person = Person("小菠蘿", 24)
person.printMsg()


# 輸出結果
name: 小菠蘿  age: 24

 

類屬性私有化

# 類屬性的私有化
class Person:
    __sum = 0

    @classmethod
    def getSum(cls, num):
        # 呼叫私有類方法
        cls.__sumAdd(num)
        print(cls.__sum)

    @classmethod
    def __sumAdd(cls, num):
        cls.__ 

 

重點

  • 子類無法訪問父類的私有變數、方法
  • 私有變數只有本類的內部能直接呼叫
  • But!外部真的不能訪問嗎?

 

偽私有屬性和私有方法

  • 其實 Python 中,並沒有真正意義上的私有,仍然可以在外部訪問私有屬性、私有方法
  • 因為,在給私有屬性、方法命名時,實際是對名稱做了一些特殊處理,使得外界無法訪問到
  • 處理方式:在名稱前面加上 _類名 ,私有屬性、方法就會變成  _類名__名稱 
# 間接呼叫
class Person:
    __sum = 0

    # 構造方法
    def __init__(self, name):
        self.__name = name

    # 私有方法
    def __getName(self):
        print("name is ", self.__name)


# 呼叫類私有屬性
print(Person._Person__sum)

person = Person("小菠蘿")

# 呼叫私有屬性
print(person._Person__name)
# 呼叫私有方法
person._Person__getName()



# 輸出結果
0
小菠蘿
name is  小菠蘿

無論是類物件還是例項物件,都可以通過 ._類名__名稱 來呼叫私有屬性、方法,這算是一種間接呼叫

 

受保護型別的屬性、方法

  • 受保護型別一般會稱為:protect 屬性,學過 Java 的應該都瞭解
  • 在屬性和方法前加一個下劃線就是 protect 型別了,私有型別是兩個下劃線
# 受保護型別
class PoloBlog:
    _sum = 0.0

    # 構造方法
    def __init__(self, name):
        self._name = name

    # 保護方法
    def _printName(self):
        print(self._name)

    # 類方法
    @classmethod
    def _classMethod(cls):
        print(cls._sum)


blog = PoloBlog("小菠蘿")
# 列印保護型別的類屬性
print(PoloBlog._sum)

# 列印保護型別的例項屬性
print(blog._name)

# 例項物件呼叫保護型別的例項方法
blog._printName()

# 例項物件呼叫保護型別的類方法
blog._classMethod()

# 類物件呼叫保護型別的類方法
PoloBlog._classMethod()


# 輸出結果
0.0
小菠蘿
小菠蘿
0.0
0.0

 

知識點

  • 父類的 protect 屬性,子類可以繼承
  • 例項物件、類物件都能直接呼叫 protect 屬性、方法

總的來說,和公共變數沒有什麼特別大的區別

  

總結

無論是受保護型變數還是私有變數,其實在外部還是能訪問的,所以並不能真正控制屬性的訪問許可權

相關文章