目录
1. getter、setter等访问器方法
1)为什么使用getter、setter访问器方法
在学习什么是setter、getter等访问器方法时,我们先来看一段代码:
# 定义一个矩形类
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
# 创建一个对象
my_rectangle = Rectangle(10, 5)
print(my_rectangle.width, my_rectangle.height) # 10 5
my_rectangle.width = 15
print(my_rectangle.width, my_rectangle.height) # 15 5
对于定义的Rectangle类,我们创建对象时都会调用__init__函数,此函数为对象定义了两个实例变量;
对象可以随意读出和修改这两个实例变量,这不符合面向对象编程的三大特征中的“封装”特征(将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法实现对内部信息的操作和访问)。
但是,由于Python没有提供类似于其他语言的private等修饰符,Python并不能将实例变量真正隐藏起来,所以尽管还是要通过定义方法去访问实例变量,但外部程序依然可以直接访问实例变量;
所以,这就是我们使用setter、getter访问方法的主要原因。除此之外,我们可以在这些方法中加入控制逻辑,限制对属性的不合理访问。
2)怎么写setter、getter方法
setter方法用于设置实例变量的值,getter方法用于获取实例变量的值;
# 定义一个矩形类
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def setSize(self,size):
self.width, self.height = size
def getSize(self):
return self.width, self.height
# 创建一个对象
my_rectangle = Rectangle(10, 5)
print(my_rectangle.getSize()) # (10, 5)
my_rectangle.setSize((20, 10))
print(my_rectangle.getSize()) # (20, 10)
2. 使用property函数定义属性
类中定义了getter、setter等访问器方法后,可以使用property()函数将它们定义为属性;
property()函数语法格式:
property(fget=None, fset=None, fdel=None, doc=None)
fget
function to be used for getting an attribute value 获取属性值
fset
function to be used for setting an attribute value
fdel
function to be used for del'ing an attribute
doc
docstring
使用property()函数时可以传入四个参数,分别代表getter方法、setter方法、del方法(删除参数,不是删除参数值)和doc(一个文档字符串,用于说明该属性);也可以根据个人所需传入1个参数(只可以读)、2个参数(可读可写)、3个参数(可读可写可删除);
Python官方介绍该函数的用法如下:
Typical use is to define a managed attribute x:
class C(object):
def getx(self): return self._x
def setx(self, value): self._x = value
def delx(self): del self._x
x = property(getx, setx, delx, "I'm the 'x' property.")
# 定义一个矩形类
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def setSize(self,size):
self.width, self.height = size
def getSize(self):
return self.width, self.height
def delSize(self):
del self.width, self.height
size=property(getSize, setSize, delSize, "可读可写可删除")
# 访问属性size的doc说明文档,注意要通过类来访问,不能通过对象来访问
print(Rectangle.size.__doc__) # 可读可写可删除
# 创建一个对象
my_rectangle = Rectangle(10, 5)
# 访问参数值可以使用定义的属性size
# 读取参数值
print(my_rectangle.size) # (10, 5)
# 修改参数值
my_rectangle.size = 20, 10
print(my_rectangle.size) # (20, 10)
# 删除参数
del my_rectangle.size
print(my_rectangle.height)
# 程序将报错,AttributeError: 'Rectangle' object has no attribute 'height'
3. 使用@property装饰器修饰方法,使其成为属性
python官方解释文档:
class C(object):
# 使用@property修饰方法,使得该方法变成x属性的getter方法
@property
def x(self):
"I am the 'x' property."
return self._x
# 为x属性设置setter方法
@x.setter
def x(self, value):
self._x = value
# 为x属性设置deleter方法
@x.deleter
def x(self):
del self._x
# 定义一个矩形类
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
@property
def size(self):
return self.width, self.height
@size.setter
def size(self, size):
self.width, self.height = size
@size.deleter
def size(self):
del self.width, self.height
# 创建一个对象
my_rectangle = Rectangle(10, 5)
print(my_rectangle.size) # (10, 5)
my_rectangle.size = 20, 10
print(my_rectangle.size) # (20, 10)
del my_rectangle.size
print(my_rectangle.width)
# 程序报错 AttributeError: 'Rectangle' object has no attribute 'width'