python中property Python内置函数之property函数用法详

python中property Python内置函数之property函数用法详

目录
  • 一、核心概念与基础语法
    • 1.property的本质
    • 2. 基础语法(两种方式)
    • 3. 使用示例
  • 二、进阶用法
    • 1. 只读属性(仅实现 getter)
    • 2. 计算属性(动态计算)
    • 3. 删除属性(实现 deleter)
    • 4. 类型检查与验证
  • 三、实战案例
    • 1. 数据库字段映射
    • 2. 缓存计算结局
    • 3. 权限控制
  • 四、深入领会与注意事项
    • 1.property的底层实现
    • 2. 继承与property
    • 3. 性能考量
  • 五、与其他技术的对比
    • 六、常见误区与最佳操作
      • 1. 避免过度使用property
      • 2. 私有属性命名约定
      • 3. 初始化时调用 setter
    • 七、拓展资料

      在 Python 中,property一个内置的装饰器,用于将类技巧转换为类属性,实现对属性的高质量控制(如类型检查、只读限制、计算属性等)。

      下面内容是对property的详细解析与实战案例:

      一、核心概念与基础语法

      1.property的本质

      • 属性封装:将技巧伪装成属性,通过点号(.)直接访问
      • 访问控制:自定义属性的 getter、setter 和 deleter 技巧
      • 计算属性:动态计算属性值,无需显式存储

      2. 基础语法(两种方式)

      方式1:使用 property() 函数class Person: def __init__(self, age): self._age = age 私有属性 def get_age(self): return self._age def set_age(self, value): if value < 0: raise ValueError(“年龄不能为负数”) self._age = value age = property(get_age, set_age) 创建 property 对象 方式2:使用装饰器(推荐)class Person: def __init__(self, age): self._age = age @property 相当于 age = property(age) def age(self): return self._age @age.setter 相当于 age = age.setter(setter) def age(self, value): if value < 0: raise ValueError(“年龄不能为负数”) self._age = value

      3. 使用示例

      p = Person(25)print(p.age) 调用 getter 技巧,输出: 25p.age = 30 调用 setter 技巧p.age = -5 抛出 ValueError: 年龄不能为负数

      二、进阶用法

      1. 只读属性(仅实现 getter)

      class Circle: def __init__(self, radius): self.radius = radius @property def area(self): return 3.14 self.radius 2c = Circle(5)print(c.area) 输出: 78.5c.area = 100 报错: AttributeError: can’t set attribute

      2. 计算属性(动态计算)

      class Rectangle: def __init__(self, width, height): self.width = width self.height = height @property def area(self): return self.width self.height @property def perimeter(self): return 2 (self.width + self.height)r = Rectangle(3, 4)print(r.area) 输出: 12print(r.perimeter) 输出: 14

      3. 删除属性(实现 deleter)

      class Person: def __init__(self, name): self._name = name @property def name(self): return self._name @name.deleter def name(self): print(“删除名字…”) del self._namep = Person(“Alice”)print(p.name) 输出: Alicedel p.name 输出: 删除名字…print(p.name) 报错: AttributeError

      4. 类型检查与验证

      class Temperature: def __init__(self, celsius): self.celsius = celsius @property def celsius(self): return self._celsius @celsius.setter def celsius(self, value): if not isinstance(value, (int, float)): raise TypeError(“温度必须是数字”) self._celsius = value @property def fahrenheit(self): return self._celsius 1.8 + 32t = Temperature(25)print(t.fahrenheit) 输出: 77.0t.celsius = “30” 报错: TypeError

      三、实战案例

      1. 数据库字段映射

      class User: def __init__(self, db_row): self._db_row = db_row @property def id(self): return self._db_row[“id”] @property def username(self): return self._db_row[“username”] @property def email(self): return self._db_row[“email”] 使用示例db_data = “id”: 1, “username”: “john”, “email”: “john@example.com”}user = User(db_data)print(user.username) 输出: john

      2. 缓存计算结局

      import mathclass Factorial: def __init__(self, number): self.number = number self._result = None @property def result(self): if self._result is None: print(“计算阶乘…”) self._result = math.factorial(self.number) return self._resultf = Factorial(5)print(f.result) 输出: 计算阶乘… 120print(f.result) 直接返回缓存结局: 120

      3. 权限控制

      class Account: def __init__(self, balance, owner): self._balance = balance self._owner = owner @property def balance(self): return self._balance @balance.setter def balance(self, value): if self._owner != “admin”: raise PermissionError(“只有管理员可以修改余额”) self._balance = valueacc = Account(1000, “user”)print(acc.balance) 输出: 1000acc.balance = 2000 报错: PermissionError

      四、深入领会与注意事项

      1.property的底层实现

      property一个描述符(descriptor)类,其简化实现如下:

      class Property: def __init__(self, fget=None, fset=None, fdel=None): self.fget = fget self.fset = fset self.fdel = fdel def __get__(self, instance, owner): if instance is None: return self if self.fget is None: raise AttributeError(“unreadable attribute”) return self.fget(instance) def __set__(self, instance, value): if self.fset is None: raise AttributeError(“can’t set attribute”) self.fset(instance, value) def __delete__(self, instance): if self.fdel is None: raise AttributeError(“can’t delete attribute”) self.fdel(instance) def getter(self, fget): return type(self)(fget, self.fset, self.fdel) def setter(self, fset): return type(self)(self.fget, fset, self.fdel) def deleter(self, fdel): return type(self)(self.fget, self.fset, fdel)

      2. 继承与property

      • 子类可重写父类的 property

        class Parent: @property def value(self): return 10 class Child(Parent): @property def value(self): return 20

      3. 性能考量

      • 少量调用property的性能开销极小(约 100ns / 次)
      • 大量调用:若性能敏感(如循环百万次),建议直接访问属性

      五、与其他技术的对比

      技术 用途 实现方式
      property 属性封装与控制 装饰器或 property () 函数
      getter/setter 传统的访问控制技巧 显式定义技巧
      getattr 动态属性获取 魔法技巧(所有属性都经过它)
      setattr 动态属性设置 魔法技巧(所有属性都经过它)

      六、常见误区与最佳操作

      1. 避免过度使用property

      • 推荐场景:需要验证、计算或访问控制的属性
      • 不推荐场景:简单的数据封装(直接使用公有属性)

      2. 私有属性命名约定

      • 使用单下划线_attr表示受保护属性(非强制私有)
      • 使用双下划线__attr进行名称修饰(Name Mangling)

      3. 初始化时调用 setter

      class Person: def __init__(self, age): self.age = age 调用 setter 进行验证 @property def age(self): return self._age @age.setter def age(self, value): if value < 0: raise ValueError(“年龄不能为负数”) self._age = value

      七、拓展资料

      场景 推荐实现方式
      简单属性 直接使用公有属性
      需要类型检查 / 验证 使用 property 装饰器
      只读属性 只实现 getter 技巧
      计算属性 使用 property 装饰器
      复杂的属性访问控制 自定义描述符类

      合理使用property可以进步代码的安全性、可维护性和可读性,尤其在需要控制属性访问逻辑的场景中表现出色。

      以上为个人经验,希望能给大家一个参考,也希望大家多多支持风君子博客。

      无论兄弟们可能感兴趣的文章:

      • Python内置函数property()怎样使用
      • Python中lazyproperty的两种技巧
      • python使用property完成数据隐藏封装与校验
      • Pythonproperty函数的具体使用
      • 掌握Pythonproperty装饰器巧妙管理类的属性
      • python装饰器中@property属性的使用解析
      • Python中通过property设置类属性的访问
      版权声明

      返回顶部