在 Python 中创建 Getter 和 Setter

面向对象编程(OOP)是一种编程范式,它使很多事情变得容易,从可组合性到继承,并允许我们更快地构建功能和程序部件。 这个范式有不同的特点; 两个是 getter 和 setter。

类是 OOP 的基础,通常具有每个实例唯一的变量,并且这些变量(通常称为属性)通过方法设置或获取。 这些方法称为 getter 和 setter。

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


Python 中的 Getter 和 Setter

Getters 和 Setters 是帮助我们设置类变量或属性而无需直接访问的方法,违背了抽象和封装的目的。 因此,通过 getter 和 setter,我们就能够处理类属性。

在我们创建 getter 和 setter 之前,重要的是要知道,与其他编程语言不同,Python 没有隐藏字段,因此您可以通过点表示法直接访问类中的变量。

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


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

称为方法的典型类函数对于创建 getter 和 setter 非常有用,我们可以使用 self 概念轻松地设置它们。

该方法为 getter 返回属性,对于 setter,该方法将参数绑定到属性。 为了进行演示,我们将使用一个拥有位置属性的 Employee、名为 getPosition 的 getter 方法和名为 setPosition 的 setter 方法。

python 复制代码
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())

输出:

bash 复制代码
Engineer II
Senior Engineer

但是,这种设置或方法没有太多特殊行为。


在Python中使用property()函数创建Getter和Setter

为了获得一些特殊的行为,我们可以使用 property() 函数来创建并返回一个属性对象,该对象包含三个方法:getter() 、setter() 和 delete()。

它有助于提供实例属性的接口。 此功能使我们能够轻松创建所有 getter 和 setter 功能。

要使用 property() 函数,我们需要设置四个参数值,它们是使 property() 成为高阶函数的函数。

getter、setter 和 delete 方法是它的参数(都是可选的),并且它返回属性对象。

python 复制代码
property(fget, fset, fdel, doc)

让我们在 OOP 代码中使用 property() 函数。

python 复制代码
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)

输出:

bash 复制代码
Engineer II
Senior Engineer

随着 property() 函数的引入,我们有了 pos 绑定,它保存属性对象,有助于保持对私有属性的安全访问。


使用@property装饰器在Python中创建Getter和Setter

我们可以使用 @property 装饰器来实现 property() 函数,这样就不需要在我们的方法中使用 get 和 set 名称了。

使用 @property 装饰器,我们可以重用定义 getter 和 setter 函数的位置名称。

使用 @property,我们创建 getter,使用 @position.setter,我们创建 setter,这通过添加到代码中并在输出中可见的 print 语句显而易见。

python 复制代码
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)

输出:

bash 复制代码
Set Position
Set Position
Set Position
Set Position
Get Employee Position:
Engineer II
Get Employee Position:
Senior Engineer

Set Position 有四种,因为 __init__ 方法在调用类实例时设置了初始位置属性,从而导致了前两种。 当我们将值设置为接下来两个的相应值时,它会再次打印。

对于getter,它在获取属性值时打印语句Get Employee Position,并且getter只被调用两次。 于是就有了这两种说法。

当我们使用 setter 方法时,我们可以向 OOP 代码添加验证。

python 复制代码
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)

输出:

bash 复制代码
Set Position
Set Position
Set Position
Traceback (most recent call last):
  File "c:\Users\akinl\Documents\Python\getterSetter.py", line 20, in <module>
    Jacob.position = "OS"
  File "c:\Users\akinl\Documents\Python\getterSetter.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
相关推荐
默_笙5 天前
🍙 给每个请求过安检:FastAPI 是怎么把校验写进类型注解的
python
小羊没烦恼!5 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
qq_426003965 天前
启动playwright录制codegen生成自动化测试脚本
python·自动化
虎头金猫5 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
长沙三为智能科技5 天前
家政小程序开发从0到上线:五阶段交付流程与验收清单
python
大蓝头5 天前
安装包UI美化之路-nsNiuniuSkin全新UI调试与预览方法
ui·electron·安装包·截图控件·截屏控件
伞伞悦读5 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
只睡四小时5 天前
Canvas 弹道联机实战:700 行 + 固定时间步长
python·websocket·html5·游戏开发·canvas
C语言小火车5 天前
C/C++ 为什么需要编译器?
开发语言·c++
奇思妙想聪明勤奋的小羊5 天前
DeepAgents第5章:子Agent 与上下文隔离—让 Agent学会委派
人工智能·python·学习·语言模型