python @property作用,一文了解python的 @property

参考自: https://www.programiz.com/python-programming/property

Python为我们提供了一个内置装饰器@property,此方法使得getter和setter在面向对象编程中使用更加容易。

在细说@property之前,我们先举一个简单的例子,让大家了解为什么需要它。

Class Without Getters and Setters

假设我们需要一个类用来存储温度的摄氏度。这个类不但提供摄氏度,还提供一个摄氏度转华氏度的方法。该类如下所示:

class Celsius:

def __init__(self, temperature = 0):

self.temperature = temperature

def to_fahrenheit(self):

return (self.temperature * 1.8) + 32

接下来展示我们怎么使用这个类。

# 温度类

class Celsius:

def __init__(self, temperature=0):

self.temperature = temperature

def to_fahrenheit(self):

return (self.temperature * 1.8) + 32

# 创建对象

human = Celsius()

# 设置温度

human.temperature = 37

# 获得温度

print(human.temperature)

# 获取华氏度

print(human.to_fahrenheit())

输出。

37

98.60000000000001

转换为华氏温度时,小数点后的额外位置是由于浮点运算错误造成的。

当我们在设置和获取任何对象的属性时(如上文所示的tempurature)时,Python都会在对象的内置dict字典属性中搜索它。

>>> human.__dict__

{'temperature': 37}

所以我们还可以这样做。

>>> human.__dict__['temperature']

37

Using Getters and Setters

如果我们想扩展上面定义的Celsius类。我们都知道任何物体的温度都不能低于-273.15摄氏度(热力学中的绝对零度)。

让我们丰富这个类让它来能够约束tempurature这个值。

约束tempurature的方法就是将tempurature设置为私有属性,并定义setter和getter方法来操作它。

# 添加了Getters和Setter方法

class Celsius:

def __init__(self, temperature=0):

self.set_temperature(temperature)

def to_fahrenheit(self):

return (self.get_temperature() * 1.8) + 32

# getter

def get_temperature(self):

return self._temperature

# setter

def set_temperature(self, value):

if value < -273.15:

raise ValueError("Temperature below -273.15 is not possible.")

self._temperature = value

在Celsius类中,temperature变成_temperature。开头加下划线是用来表示私有变量(约定俗成的规定)。

接着让我们看看怎么使用这个类。

class Celsius:

def __init__(self, temperature=0):

self.set_temperature(temperature)

def to_fahrenheit(self):

return (self.get_temperature() * 1.8) + 32

# getter

def get_temperature(self):

return self._temperature

# setter

def set_temperature(self, value):

if value < -273.15:

raise ValueError("Temperature below -273.15 is not possible.")

self._temperature = value

# 创建温度类

human = Celsius(37)

# 通过getter方法获取温度

print(human.get_temperature())

print(human.to_fahrenheit())

# setter方法设置温度

human.set_temperature(-300)

print(human.to_fahrenheit())

输出。

37

98.60000000000001

Traceback (most recent call last):

File "", line 30, in

File "", line 16, in set_temperature

ValueError: Temperature below -273.15 is not possible.

这个示例成功演示了温度类不允许把温度设置在-273.15度以下。

在Python中temperature属性依然可以通过类直接访问,与Java不同,Python中并没有private关键字。所以说在Python中,变量前添加下划线变成私有变量也就是约定俗称的规定,大家都应遵守。

>>> human._temperature = -300 # 依然可以更改此属性

>>> human.get_temperature()

-300

然而,上面的类带来了一个新的问题,我们再也不能通过obj.temperature = obj 和 value = obj.emperature,取而代之的是obj.set_temperature(obj)和value = obj.get_temperature()。

此时,该Python的内置装饰器出场了。

The property Class

处理上述问题的pythonic方法是使用property类。下面是我们如何更新代码:

# 使用property的类

class Celsius:

def __init__(self, temperature=0):

self.temperature = temperature

def to_fahrenheit(self):

return (self.temperature * 1.8) + 32

# getter

def get_temperature(self):

print("Getting value...")

return self._temperature

# setter

def set_temperature(self, value):

print("Setting value...")

if value < -273.15:

raise ValueError("Temperature below -273.15 is not possible")

self._temperature = value

# 创建一个property对象

temperature = property(get_temperature, set_temperature)

我们添加了一个print()方法在get_temperature和set_temperature方法中。

类中的最后一行,我们创建了一个property对象--temperature。让我们看一下怎么使用这个新类。

# using property class

class Celsius:

def __init__(self, temperature=0):

self.temperature = temperature

def to_fahrenheit(self):

return (self.temperature * 1.8) + 32

# getter

def get_temperature(self):

print("Getting value...")

return self._temperature

# setter

def set_temperature(self, value):

print("Setting value...")

if value < -273.15:

raise ValueError("Temperature below -273.15 is not possible")

self._temperature = value

# creating a property object

temperature = property(get_temperature, set_temperature)

human = Celsius(37)

print(human.temperature)

print(human.to_fahrenheit())

human.temperature = -300

输出。

Setting value...

Getting value...

37

Getting value...

98.60000000000001

Setting value...

Traceback (most recent call last):

File "", line 31, in

File "", line 18, in set_temperature

ValueError: Temperature below -273 is not possible

上面我们看到了,当对temperature进行操作时,会自动调用到get_temperature和set_temperature方法。前面我们也提到,当通过Celsius的对象获取temperature属性时会从obj.__dict__中找到temperature属性进行操作。而当前这个类并没有这样。

当我们在温度类中对temperature进行赋值时也会调用到set_temperature方法。

>>> human = Celsius(37)

Setting value...

再看看下面对temperature的使用。

>>> human.temperature

Getting value

37

>>> human.temperature = 37

Setting value

>>> c.to_fahrenheit()

Getting value

98.60000000000001

The @property Decorator

在Python中,property()是内建方法。此方法的定义如下。

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

参数解释:

fget:获取属性值的方法。

fset:设置属性值的方法。

fdel:删除属性值的方法。

doc:字符串(类似于说明)。

从实现中可以看出,这些函数参数是可选的。因此,属性对象可以简单地创建如下。

>>> property()

在Celsius类中我们添加了如下代码。

temperature = property(get_temperature,set_temperature)

当然我们也可以这样做。

# make empty property

temperature = property()

# assign fget

temperature = temperature.getter(get_temperature)

# assign fset

temperature = temperature.setter(set_temperature)

熟悉Python装饰器的程序员可以认识到上面的构造可以作为装饰器来实现。

接下来让我们看一下如何运用装饰器来替代上面的set_temperature和get_temperature。

# Using @property decorator

class Celsius:

def __init__(self, temperature=0):

self.temperature = temperature

def to_fahrenheit(self):

return (self.temperature * 1.8) + 32

@property

def temperature(self):

print("Getting value...")

return self._temperature

@temperature.setter

def temperature(self, value):

print("Setting value...")

if value < -273.15:

raise ValueError("Temperature below -273 is not possible")

self._temperature = value

# create an object

human = Celsius(37)

print(human.temperature)

print(human.to_fahrenheit())

coldest_thing = Celsius(-300)

输出。

Setting value...

Getting value...

37

Getting value...

98.60000000000001

Setting value...

Traceback (most recent call last):

File "", line 29, in

File "", line 4, in __init__

File "", line 18, in temperature

ValueError: Temperature below -273 is not possible

到此,property我们介绍完毕。

我想说的是,既然使用的是面向对象的语言,那么我们要善用面向对象中封装这个特性,使它能够发挥出重要的作用。

标签:一文,python,self,value,human,property,def,temperature

来源: https://www.cnblogs.com/zhenmei/p/14258680.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值