4.1 访问限制
在之前的专栏:Python基础
中,笔者在面向对象
编程中介绍了类、对象的属性,按照属性的访问程度可以分为一般属性和私有属性。
通常,在类、对象中,如果一个属性名以__
开头,则代表这个属性是私有属性,正常情况下是不可以在外部直接调用或修改该属性的。通过将属性设置成私有属性就是访问限制
。
访问限制是为了程序的健壮性,使得无法直接在外部修改某些特定的属性,保证了程序的正常运行。
举个例子,如果某个类中有个属性是用来存放年龄的,而有个方法需要用到这个年龄属性,并且是将这个年龄作为了除数,如果不小心设置或者输入年龄为0,那么就会导致程序出错。
对于某些比较重要的属性,我们如果想要用户能够获取到或者修改,则可以通过自定义方法实现,比如:getage、setage。通过方法设置属性可以进行参数检查,避免传入错误或无效的参数。
定义私有变量
class Person:def __init__(self):self.name = 'lucy'self.__age = 10p = Person()
ic(p.name)
ic(p.__age)
17:09:42|> p.name: ‘lucy’
Traceback (most recent call last):
File “E:\t1.py”, line 12, in
ic(p.__age)
AttributeError: ‘Person’ object has no attribute ‘__age’
我们可以看到,可以在外部直接获取到属性name
,但是无法获取到属性__age
。
通过方法获取属性
from icecream import icclass Person:def __init__(self):self.name = 'lucy'self.__age = 10def getage(self):return self.__agep = Person()
ic(p.getage())
17:28:25|> p.getage(): 10
通过方法修改属性
from icecream import icclass Person:def __init__(self):self.name = 'lucy'self.__age = 10def getage(self):return self.__agedef setage(self, age):if isinstance(age, int) and 0 < age < 150:self.__age = ageelse:ic('输出的年龄有误,请核对!')p = Person()
p.setage(20)
ic(p.getage())
p.setage(200)
ic(p.getage())
18:03:42|> p.getage(): 20
18:03:42|> ‘输出的年龄有误,请核对!’
18:03:42|> p.getage(): 20
4.1.2 封装
在python中,封装是一种代码组织技术,可用于将数据和关联的方法(函数)作为一个单元进行管理。可以通过在类中定义公共方法来控制对类成员变量的访问,并保护它们免受不必要的修改。
封装有以下作用:
- 将数据与相关行为捆绑在一起,以方便管理和维护代码。
- 隐藏具体实现细节,使得代码更加安全和抽象化。
- 通过只暴露有限的接口来减少代码的复杂度,提高代码的可读性和可维护性。
- 改进了软件模块之间的互操作性和协作能力,使得软件更加可扩展和灵活。
在python中,可以使用特殊的命名约定来模拟私有成员。我们可以在名称前加上双下划线"__",这样就可以防止其他人意外地访问到该成员,并且只能通过类中定义的公共方法来访问。
class Car:# 定义类私有变量__max_speed = 0__mileage = 0def __init__(self):# 初始化变量self.__max_speed = 200self.__mileage = 10# 定义公共方法def drive(self):print('Driving. Max speed:', self.__max_speed)# 定义getter和setter方法def get_max_speed(self):return self.__max_speeddef set_max_speed(self, speed):self.__max_speed = speedcar = Car()
print(car.get_max_speed()) # 输出200
car.set_max_speed(250)
car.drive() # Driving. Max speed: 250
在上面的代码中,Car 类定义了两个私有变量 __max_speed 和 __mileage,这些变量只能在类的内部使用。然后,我们定义了一个公共方法 drive(),它可以在类的外部访问,并且使用getter和setter方法来管理变量 __max_speed 的值。这样,我们就可以通过类的公共接口访问其数据和方法,而不需要直接访问其私有变量。