面向对象之封装
【一】封装
【1】第一层面的封装
- 第一层面的封装:类就像是一个袋子,把各种数据和属性撞到这个类里面,这就是封装
第一阶段:
# 如果我们要定义学生green如何定义?
name = 'green'
age = 22
sex = '男'
我们当然可以用这三个变量去形容green这个人
但是弊端也很明显---->太零散,如果学生很多,就需要很多变量去描述
为了解决这个问题,所以出现了类这个概念
第二阶段:
class Student(object):
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
one = Student('green',22,'男') # 这里的one就相当于一个学生jack,所有的属性都封装到了one变量中。这里的Student类,相当于一个模板。只要给定它name,age,sex,它就能创建出一个学生对象。
two = Student('aaa',16,'男')
three = Student('bbb',15,'女')
four = Student('ccc',14,'男')
five = Student('ddd',13,'女')
print(f'姓名:{one.name} 年龄:{one.age} 性别:{one.sex}')
- 到此,我已经是感受到了使用类封装的便利了
【2】第二层面的封装
-
类中定义私有的属性和方法只有类内部能有使用
-
通过在属性或方法前面加上
__
对其进行封装 -
这样子的好处可以加强数据的安全性
第一阶段
class Student:
def __init__(self, name, sex, age):
self.__name = name
self.__sex = sex
self.age = age
student_one = Student(name='green', sex='man', age=22)
print(student_one.name) # AttributeError: 'Student' object has no attribute 'name'
print(student_one.sex) # AttributeError: 'Student' object has no attribute 'sex'
print(student_one.age) # 22
# 可以发现在类外部无法调用 类内部__封装的属性
- 如果想要调用封装起来的数据,就只能通过在类内部开设一个接口的方法来调用
第二阶段
class Student:
def __init__(self, name, sex, age):
self.__name = name
self.__sex = sex
self.age = age
def show_info(self):
print(f'姓名:>>>>{self.__name}\n性别:>>>>{self.__sex}\n年龄:>>>>{self.age}')
student_one = Student(name='green', sex='man', age=22)
student_one.show_info()
'''
姓名:>>>>green
性别:>>>>man
年龄:>>>>22
'''
# 在类的内部通过show_info方法调用封装起来的数据
# 在类的外部就可以调用show_info这个没有被加密封装起来的方法
# 从而达到可以调用封装起来的数据的效果
【3】property
装饰器
property
装饰器是 Python 中一种用于创建只读属性的装饰器。其基本用法是将一个方法转换成属性的形式来访问。这对于实现封装和保护类的内部状态非常有用,同时也允许类的使用者以直观的方式获取属性值,而无需调用一个方法。
class Student:
def __init__(self, name, sex, age):
self.__name = name
self.__sex = sex
self.age = age
def show_info(self):
print(f'姓名:>>>>{self.__name}\n性别:>>>>{self.__sex}\n年龄:>>>>{self.age}')
@property
def name(self):
return self.__name
@name.setter
def name(self, name):
if len(name) > 3:
self.__name = name
else:
print('名字太奇怪了!')
student_one = Student(name='green', sex='man', age=22)
student_one.name = '1'
print(student_one.name) # green
'''
名字太奇怪了!
green
'''
总结:
- 使用 @property 装饰器时,接口名不必与属性名相同.
- 凡是赋值语句,就会触发set方法。
- @property会把函数属性伪装成数据属性