首页Python【Python内置函数】p...

【Python内置函数】property()函数

Python 提供了许多内置函数,这些函数是Python语言的一部分,可以直接在Python程序中使用而无需导入任何模块。

本系列将会陆续整理分享一些的Python内置函数。

文章配套代码获取有以下两种途径:
  • 通过百度网盘获取:
链接:https://pan.baidu.com/s/11x9_wCZ3yiYOe5nVcRk2CQ?pwd=mnsj 提取码:mnsj
  • 前往GitHub获取
https://github.com/returu/Python_built-in_functions





01
简介

property() 函数用于实现属性的封装和访问控制。它允许开发者将方法伪装成属性,从而在访问属性时自动调用相应的方法,实现更灵活的属性管理。

property() 函数的基本语法如下:

property(fget=None, fset=None, fdel=None, doc=None)
参数说明:
  • fget:用于获取属性值的函数(getter);
  • fset:用于设置属性值的函数(setter);
  • fdel:用于删除属性值的函数(deleter);
  • doc:属性的可选文档字符串。

返回值:

property()函数返回一个property对象,该对象可以用作类属性的装饰器。

02
使用

下面是一些使用 property() 函数的示例:

  • 示例 1:使用property()构造函数

在类定义中,直接调用property()造函数来创建一个属性。

class Person:
    def __init__(self, name):
        self._name = name

    # 定义一个获取 name 属性的函数
    def get_name(self):
        return self._name

    # 定义一个设置 name 属性的函数
    def set_name(self, value):
        if not isinstance(value, str):
            raise ValueError("Name must be a string")
        self._name = value

    # 定义一个删除 name 属性的函数
    def del_name(self):
        del self._name

    # 使用 property 创建一个 name 属性
    name = property(get_name, set_name, del_name, "The person's name")
# 使用示例
person = Person("Alice")

# 调用 get_name 方法
print(person.name)  # 输出:Alice
# 调用 set_name 方法
person.name = "Bob"
print(person.name)  # 输出:Bob

# 尝试设置非法值
try:
    person.name = -1
except ValueError as e:
    print(e)  # 输出错误信息:Name must be a string

# 删除属性
del person.name
# 尝试访问已删除的属性会引发异常
try:
    print(person.name)
except AttributeError as e:
    print(e)  # 输出: 'Person' object has no attribute '_name'


  • 示例 2:使用属性对象的附加方法

属性对象具有以下方法:

  • getter(fget):返回一个新的属性对象,其获取器函数设置为 fget

  • setter(fset):返回一个新的属性对象,其设置器函数设置为 fset

  • deleter(fdel):返回一个新的属性对象,其删除器函数设置为 fdel

这些方法可用于在创建属性后动态修改其行为。

class Person_1:
    def __init__(self, name):
        self._name = name

    # 定义一个获取 name 属性的函数
    def get_name(self):
        return self._name

    # 定义一个设置 name 属性的函数
    def set_name(self, value):
        if not isinstance(value, str):
            raise ValueError("Name must be a string")
        self._name = value

    # 定义一个删除 name 属性的函数
    def del_name(self):
        del self._name

    # 显式使用 getter、setter 和 deleter 方法
    name = property(get_name)
    name = name.setter(set_name)
    name = name.deleter(del_name)


  • 示例 3:使用装饰器简化语法

在实际开发中,通常使用 @property 装饰器简化属性的创建过程。使用@property定义getter@属性名.setter@属性名.deleter定义setterdeleter,使代码更简洁。

以下是使用装饰器的等效代码:

class Person_2:
    def __init__(self, name):
        self._name = name

    @property
    def name(self):
        """I'm the 'name' property."""
        return self._name

    @name.setter
    def name(self, value):
        if not isinstance(value, str):
            raise ValueError("Name must be a string")
        self._name = value

    @name.deleter
    def name(self):
        del self._name


  • 示例 4:关键特性

只读属性:若未定义setter,属性不可修改。

class Person_3:
    def __init__(self, name):
        self._name = name

    @property
    def name(self):
        """I'm the 'name' property."""
        return self._name
# 使用示例
person_3 = Person_3("Alice")

# 调用 get_name 方法
print(person_3.name)  # 输出:Alice
# 属性不可修改或删除
person_3.name = "Bob"  # AttributeError

内部属性访问:返回的属性对象还具有与构造函数参数对应的 fgetfset 和 fdel 属性。

# 访问 property 对象的 fget, fset, fdel 属性
print("fget:", Person_2.name.fget)  # 输出:fget: <function Person_2.name at 0x...>
print("fset:", Person_2.name.fset)  # 输出:fset: <function Person_2.name at 0x...>
print("fdel:", Person_2.name.fdel)  # 输出:fdel: <function Person_2.name at 0x...>

 Python 3.5 及更高版本中,属性对象的文档字符串(docstring)现在是可以修改的。这意味着可以动态地更改属性的文档字符串,而不仅仅是在定义时设置它。

# 打印原始文档字符串
print("Original docstring:", Person_2.name.__doc__)
# 输出:Original docstring: I'm the 'name' property.

# 修改文档字符串
Person_2.name.__doc__ = "This is a new docstring for the 'name' property."

# 打印修改后的文档字符串
print("Modified docstring:", Person_2.name.__doc__)
# 输出:Modified docstring: This is a new docstring for the 'name' property.

从 Python 3.13 开始,property对象新增了一个__name__属性,用于保存属性的名称。这个名称可以在运行时被修改。这个属性是针对property对象本身的,而不是类的名称。

# 打印原始属性名称
print("Original property name:", Person.name.__name__)
# 输出:name

# 修改属性名称
Person.name.__name__ = "new_name"

# 打印修改后的属性名称
print("Modified property name:", Person.name.__name__)
# 输出:new_name

本篇文章来源于微信公众号: 码农设计师

RELATED ARTICLES

欢迎留下您的宝贵建议

Please enter your comment!
Please enter your name here

- Advertisment -

Most Popular

Recent Comments