描述符

Python 面向对象编程进阶

Jake Roach

Data Engineer

改变与属性的交互方式

class Student:
    def __init__(self, name, ssn):
        self.name = name
        self.ssn = ssn
# 创建一个学生对象,并访问 "ssn" 属性
shaw = Student("Daniel Shaw", "193-80-1821")
print(shaw.ssn)

# 若值被修改或删除,应如何处理?
193-80-1821
Python 面向对象编程进阶

使用 @property 创建描述符

描述符是用于控制属性的获取、设置或删除方式的对象。

使用 @property 创建描述符

  • "getter"、"setter"、"deleter"
  • 方法名 == 属性名

也可通过以下方式创建描述符…

  • property() 函数
  • __get__()__set__()__delete__()

$$

class Student:
    def __init__(self, name, ssn):
        self.name = name
        self.ssn = ssn

    @property  
    def ssn(self):
        return "XXX-XX-" + self._ssn[-4:]

    @ssn.setter  
    def ssn(self, new_ssn):
        self._ssn = new_ssn 

    @ssn.deleter
    def ssn(self):
        raise AttributeError("Can't delete SSN")
Python 面向对象编程进阶

@property

class Student:
    def __init__(self, name, ssn):
        self.name = name
        self.ssn = ssn  # Does not need to include an underscore

    @property  
    def ssn(self):  # This is the "getter" method
        return "XXX-XX-" + self._ssn[-4:]
  • 控制 ssn 的读取方式
  • 只与 self._ssn 交互,不与 self.ssn 交互
Python 面向对象编程进阶

@ssn.setter

class Student:
    def __init__(self, name, ssn):
        self.name = name
        self.ssn = ssn
    ...

    @ssn.setter  
    def ssn(self, new_ssn):
        if len(new_ssn) == 11:
          # Add things such as data 
          # validation, operations on
          # other attributes, etc.
          self._ssn = new_ssn

@<attribute-name>.setter

  • ssn 的"setter"方法
  • 校验数据质量
  • 可操作其他属性

$$

$$

$$

请记得只与 self._ssn 交互,而非 self.ssn

Python 面向对象编程进阶

@ssn.deleter

class Student:
    def __init__(self, name, ssn):
        self.name = name
        self.ssn = ssn

    ...

    @ssn.deleter
    def ssn(self):
        # Can perform clean up, soft delete, raise exception
        raise AttributeError("Can't delete SSN")
Python 面向对象编程进阶

描述符实战

shaw = Student("Daniel Shaw", "193-80-1821")
print(shaw.ssn)  # Access the ssn attribute
XXX-XX-1821
shaw.ssn = "821-11-9380"  # Update Shaw's social security number
print(shaw.ssn)
XXX-XX-9380
del shaw.ssn  # Attempt to delete the ssn attribute
AttributeError: Can't delete SSN
Python 面向对象编程进阶

Passons à la pratique !

Python 面向对象编程进阶

Preparing Video For Download...