我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Python @property 详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Python @property 详解

本文讲解了 Python 的 property 特性,即一种符合 Python 哲学地设置 getter 和 setter 的方式。

Python 有一个概念叫做 property,它能让你在 Python 的面向对象编程中轻松不少。在了解它之前,我们先看一下为什么 property 会被提出。

一个简单的例子

比如说你要创建一个温度的类Celsius,它能存储摄氏度,也能转换为华氏度。即:

class Celsius:
    def __init__(self, temperature = 0):
        self.temperature = temperature

    def to_fahrenheit(self):
        return (self.temperature * 1.8) + 32

我们可以使用这个类:

>>> # 创建对象 man
>>> man = Celsius()

>>> # 设置温度
>>> man.temperature = 37

>>> # 获取温度
>>> man.temperature
37

>>> # 获取华氏度
>>> man.to_fahrenheit()
98.60000000000001

最后额外的小数部分是浮点误差,属于正常现象,你可以在 Python 里试一下 1.1 + 2.2

在 Python 里,当我们对一个对象的属性进行赋值或估值时(如上面的temperature),Python 实际上是在这个对象的 __dict__字典里搜索这个属性来操作。

>>> man.__dict__
{'temperature': 37}

因此,man.temperature实际上被转换成了man.__dict__['temperature']

假设我们这个类被程序员广泛的应用了,他们在数以千计的客户端代码里使用了我们的类,你很高兴。

突然有一天,有个人跑过来说,温度不可能低于零下273度,这个类应该加上对温度的限制。这个建议当然应该被采纳。作为一名经验丰富的程序员,你立刻想到应该使用 setter 和 getter 来限制温度,于是你将代码改成下面这样:

class Celsius:
    def __init__(self, temperature = 0):
        self.set_temperature(temperature)

    def to_fahrenheit(self):
        return (self.get_temperature() * 1.8) + 32

    # 更新部分
    def get_temperature(self):
        return self._temperature

    def set_temperature(self, value):
        if value < -273:
            raise ValueError("Temperature below -273 is not possible")
        self._temperature = value

很自然地,你使用了“私有变量”_temperature来存储温度,使用get_temperature()set_temperature()提供了访问_temperature的接口,在这个过程中对温度值进行条件判断,防止它超过限制。这都很好。

问题是,这样一来,使用你的类的程序员们需要把他们的代码中无数个obj.temperature = val改为obj.set_temperature(val),把obj.temperature改为obj.get_temperature()。这种重构实在令人头痛。

所以,这种方法不是“向下兼容”的,我们要另辟蹊径。

@property 的威力!

想要使用 Python 哲学来解决这个问题,就使用 property。直接看代码:

class Celsius:
    def __init__(self, temperature = 0):
        self.temperature = temperature

    def to_fahrenheit(self):
        return (self.temperature * 1.8) + 32

    def get_temperature(self):
        print("Getting value")
        return self._temperature

    def set_temperature(self, value):
        if value < -273:
            raise ValueError("Temperature below -273 is not possible")
        print("Setting value")
        self._temperature = value

    # 重点在这里
    temperature = property(get_temperature,set_temperature)

我们在class Celsius的最后一行使用了一个 Python 内置函数(类) property()。它接受两个函数作为参数,一个 getter,一个 setter,并且返回一个 property 对象(这里是temperature)。

这样以后,任何访问temperature的代码都会自动转而运行get_temperature(),任何对temperature赋值的代码都会自动转而运行set_temperature()我们在代码里加了print()便于测试它们的运行状态。

>>> c = Celsius()  # 此时会运行 setter,因为 __init__ 里对 temperature 进行了赋值
Setting value

>>> c.temperature  # 此时会运行 getter,因为对 temperature 进行了访问
Getting value
0

需要注意的是,实际的温度存储在_temperature里,temperature只是提供一个访问的接口。

深入了解 Property

正如之前提到的,property()是 Python 的一个内置函数,同时它也是一个类。函数签名为:

property(fget=None, fset=None, fdel=None, doc=None)

其中,fget是一个 getter 函数,fset是一个 setter 函数,fdel是删除该属性的函数,doc是一个字符串,用作注释。函数返回一个 property 对象。

一个 property 对象有 getter()setter()deleter()三个方法用来指定相应绑定的函数。之前的

temperature = property(get_temperature,set_temperature)

实际上等价于

# 创建一个空的 property 对象
temperature = property()
# 绑定 getter
temperature = temperature.getter(get_temperature)
# 绑定 setter
temperature = temperature.setter(set_temperature)

这两个代码块等价。

熟悉 Python 装饰器的程序员肯定已经想到,上面的 property 可以用装饰器来实现。

通过装饰器@property,我们可以不定义没有必要的 get_temperature()set_temperature(),这样还避免了污染命名空间。使用方式如下:

class Celsius:
    def __init__(self, temperature = 0):
        self._temperature = temperature

    def to_fahrenheit(self):
        return (self.temperature * 1.8) + 32

    # Getter 装饰器
    @property
    def temperature(self):
        print("Getting value")
        return self._temperature

    # Setter 装饰器
    @temperature.setter
    def temperature(self, value):
        if value < -273:
            raise ValueError("Temperature below -273 is not possible")
        print("Setting value")
        self._temperature = value

你可以使用装饰器,也可以使用之前的方法,完全看个人喜好。但使用装饰器应该是更加 Pythonic 的方法吧。

参考

Python @property

(本文完)

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Python @property 详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Python @property 详解

本文讲解了 Python 的 property 特性,即一种符合 Python 哲学地设置 getter 和 setter 的方式。Python 有一个概念叫做 property,它能让你在 Python 的面向对象编程中轻松不少。在了解它
2023-01-30

详解Python装饰器之@property

一、property() 函数讲解 了解 @property 装饰器之前,我们首先要了解内置函数的 property()。class property(fget=None, fset=None, fdel=None, doc=None)描述
2022-06-02

python特性--property

在定义一个类的时候,有时我们需要获取一个类的属性值,而这个属性值需要经过类中的其他属性运算来获得的。那么很容易,只要我们在类中定义一个方法,并且通过调用方法可以获取到那个需要运算的属性值。那么,问题来了,当有一天需求变了,你需要反向操作你之
2023-01-30

python中@property和pro

1、基本的@property使用,可以把函数当做属性用class Person(object): @property def get_name(self): print('我叫xxx') def main():
2023-01-30

python使用@property @x

@property可以将python定义的函数“当做”属性访问,从而提供更加友好访问方式,但是有时候setter/deleter也是需要的。1》只有@property表示只读。2》同时有@property和@x.setter表示可读可写。3
2023-01-31

Python学习之property

Python中使用Property函数可以将类中的函数当作属性来调用。案例 1 __metaclass__=type 2 class Rectangle: 3 def __init__(self): 4 self.w
2023-01-30

Android 自定义gradle property详解及实例代码

Android 自定义gradle property 在Android studio上运行项目,gradle的配置是必不可少的,但是随着项目的逐渐成长,迎面而来的就是.各种依赖包的添加,数不胜数的签名,渠道包等,整个gradle变得很乱,这
2022-06-06

python @property用法作用

@property广泛应用在类的定义中,可以让调用者写出简短的代码,同时保证对参数进行必要的检查,这样,程序运行时就减少了出错的可能性。详见链接:廖雪峰python3使用@property练习请利用@property给一个Screen对象加
2023-01-31

python中@property怎么使用

本篇内容介绍了“python中@property怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1.什么是property简单地说就是
2023-07-02

python中的@property是什么

这篇文章主要讲解了“python中的@property是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“python中的@property是什么”吧! 说明1、内置的@property装饰
2023-06-20

property如何在python中使用

这篇文章给大家介绍property如何在python中使用,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。什么是property装饰器顾名思义,这是一个装饰器,起到一个辅助作用,具体理解请看下面一个例子。我们知道,程序中
2023-06-14

python property的使用技巧分享

property属性一种用起来像是使用实例属性一样的特殊属性,可以对应于某个方法既要保护类的封装特性,又要让开发者可以使用 对象.属性 的方式操作方法,@property 装饰器,可以直接通过方法名来访问方法,不需要在方法名后添加一对 (
2022-06-02

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录