您当前的位置:首页 > IT编程 > python
| C语言 | Java | VB | VC | python | Android | TensorFlow | C++ | oracle | 学术与代码 | cnn卷积神经网络 | gnn | 图像修复 | Keras | 数据集 | Neo4j | 自然语言处理 | 深度学习 | 医学CAD | 医学影像 | 超参数 | pointnet | pytorch | 异常检测 | Transformers | 情感分类 | 知识图谱 |

自学教程:python使用property完成数据隐藏封装与校验

51自学网 2025-02-05 12:14:37
  python
这篇教程python使用property完成数据隐藏封装与校验写得很实用,希望能帮到您。

禁止随意设置属性

需求

考虑这样一种情况,在某一个类中,有一个属性我们不希望别人随便设置,因为这可能会造成很大的麻烦:

class Rectangle:    def __init__(self, width, height):        self.width = width        self.height = height        def calculate_area(self):        return self.width * self.height  r = Rectangle(3, 4)print(r.calculate_area())

在这种情况下,长度和宽度都应该是数字类型的,而如果有人在这个过程中修改了这个属性,那么就会导致错误。

r = Rectangle(3, 4)r.width = "3"print(r.calculate_area())  # 结果为3333,明显不是我们希望的结果

私有属性

为了避免他人随意访问,我们可以将其设置为私有属性,通常可以添加1个或者2个下划线。

class Rectangle:    def __init__(self, width, height):        # 一个下划线通常表明了,这个属性不应该随意使用,但是不起实际作用        self._width = width                # 两个下划线表明了,这个属性会触发名称重整,但是也并非真正的私有        self.__height = height                r = Rectangle(3, 4)print(r._width) # 双下划线最终会重整为_类名__属性名的形式print(r._Rectangle__height)

需要注意的是,由于python中没有真正的私有属性,所以,这两种设置方法都不能完全起到作用,但是一般而言,两个下划线是更好的,因为可以触发名称重整。

提供访问方法

在这种情况下,为了避免他人随意设置属性,因此需要提供专门的访问方法。

class Rectangle:    def __init__(self, width, height):        self.set_width(width)        self.set_height(height)     def set_width(self, width):        if not isinstance(width, (int, float)):            raise ValueError("width must be a number.")        if width <= 0:            raise ValueError("width must be greater than 0.")        self.__width = width     def set_height(self, height):        if not isinstance(height, (int, float)):            raise ValueError("height must be a number.")        if height <= 0:            raise ValueError("height must be greater than 0.")        self.__height = height     def get_width(self):        return self.__width     def get_height(self):        return self.__height r = Rectangle(3, 4) # 此时需要通过专门的方法进行访问print(r.get_width()) # 非法的设置不再被允许r.set_width("3")

但是这样的使用方法并不方便,因此,在python中,一个更好的使用方法是通过property。

property的详细介绍

基本语法

基本语法实现是通过property的内置函数完成的

class MyClass:    def __init__(self, value):        self.value = value     # get方法    def get_value(self):        return self.__value     # set方法    def set_value(self, value):        if value < 0:            raise ValueError("value must be non-negative.")        self.__value = value     # del方法    def del_value(self):        print("value is being deleted.")        del self.__value     # property创建    value = property(get_value, set_value, del_value) mc = MyClass(20241120)print(mc.value)

使用装饰器

class MyClass:    def __init__(self, value):        self.value = value     @property    def value(self):        return self.__value     @value.setter    def value(self, value):        if value < 0:            raise ValueError("value must be non-negative.")        self.__value = value     @value.deleter    def value(self):        print("value is being deleted.")        del self.__value

与基本语法的版本效果是相同的

常见应用

数据隐藏与封装

property装饰器允许像访问和操作普通一样属性进行操作

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):        if not isinstance(value, (int, float)):            raise ValueError("width must be a number.")        if value <= 0:            raise ValueError("width must be greater than 0.")        self.__width = value     @property    def height(self):        return self.__height     @height.setter    def height(self, value):        if not isinstance(value, (int, float)):            raise ValueError("height must be a number.")        if value <= 0:            raise ValueError("height must be greater than 0.")        self.__height = value         r = Rectangle(3, 4)print(r.width) r.width = "3"

设置只读属性

通过property,可以设置一个属性只允许读取,不允许修改

class Person:    def __init__(self, name):        self.__name = name     @property    def name(self):        return self.__name    # 初始化的时候可以设置名字p = Person("sagegrass") # 名字可以正常被访问print(p.name) # 名字不可以被修改,AttributeError: can't set attribute 'name'p.name = "xxx"

一般来说,这样设置已经足够保证属性只读,但是极特殊的情况下,仍然可以通过p._Person__name进行修改,

不过通常无需额外关注这一问题。

动态计算

关于一开始的例子,我们使用calculate_area进行面积的计算,但是,通过property就可以将area设置为一个属性,进行动态的计算

class Rectangle:    def __init__(self, width, height):        self.width = width        self.height = height        def calculate_area(self):        return self.width * self.height

使用property属性,修改为:

class Rectangle:    def __init__(self, width, height):        self.width = width        self.height = height     @property    def area(self):        return self.width * self.height    r = Rectangle(3, 4)print(r.area)r.width = 5print(r.area)

以上就是python使用property完成数据隐藏封装与校验的详细内容,更多关于python property数据隐藏封装与校验的资料请关注本站其它相关文章!


一文探索Python中PDF解析利器PDFMiner的使用
Python中使用Matplotlib进行多图绘制的详细教程
万事OK自学网:51自学网_软件自学网_CAD自学网自学excel、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。