面向对象——访问限制

一、私有属性和私有方法

在很多面向对象编程中,属性可以设置为私有属性,python中也是如此,但是python跟其他编程语言不同在于python并不从语法上严格保证私有属性的私密性,也就是说,虽然在python中设置了私有属性,但是实际上python只是对这个私有属性重新命名,在类的外部通过重命名后的变量名字任可访问到该私有属性。因此在python中针对私有属性的访问问题,程序员们会有一个共识——不要随便访问私有属性,访问对象属性统一通过对象方法去执行。python类中设置私有属性只需要在属性名字前加双下划线即可。

class Student:
	def __init__(self,name,age):
		self.__name=name
		self.__age=age

s1=Student('z7sz',20)
print(s1.__name)   #这一行会报错,__name是私有属性,无法在外部直接访问
print(s1._Student__name)  #这一行不会报错并且可以得到属性值,但是最好不要这么做

python中的私有方法跟私有属性是一样的。

class Student:
	def __init__(self,name,age):
		self.__name=name
		self.__age=age

	def __get(self):
		return f'{self.__name}:{self.__age}'
	
	def get(self):
		return self.__get()
    
print(s1.get())
print(s1._Student__get())

上面两行print都能执行成功,但是第二种方式最好不要这么做。

二、property装饰器

前面说了因为私有属性的缘故,使得我们不能够像访问属性的方式来获取值,也不能像直接给私有属性赋值,因此我们通常都会另外写获取和赋值的函数来代替直接通过对象.属性名的方式来操作属性。但是这样毕竟没有直接通过对象.属性名方便,因此property装饰器负责把一个方法变成属性调用,这样就使得我们从对象.方法名()的方式变成对象.属性名的方式来操作属性。

class Student:
    def __init__(self,name):
        self.__name=name
    def get_name(self):
        return self.__name
    
    def set_name(self,name):
        if not isinstance(name,str):  #name必须为字符串
            raise ValueError('name must be an str!')
        self.__name=name

s=Student('z7sz')
s.set_name('z7sz1')
print(s.get_name())

上面这种方式是不通过装饰器,通过方法来访问数据的方式

class Student_p:
    def __init__(self,name):
        self.__name=name
    
    @property
    def name(self):
        return self.__name
    
    @name.setter
    def name(self,name):
        if not isinstance(name,str):  #name必须为字符串
            raise ValueError('name must be an str!')
        self.__name=name

s1=Student_p('blog')
print(s1.name)  #直接通过'对象.属性'访问数据
s1.name='blog1'  #直接赋值
print(s1.name)

@property涉及到两个方面,本身可以将getter方法变成属性,也就是读取的方法,@property本身又创建了另一个装饰器@xxx.setter,负责把一个setter方法变成属性赋值。所以在上面的代码中@property装饰器可以直接读取数据,@name.setter可以赋值。

而且通过该装饰器还可以实现某属性只读不写的功能,只写@property装饰器不写@name.setter则可以实现name属性的只读不写。

装饰器会在后面详细讲,在面向对象内容的装饰器大家可以先记得怎么用。

三、__slots__ 魔法变量

上面的私有属性+装饰器实现了类中私有属性不能随便被读写,但是外部可以随意像类中写入属性。因此__slots__变量,可以用来限制class实例能添加的属性。

class A:
    __slots__=('name','age') #实例只能添加这两个属性

a=A()
a.name='zsz'
a.age=14
a.sex=1  #这里会报错,因为A不允许实例添加除name和age之外的属性

我的博客:https://blog.z7sz.top

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xingyuzhongxuan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值