python中的property属性

1. 什么是property属性

在Python中,property是一种特殊的装饰器,可以将类中的方法像属性一样使用。它可以将一个方法转换为类的一个属性,当属性被调用时,该方法会自动执行,返回值就是该属性的值。

在Python的面向对象编程中,使用property属性与直接定义属性相比,可以更加灵活地控制属性的赋值和取值。通过property属性,我们可以设置属性的只读、只写、可读可写等权限,以及进行数据的类型检查和限制,确保属性值的有效性。

2. 创建property属性

要创建property属性,我们需要使用Python自带的property装饰器。在使用property装饰器之前,我们先来看一个案例,了解为什么需要使用property。

2.1 案例:不使用property的情况

class Circle:

def __init__(self, radius):

self.radius = radius

def area(self):

return 3.14 * self.radius ** 2

c = Circle(5)

print(c.radius) # 5

print(c.area()) # 78.5

在上面的代码中,我们创建了一个圆形对象,该对象的属性为半径,方法为计算圆形的面积。我们可以通过直接访问半径属性,并调用area方法计算面积。

但是,如果我们希望修改该圆形对象的半径,我们只能通过直接修改半径属性的方式实现:

c.radius = 10

print(c.radius) # 10

print(c.area()) # 314.0

虽然这种方式看起来简单,但是存在如下问题:

属性没有被有效的封装

可能会有人不知道该如何修改属性

属性修改时无法进行数据的有效性检查和限制

接下来,我们将使用property属性重新定义Circle类:

2.2 使用property的情况

class Circle:

def __init__(self, radius):

self._radius = radius

@property

def radius(self):

return self._radius

@radius.setter

def radius(self, value):

if value <= 0:

raise ValueError('半径必须大于0')

else:

self._radius = value

def area(self):

return 3.14 * self.radius ** 2

c = Circle(5)

print(c.radius) # 5

print(c.area()) # 78.5

c.radius = 10

print(c.radius) # 10

print(c.area()) # 314.0

在上面的代码中,我们通过使用@property装饰器,将radius方法转换为属性,可以像直接访问属性一样访问和修改半径属性。

同时,我们还定义了一个setter方法,确保半径属性的有效性。当半径值小于等于0时,程序将抛出一个ValueError异常。

3. property属性的应用场景

property属性常用于以下场景:

3.1 控制属性的只读或只写权限

class Student:

def __init__(self, name, age):

self._name = name

self._age = age

@property

def name(self):

return self._name

@property

def age(self):

return self._age

s = Student('小明', 18)

print(s.name) # 小明

# 下面这行代码会抛出AttributeError异常

# s.name = '张三'

在上面的代码中,我们使用@property装饰器,将name和age方法转换为只读属性,修改属性将抛出AttributeError异常。

3.2 控制属性的读写权限

class Rectangle:

def __init__(self, width, height):

self._width = width

self._height = height

@property

def width(self):

return self._width

@width.setter

def width(self, value):

self._width = value

@property

def height(self):

return self._height

@height.setter

def heigh(self, value):

self._height = value

r = Rectangle(10, 20)

print(r.width) # 10

# 可以修改width属性

r.width = 30

print(r.width) # 30

# 下面这行代码会抛出异常

# r.height = 30

在上面的代码中,我们使用@property装饰器,将width和height方法转换为可读可写属性,read-write属性。

同时,我们还定义了setter方法,确保属性值的有效性。

3.3 控制属性的类型

class Dog:

def __init__(self, name, age):

self._name = name

self._age = age

@property

def name(self):

return self._name

@property

def age(self):

return self._age

@age.setter

def age(self, value):

if isinstance(value, int) and value >= 0:

self._age = value

else:

raise ValueError('年龄必须为非负整数')

d = Dog('旺财', 2)

print(d.age) # 2

# 下面这行代码会抛出ValueError异常

# d.age = -1

在上面的代码中,我们通过定义setter方法,控制了age属性的类型和范围,确保属性值的有效性。

4. 总结

在Python中,使用property属性可以将类中的方法像属性一样使用。它可以将一个方法转换为类的一个属性,当属性被调用时,该方法会自动执行,返回值就是该属性的值。

通过property属性,我们可以更加灵活地控制属性的赋值和取值。通过setter方法,我们可以对属性值进行有效性检查和限制,确保属性值的有效性。

最后,通过合理的使用property属性,可以使我们的面向对象程序更加健壮和易于维护。

后端开发标签