Python中的 Getter 和 Setter
在Python中,getter 和 setter 与其他面向对象编程语言中的不同。基本上,在面向对象程序中使用 getter 和 setter 的主要目的是确保数据封装。 Python中的私有变量实际上并不是其他面向对象语言中的隐藏字段。 Python中的 Getter 和 Setter 常用于以下情况:
- 我们使用 getter 和 setter 来围绕获取和设置值添加验证逻辑。
- 为了避免直接访问类字段,即私有变量不能被外部用户直接访问或修改。
使用普通函数实现 getter 和 setter 行为
为了实现 getters & setters 属性,如果我们定义普通的get()
和set()
方法,它不会反映任何特殊的实现。例如
# Python program showing a use
# of get() and set() method in
# normal function
class Geek:
def __init__(self, age = 0):
self._age = age
# getter method
def get_age(self):
return self._age
# setter method
def set_age(self, x):
self._age = x
raj = Geek()
# setting the age using setter
raj.set_age(21)
# retrieving age using getter
print(raj.get_age())
print(raj._age)
输出:
21
21
在上面的代码中,函数get_age()
和set_age()
充当普通函数,不会像 getter 和 setter 那样产生任何影响,为了实现这样的功能, Python有一个特殊的函数property()
。
使用 property()函数实现 getter 和 setter 行为
在Python中, property()
是一个内置函数,它创建并返回一个属性对象。属性对象具有三个方法,getter()、setter() 和 delete()。 Python中的property()
函数有四个参数property(fget, fset, fdel, doc)
, fget
是一个用于检索属性值的函数。 fset
是用于设置属性值的函数。 fdel
是删除属性值的函数。 doc
为属性创建一个文档字符串。属性对象具有三个方法, getter()
、 setter()
和delete()
,分别指定fget
、 fset
和fdel
。例如
# Python program showing a
# use of property() function
class Geeks:
def __init__(self):
self._age = 0
# function to get value of _age
def get_age(self):
print("getter method called")
return self._age
# function to set value of _age
def set_age(self, a):
print("setter method called")
self._age = a
# function to delete _age attribute
def del_age(self):
del self._age
age = property(get_age, set_age, del_age)
mark = Geeks()
mark.age = 10
print(mark.age)
setter method called
getter method called
10
在上面的代码中, line #25
只有一个打印语句,但由于在line #23
调用了 setter 方法set_age()
和在line #25
调用了 getter 方法get_age()
,因此输出由三行组成。因此, age
是一个属性对象,有助于保持私有变量的访问安全。
使用 @property 装饰器来实现 getter 和 setter 行为
在之前的方法中,我们使用property()
函数来实现 getter 和 setter 行为。然而,正如本文前面提到的,getter 和 setter 也用于验证属性值的获取和设置。还有另一种实现属性函数的方法,即使用装饰器。 Python @property 是内置装饰器之一。任何装饰器的主要目的都是以这样一种方式更改您的类方法或属性,以便您的类的用户无需对其代码进行任何更改。例如
# Python program showing the use of
# @property
class Geeks:
def __init__(self):
self._age = 0
# using property decorator
# a getter function
@property
def age(self):
print("getter method called")
return self._age
# a setter function
@age.setter
def age(self, a):
if(a < 18):
raise ValueError("Sorry you age is below eligibility criteria")
print("setter method called")
self._age = a
mark = Geeks()
mark.age = 19
print(mark.age)
输出:
setter method called
getter method called
19
在上面的代码中,很清楚如何使用@property
装饰器以pythonic 方式创建getter 和setter。 Line 15-16
充当验证代码,如果我们尝试使用小于 18 的值初始化年龄,则会引发ValueError
,这样任何类型的验证都可以应用于 getter 或 setter 函数。