Python3僞私有屬性

目錄

1:僞私有屬性介紹 

2:雙下劃線:僞私有屬性實現過程


1:僞私有屬性介紹 

在Python中一切都是對象,並且類的所有屬性和方法都是公有的(public),並不存在private 關鍵字來聲明私有方法或屬性。那麼在Python中怎麼實現像其他編程語言一樣的私有屬性呢?其實只需在屬性前加上雙下劃線(但是結尾處不能有雙下劃線)即可,如:self.__name,這並不是真正私有,而是“僞私有”,因爲Python會把self.__name 變爲self._類名__name,你可以使用"對象._類名__name"訪問這個屬性。

# encoding=gbk

class Test:
    def __init__(self,name):
        self.__name = name

t = Test('ixusy88')
print(t.__dict__)  # 輸出 {'_Test__name': 'ixusy88'}; 屬性 __name 變爲 _Test__name了
# print(t.__name)  # 輸出:AttributeError: 'Test' object has no attribute '__name';
                   # 不能訪問屬性__name,因爲屬性 __name 變爲 _Test__name了,不存在屬性__name

# 可以通過 對象._類名__屬性  訪問
print(t._Test__name)
# 通過下標訪問
print(t.__dict__['_Test__name'])

2:雙下劃線:僞私有屬性實現過程

在運算符重載中有提到 __setattr__ 能夠攔截所有的屬性賦值操作,__getattr__能夠攔截沒有定義屬性的訪問(即不存在於

__dict__中的屬性)。

其攔截過程如下:
self.屬性 = 屬性值   會調用 self.__setattr__('屬性',屬性值)

self.屬性 = 屬性值   會調用 self.__setattr__('_類__屬性',屬性值)

對象.屬性 = 屬性值   會調用 self.__setattr__('屬性',屬性值)

對象.屬性 = 屬性值   會調用 self.__setattr__('屬性',屬性值)

只攔截不處理:

# encoding=gbk

class Test:
    def __init__(self,name,age):
        self.__name = name  # self.__setattr__('_Test__name',name)
        self.age = age      # self.__setattr__('age',age)


    def __getattr__(self, item):
        print('in __getattr__:' + item)

    def __setattr__(self, key, value):
        print('in __setattr__:' + key,value)


    def setV(self):
        self.__a1 = 'a1_11'  # self.__setattr__('_Test__a1','a1_11')

print('1:' + '*'*30)
t = Test('ixusy88',18)
print('2:' + '*'*30)
print(t.__dict__)  # 輸出 {}  ,因爲在__setattr__中攔截了所有的屬性賦值,
print('3:' + '*'*30)
t.setV()
print('4:' + '*'*30)
t.aa = '123'    # self.__setattr__('aa','123')
print('5:' + '*'*30)
t.__bb = '123'  # self.__setattr__('__bb','123')
print('6:' + '*'*30)
print(t.vv)  # self.__getattr__('vv')
print('7:' + '*'*30)
print(t.age)  # self.__getattr__('age')  , 在構造函數中雖然有self.age 賦值,但是__getattr__會攔截所有,
print('8:' + '*'*30)
print(t.__dict__)  # 輸出 {}  ,因爲在__setattr__中攔截了所有的屬性賦值,


"""
輸出結果:
1:******************************
in __setattr__:_Test__name ixusy88
in __setattr__:age 18
2:******************************
{}
3:******************************
in __setattr__:_Test__a1 a1_11
4:******************************
in __setattr__:aa 123
5:******************************
in __setattr__:__bb 123
6:******************************
in __getattr__:vv
None
7:******************************
in __getattr__:age
None
8:******************************
{}

"""

正常攔截;

# encoding=gbk

class Test:
    def __init__(self,name,age):
        self.__name = name  # self.__setattr__('_Test__name',name)
        self.age = age      # self.__setattr__('age',age)


    def __getattr__(self, item):
        print('in __getattr__:' + item)
        # raise TypeError('private attribute:' + item)  #  拋出異常


    def __setattr__(self, key, value):
        print('in __setattr__:' + key,value)
        self.__dict__[key] = value


    def setV(self):
        self.__a1 = 'a1_11'  # self.__setattr__('_Test__a1','a1_11')

print('1:' + '*'*30)
t = Test('ixusy88',18)
print('2:' + '*'*30)
print(t.__dict__)  # 輸出 {'_Test__name': 'ixusy88', 'age': 18}
print('3:' + '*'*30)
t.setV()
print('4:' + '*'*30)
t.aa = '123'    # self.__setattr__('aa','123')
print('5:' + '*'*30)
t.__bb = '123'  # self.__setattr__('__bb','123')
print('6:' + '*'*30)
print(t.vv)  # self.__getattr__('vv')
print('7:' + '*'*30)
print(t.age)  # 直接輸出 18,不會調用self.__getattr__('age') ,
print('8:' + '*'*30)
print(t.__dict__)  # 輸出 {'_Test__name': 'ixusy88', 'age': 18, '_Test__a1': 'a1_11', 'aa': '123', '__bb': '123'}


"""
輸出:
1:******************************
in __setattr__:_Test__name ixusy88
in __setattr__:age 18
2:******************************
{'_Test__name': 'ixusy88', 'age': 18}
3:******************************
in __setattr__:_Test__a1 a1_11
4:******************************
in __setattr__:aa 123
5:******************************
in __setattr__:__bb 123
6:******************************
in __getattr__:vv
None
7:******************************
18
8:******************************
{'_Test__name': 'ixusy88', 'age': 18, '_Test__a1': 'a1_11', 'aa': '123', '__bb': '123'}

"""

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章