在Python中创建Getter和Setter
面向对象的编程(OOP)是一种编程范式,它使很多事情变得简单,从可组合性到继承性,使我们能够更快地建立功能和程序部分。这种范式有不同的特点;两个是getters
和setters
。
类是OOP的基础,通常有每个实例所特有的变量,这些变量(通常称为属性)通过方法来设置或获得。这些方法被称为getters
和setters
。
这些行为在支持 OOP 的编程语言中很流行,Python 也支持它。本文将讨论如何在Python中创建一个getter
和setter
。
Python中的Getter和Setter
Getter和Setter是帮助我们设置类变量或属性的方法,不需要直接访问,这违背了抽象和封装的目的。因此,通过getters
和setters
,我们被赋予了处理类属性的能力。
在我们创建getters
和setters
之前,重要的是要知道,与其它编程语言不同,Python 没有隐藏字段,所以你可以通过点符号直接访问类中的变量。
我们可以使用普通函数、property()
函数和@property
装饰器来实现getters
和setters
。
在Python中使用函数来创建Getter和Setter
被称为方法的典型类函数对于创建getters
和setters
是很有用的,我们可以使用self
的概念轻松地设置它们。
对于getter
,方法返回属性,而对于setters
,方法将参数绑定到属性上。为了展示,我们将使用一个Employee
,它持有一个position
属性,getter
方法称为getPosition
,setter
方法称为setPosition
。
class Employee:
def __init__(self) -> None:
self.position = None
def getPosition(self):
return self.position
def setPosition(self, position):
self.position = position
Jacob = Employee()
Jinku = Employee()
Jacob.setPosition("Engineer II")
Jinku.setPosition("Senior Engineer")
print(Jacob.position)
print(Jinku.getPosition())
输出:
Engineer II
Senior Engineer
但是,这种设置或方法并没有什么特别的行为。
在Python中使用property()
函数来创建Getter和Setter
为了获得一些特殊的行为,我们可以利用property()
函数,该函数创建并返回一个属性对象,该对象拥有三个方法:getter()
,setter()
, 和delete()
。
它有助于提供一个实例属性的接口。这个功能允许我们轻松地创建所有的getter
和setter
能力。
为了使用property()
函数,我们需要设置四个参数值,这些参数值是使property()
,一个高阶函数的函数。
getter
,setter
, 和delete
方法是它的参数(都是可选的),并且它返回属性对象。
property(fget, fset, fdel, doc)
让我们在我们的OOP代码中使用property()
函数。
class Employee:
def __init__(self):
self.position = None
def getPosition(self):
return self.position
def setPosition(self, position):
self.position = position
pos = property(getPosition, setPosition)
Jacob = Employee()
Jinku = Employee()
Jacob.position = "Engineer II"
Jinku.position = "Senior Engineer"
print(Jacob.position)
print(Jinku.position)
输出:
Engineer II
Senior Engineer
随着property()
函数的引入,我们有了pos
绑定,它持有属性对象,有助于保持对私有属性的安全访问。
在Python中使用@property
装饰器来创建Getter和Setter
我们可以使用@property
装饰器来实现property()
函数,有了它,就不需要在我们的方法中使用get
和set
的名字。
使用@property
装饰器,我们可以重新使用position
名称,它将定义getter
和setter
函数。
有了@property
,我们创建了getter
,有了@position.setter
,我们创建了setter
,这在代码中添加了print
语句后就很明显了,在输出中可以看到。
class Employee:
def __init__(self):
self.position = None
@property
def position(self):
print("Get Employee Position: ")
return self._position
@position.setter
def position(self, value):
print("Set Position")
self._position = value
Jacob = Employee()
Jinku = Employee()
Jacob.position = "Engineer II"
Jinku.position = "Senior Engineer"
print(Jacob.position)
print(Jinku.position)
输出:
Set Position
Set Position
Set Position
Set Position
Get Employee Position:
Engineer II
Get Employee Position:
Senior Engineer
有四个Set Position
,因为__init__
方法,当类实例被调用时,它设置了初始position
属性,这导致了前两个。当我们为后面两个设置相应的值时,它又会打印出来。
对于getter
,当它获得属性值时,会打印出语句Get Employee Position
,而getter
只被调用两次。因此,这两个语句。
当我们使用setter
方法时,我们可以在我们的OOP代码中添加验证。
class Employee:
def __init__(self):
self.position = None
@property
def position(self):
print("Get Employee Position: ")
return self._position
@position.setter
def position(self, value):
print("Set Position")
if (value != None and len(value) <= 2):
raise ValueError("Position name is less than two and is deemed invalid")
self._position = value
Jacob = Employee()
Jinku = Employee()
Jacob.position = "OS"
Jinku.position = "Senior Engineer"
print(Jacob.position)
print(Jinku.position)
输出:
Set Position
Set Position
Set Position
Traceback (most recent call last):
File "c:UsersakinlDocumentsPythongetterSetter.py", line 20, in <module>
Jacob.position = "OS"
File "c:UsersakinlDocumentsPythongetterSetter.py", line 14, in position
raise ValueError("Position name is less than two and is deemed invalid")
ValueError: Position name is less than two and is deemed invalid