封装、property装饰器

一、封装
封装是指隐藏对象中一些不希望被外部所访问到的属性或方法。(我个人理解其具体的隐藏方法或者思路,实际上就是在定义属性名的时候,属性名不要取的太常规)

出现封装的原因:我们需要一种方式来增强数据的安全性
• 1. 属性不能随意修改
• 2. 属性不能改为任意的值
比如:

class Car():

	def __init__(self,name,color):
		self.name=name
		self.color=color

	def run(self):
		print(self.name,'汽车开动了')

car1=Car('法拉利','红色')
car1.run()
car1.name='兰博基尼'
car1.run()

car1.name='中华田园犬'
car1.run()

结果:
在这里插入图片描述
中华田园犬 和汽车开动了,明显是不合适的,所以我们就不想要car1的name属性被轻易的修改。
为了防止数据被更改,我们引入封装,以告诉协同开发者,某个属性很重要,不要轻易修改。
由此:

class Car():

	def __init__(self,name,color):
		self._name=name   #这个‘_’就告诉别人,这是个私有属性,不要轻易修改
		self.color=color

	def run(self):
		print(self._name,'汽车开动了')

car1=Car('法拉利','红色')
car1.run()


car1.name='中华田园犬'#也能顺利运行,没有报错,这相当于创建了一个新的属性
car1.run()
print(car1.name)

结果:
在这里插入图片描述
这样就修改不了了。
但实际上,想要修改也可以。所以说“防君子,不防小人”
如下:

class Car():

	def __init__(self,name,color):
		self._name=name   #这个—就告诉别人,这是个私有属性,不要轻易修改
		self.color=color

	def run(self):
		print(self._name,'汽车开动了')

car1=Car('法拉利','红色')
car1.run()


car1.name='中华田园犬'#也能顺利运行,没有报错,这相当于创建了一个新的属性
car1.run()
print(car1.name)

car1._name='中华田园犬'
car1.run()

结果:
在这里插入图片描述
1、完全封装(隐藏属性):即用__name(双下划线后属性名)来定义属性。

class Car():

	def __init__(self,name,color):
		self.__name=name
		self.color=color

	def run(self):
		print(self.__name,'汽车开动了')


car1=Car('法拉利','红色')
car1.run()

结果:
在这里插入图片描述
完全封装时,若要访问到该属性,用print(car1.__name)将报错报错’Car’ object has no attribute ‘__name’

在这里插入图片描述
因为双下划线开头的属性,是对象的隐藏属性,隐藏属性只能在类的内部访问,无法通过对象访问
其实隐藏属性只不过是Python自动为属性改了一个名字: _类名__属性名
如下访问隐藏属性:

class Car():

	def __init__(self,name,color):
		self.__name=name
		self.color=color

	def run(self):
		print(self.__name,'汽车开动了')


car1=Car('法拉利','红色')
car1.run()

print(car1._Car__name)#完全封装时调用属性的方法(实例对象._类名__属性名)

结果:
在这里插入图片描述
2、getter和setter方法
getter方法用来查看私有属性,实际上就是在类的内部定义一个函数来访问私有属性。
setter方法用来修改私有属性。
如果只有一个getter方法而没有setter方法,那这个属性是一个只读属性。

class Car():

	def __init__(self,name,color):
		self.__name=name
		self.__color=color

	def run(self):
		print(self.__name,'汽车开动了')

	def get_name(self):
		return self.__name

	def set_name(self,name):
		self.__name=name 

car1=Car('法拉利','红色')
car1.run()

print(car1.get_name())

print(car1.set_name('宝马'))
print(car1.get_name())

结果:
在这里插入图片描述
二、property装饰器
我们可以使用@property装饰器来创建只读属性,@property装饰器会将方法转换为相同名称的只读属性,可以与所定义的属性配合使用,这样可以防止属性被修改。

class Person():
	def __init__(self,name):
		self._name=name

	def name(self):
		print('name方法执行了')
		return self._name
	
p1=Person('邱淑贞')
print(p1.name())

结果:
在这里插入图片描述
用@property装饰器的代码为:

class Person():
	def __init__(self,name):
		self._name=name

	@property
	def name(self):
		print('name方法执行了')
		return self._name
	
p1=Person('邱淑贞')
print(p1.name)

和前一段代码的不同之处是: @property 以及最后一行。
结果:
在这里插入图片描述
效果和前一段代码的效果一样。@property装饰器将后面的name方法转换成了name属性。
而当我们要修改这个name属性时:
在这里插入图片描述
报错:AttributeError: can’t set attribute(无法设置属性)

又当我们调用@property装饰器后面的name方法时:
在这里插入图片描述
报错:TypeError: ‘str’ object is not callable('str’对象是不可调用的)
也就是说@property装饰器保护了name方法(属性)不被(调用)修改。

那我们要如何yoga装饰器来修改name属性呢?如下:

class Person():
	def __init__(self,name):
		self._name=name

	@property
	def name(self):
		print('get方法执行了')
		return self._name

	@name.setter
	def name(self,name):
		print('set方法执行了')
		self._name=name
		
p1=Person('邱淑贞')
print(p1.name)
p1.name='刘亦菲'
print(p1.name)

结果:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值