在Python中创建Getter和Setter

面向对象的编程(OOP)是一种编程范式,它使很多事情变得简单,从可组合性到继承性,使我们能够更快地建立功能和程序部分。这种范式有不同的特点;两个是getterssetters

类是OOP的基础,通常有每个实例所特有的变量,这些变量(通常称为属性)通过方法来设置或获得。这些方法被称为getterssetters

这些行为在支持 OOP 的编程语言中很流行,Python 也支持它。本文将讨论如何在Python中创建一个gettersetter

Python中的Getter和Setter

Getter和Setter是帮助我们设置类变量或属性的方法,不需要直接访问,这违背了抽象和封装的目的。因此,通过getterssetters ,我们被赋予了处理类属性的能力。

在我们创建getterssetters 之前,重要的是要知道,与其它编程语言不同,Python 没有隐藏字段,所以你可以通过点符号直接访问类中的变量。

我们可以使用普通函数、property() 函数和@property 装饰器来实现getterssetters

在Python中使用函数来创建Getter和Setter

被称为方法的典型类函数对于创建getterssetters 是很有用的,我们可以使用self 的概念轻松地设置它们。

对于getter ,方法返回属性,而对于setters ,方法将参数绑定到属性上。为了展示,我们将使用一个Employee ,它持有一个position 属性,getter 方法称为getPositionsetter 方法称为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()

它有助于提供一个实例属性的接口。这个功能允许我们轻松地创建所有的gettersetter 能力。

为了使用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() 函数,有了它,就不需要在我们的方法中使用getset 的名字。

使用@property 装饰器,我们可以重新使用position 名称,它将定义gettersetter 函数。

有了@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