python面向对象-(属性)访问控制

本文介绍Python中私有属性的概念及实现方式,包括如何使用双下划线定义私有属性,以及如何通过属性装饰器实现对属性的访问控制。

访问控制

私有属性(Private)
为什么需要私有属性?
为解决:想通过方法控制属性,但是属性在外部可以访问,可绕过控制方法,直接修改属性。

class Person:
    def __init__(self,name,age=18):
        self.name=name
        self.age=age
    def growup(self,i=1):
        if i>0 and i<150:  #控制逻辑
            self.age+=i

P1=Person('TOM')
print(P1.age)
P1.growup(20) #正常范围
# P1.age=160  #超过正常范围,并绕过控制逻辑
print(P1.age)

私有属性

使用双下划线开头的属性名,就是私有属性,从外部无法访问该属性。

#私有属性
class Person:
    def __init__(self,name,age=18):
        self.name=name
        self.__age=age
    def growup(self,i=1):
        if i>0 and i<150:  #控制逻辑
            self.__age+=i


    def getage(self):    #可新增一个方法获取私有属性
        return self.__age

P1=Person('TOM')
# print(P1.__age)
P1.growup(20) #正常范围
# # P1.age=160  #超过正常范围,并绕过控制逻辑
# print(P1.__age) #访问不到
# P1.__age=58  #无法修改,__age未被覆盖   python解释器已为其改名_类名__变量名
print(P1.getage())
# print(P1.__dict__)

#直接修改私有变量

P1._Person__age=15
print(P1.getage())
print(P1.__dict__)

私有变量的本质:
类定义的时候,如果声明一个实例变量的时候,使用双下划线,python解释器会将其改名,转为:_类名__变量名,之前的名字就访问不到了。
知道私有变量的新名称,就可以直接从外部访问,并可以修改。

保护变量

在变量名前加一个下划线,称为保护变量。
_age属性未改变名称,和普通属性一样,解释器也未作任何特殊处理,只是开发者共同的约定,这种变量,如同私有变量,不要直接使用。

class Person:
    def __init__(self,name,age=18):
        self.name=name
        self._age=age
tom = Person('tom')
print(tom._age)
print(tom.__dict__)

私有方法

参照保护变量、私有变量,使用单、双下划线命名的方法。

#私有方法
class Person:
    def __init__(self,name,age=18):
        self.name=name
        self._age=age

    def _getname(self):
        return self.name

    # def _getage(self):
    #     return self._age

    def __getage(self):
        return self._age


tom = Person("Tom")
print(tom._getname())
# print(tom._getage())
# print(tom.__getage())  #无此属性  改名:_Person__getage
print(tom.__dict__)
print(tom.__class__.__dict__)

# print(tom._Person__getage())
# print(tom.__dict__)

本质:
保护方法:单下划线的方法,只是开发者之间的约定,解释器不做任何改变。
私有方法:双下划线的方法,改名策略与私有变量相同:_类名__方法名
方法变量在类的__dict__中可以找到。
在python中使用单下划线或者双下划线来标识一个成员(即属性)被保护或被私有化隐藏起来。
但不管什么样的访问控制都不可能真正阻止用户修改,下划线只是一种提醒和警告,非必要不要修改被保护的成员。

属性装饰器

通过age和set_age操作属性

#通过age和set_age操作属性
class Person:
    def __init__(self,name,age=18):
        self.name=name
        self.__age=age

    def age(self):     #与set方法结合用,必须先定义读取属性的方法
        return self.__age

    def set_age(self,age):    #set方法设置属性,必须传参,变量名传入
        self.__age=age

tom = Person("Tom")

# print(tom.__age)   #直接读取不到
# print(tom.age())
# print(tom.__dict__)
# tom.__age=20    #私有属性,已改名,无法直接修改属性
# print(tom.age())
# print(tom.__dict__)
tom.set_age(20)
print(tom.age())
print(tom.__dict__)

使用属性装饰器@property
@property装饰器能通过简单的方式,把方法的操作变为对属性的访问,并起到一定的隐藏效果

class Person:
    def __init__(self,name,age=18):
        self.name=name
        self.__age=age

    @property       #读取属性的方法
    def age(self):
        return self.__age

    @age.setter
    def age(self,age):    #set方法设置属性,必须传参,变量名传入
        self.__age=age

    @age.deleter
    def age(self):
        # del self.__age
        print("del")


tom = Person("Tom")
print(tom.age)
print(tom.__dict__)
tom.age = 20
print(tom.age)
print(tom.__dict__)
#del tom.age

注意:
使用@property装饰器时,三个方法要同名
@property装饰器:后面跟的函数名就是之后的属性名。它就是getter,必须要有的方法,只读属性
@setter装饰器:与属性名同名,且接收两个参数,第一个self,第二个是将要赋值的值,可写属性
@deleter装饰器:可以控制是否删除属性,很少用

@property装饰器必须在前,@setter、@deleter在后

#简单写法
# class Person:
#     def __init__(self,name,age=18):
#         self.name=name
#         self.__age=age
#
#     def getage(self):
#         return self.__age
#
#     def setage(self,age):
#         self.__age=age
#
#     def delage(self):
#         del self.__age
#
#     age=property(getage,setage,delage,'age property')
#
# tom = Person("Tom")
#
# print(tom.__dict__)
# print(tom.getage())
# print(tom.age)
# tom.age=20
# print(tom.age)
# print(tom.__dict__)
## tom.setage(30)
# print(tom.age)
# print(tom.__dict__)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值