Python類的存取許可權(public、 private、protected)

2020-07-16 10:05:27
與 C++、C#、Java 等語言相似,Python 支援將類的屬性和方法設定成特定的存取許可權,但不是通過關鍵字區分,而是使用一套約定式的規則:
  • 使用一個下畫線“_”開頭的屬性或方法為保護(protected)屬性或方法,只能在類或其派生類中存取,在類內部以“self._屬性名或方法名”的方式使用;
  • 其他的屬性或方法為公有(public)屬性或方法,可在類的外部直接存取,在類內部以“self.屬性名或方法名”的方式使用。

以下例子展示了三種不同存取許可權的屬性和方法:
class Class1:
    public1= 111
    _protected1 = 222
    _private1 = 333
    def publicFunc1(self):
        pass
    def _protectedFunc1(self):
        pass
    def __privateFunc1(self):
        pass

class Class2(Class1):
    public2 = 444
    _protected2 = 555
    __private2 = 666
    def publicFunc2(self):
        pass
    def _protectedFunc2(self):
        pass
    def __privateFunc2(self):
        pass

c1 = Class1()
    print(c1.public1)
    print(c1._protected1)
    print(c1.__private1)
c1.publicFunc1()
c1._protectedFunc1()
c1.__privateFunc1()

c2 = Class2()
    print(c2.public1)
    print(c2._protected1)
    print(c2.__private1)
    print (c2.public2)
    print(c2._protected2)
    print(c2.__private2)
c2.publicFunc1()
c2._protectedFunc1()
c2.__privateFunc1()
c2.publicFunc2()
c2._protectedFunc2()
c2.__privateFunc2()
上述程式碼的執行結果如下所示:

>>> class Class1:
...          public1= 111
...          protected1 = 222
...          _private1 = 333
...          def publicFunc1(self):
...              pass
...          def _protectedFunc1(self):
...              pass
...          def __privateFunc1(self):
...              pass

>>> class Class2(Class1):
...          public2 = 444
...          _protected2 = 555
...          __private2 = 666
...          def publicFunc2(self):
...              pass
...          def _protectedFunc2(self):
...              pass
...          def __privateFunc2(self):
...              pass

>>> c1 = Class1()
>>> print(c1.public1)
111
>>> print(c1._protected1)
222
>>> print(c1.__private1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    print(c1.__private1)
AttributeError: 'Class1' object has no attribute '__private1'
>>> c2 = Class2()
>>> print(c2.public1)
111
>>> print(c2._protected1)
222
>>> print(c2.__private1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    print(c2.__private1)
AttributeError: 'Class2' object has no attribute '__private1'
>>> print (c2.public2)
444
>>> print(c2._protected2)
555
>>> print(c2.__private2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    print(c2.__private2)
AttributeError: 'Class2' object has no attribute '__private2'
>>> c2.publicFunc1()
>>> c2._protectedFunc1()
>>> c2.__privateFunc1()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    c2.__privateFunc1()
AttributeError: 'Class2' object has no attribute '__privateFunc1'
>>> c2.publicFunc2()
>>> c2._protectedFunc2()
>>> c2.__privateFunc2()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    c2.__privateFunc2()
AttributeError: 'Class2' object has no attribute '__privateFunc2'

可以看到,在外部直接存取類的私有屬性或方法時觸發了 AttributeError 異常。