天天看點

python類的成員沒有通路控制限制_如何掌握python通路限制?

說到通路控制,python小白可能會很陌生。那就舉一個簡單的例子,我們住的房子是私有物,而外面的公共設施是公有物。這樣是不是好了解一點了呢?

通路控制有三種級别:私有、受保護、公有

私有(Private):隻有類自身可以通路

受保護(Protected):隻有類自身和子類可以通路

公有(Public):任何類都可以通路

一、公有(Public)

在Python的類中,預設情況下定義的屬性都是公有的。class Foo(object):

bar = 123

def __init__(self, bob):

self.bob = bob

print(Foo.bar)  # 123

foo = Foo(456)

print(foo.bob)  # 456

上面類Foo中的bar屬性就是類屬性,init方法中定義的bob是執行個體屬性,bar和bob都是公有的屬性,外部可以通路,分别print類中的bar和執行個體中的bob,輸出了對應的值。

二、受保護(Protected)

在Python中定義一個受保護的屬性,隻需要在其名字前加一個下劃線_,我們将Foo方法中的bob和bar改為_bob和_bar,他們就變成了受保護的屬性了,代碼如下:class Foo(object):

_bar = 123

def __init__(self, bob):

self._bob = bob

class Son(Foo):

def print_bob(self):

print(self._bob)

@classmethod

def print_bar(cls):

print(cls._bar)

Son.print_bar()  # 123

son = Son(456)

son.print_bob()  # 456

定義一個類Son繼承自Foo,由于受保護的對象隻能在類的内部和子類中被通路,不能直接調用print(Son._bar)或print(son._bob)來輸出這兩個屬性的值,是以定義了print_bar和print_bob方法,實作在子類中輸出,這段代碼也正常的輸出了_bar和_bob的值。

接下來,試着反向驗證一下,在類的外部,能不能通路其屬性,将上面代碼的輸出部分修改如下:print(Son._bar)  # 123

son = Son(456)

print(son._bob)  # 456

(假裝)驚訝的發現,竟然沒有報錯,也輸出了正确的值。

Python中用加下劃線來定義受保護變量,是一種約定的規範,而不是語言層面真的實作了通路控制,是以,我們定義的保護變量,依然可以在外部被通路到(這是個feature,不是bug)。

三、私有(private)

Python定義私有屬性,需要在屬性名前加兩個下劃線__,把上面的代碼修改一下,運作一下會發現下面的代碼中的任何一個print都會報錯的。class Foo(object):

__bar = 123

def __init__(self, bob):

self.__bob = bob

class Son(Foo):

def print_bob(self):

print(self.__bob)  # Error

@classmethod

def print_bar(cls):

print(cls.__bar)  # Error

print(Son.__bar)  # Error

son = Son(456)

print(son._bob)  # Error

以上就是python通路限制的三種級别。更多Python學習推薦:JQ教程網Python大全。