@property属性函数

一、应用

    1、@property一般应用在Python方法上,可以有效地将属性访问(attribute access)变成方法调用(method call) 

    2、简单的列子:如果单纯的学生的分数作为属性,那么将没有办法对分数进行检查(毕竟分数不能为负数和无限大)。

    那么我们可以用@property将属性访问(attribute access)变成方法调用(method call)

 1 class Student(object):
 2    @property # 将属性的访问变成方法的调用(调用方式还是 "对象.方法名")
3
  def score(self):
4
     return self._score
 6    # 通过socre.setter装饰的score即可对value进行修改,也可以进行参数检查
 7     @score.setter
 8     def score(self, value):
 9         if not isinstance(value, int):
10             raise ValueError('score must be an integer!')
11         if value < 0 or value > 100:
12             raise ValueError('score must between 0 ~ 100!')
13         self._score = value
14 
15 
16 stu = Student()
17 stu.score = 78
18 print(stu.score)

 

二、实例:

  创建一个代表金钱的类:

1 class Money:
2   def __init__(self, dollars, cents):
3     self.dollars = dollars
4     self.cents = cents  

  这个类后来被打包到一个Python库里,并且慢慢地被许多不同的应用使用。举个例子,另一个团队中的Python程序员Bob是这样使用Money类的:

1 money = Money(27, 12)
2 message = "I have {:d} dollars and {:d} cents."
3 print(message.format(money.dollars, money.cents))
4 # "I have 27 dollars and 12 cents."
5 money.dollars += 2
6 money.cents += 20
7 print(message.format(money.dollars, money.cents))
8 # "I have 29 dollars and 32 cents."

   但是,因为某种业务需求不再记录美元和美分,而是仅仅记录美分,这样的导致代码需要重构;许多团队都复用了她的代码。因此,她需要协调他们的代码库与自己的修改保持一致。

  这时候使用Python内建的property装饰器,会使问题简单许多。代码如 下:

 1 class Money:
 2     def __init__(self, dollars, cents):
 3         # 改成美分
 4         self.total_cents = dollars * 100 + cents
 5 
 6     # @property修饰的函数可以通过"obj.方法名" 直接调用;但是不能直接修改
 7     # 如 money.dollars = 100 ,这样是会报错的。
 8     # 但是我可以为该方法定一个setter方法来修改其值;第13行的就定义了这样一个方法。
 9     @property
10     def dollars(self):
11         # 将@dollars.setter转化的美分除以100 返回给以前的团队使用。 
12         return self.total_cents // 100;
13 
14     # 该方法与@property修饰的方法名称一样
15     @dollars.setter
16     def dollars(self, new_dollars):
17         # 将传进的美元转化成美分,方便其他业务的使用
18         self.total_cents = 100 * new_dollars + self.cents
19 
20 
21     @property
22     def cents(self):
23         return self.total_cents % 100;
24 
25     @cents.setter
26     def cents(self, new_cents):
27         self.total_cents = 100 * self.dollars + new_cents
28 
29 
30 # 他的代码完全没有变动,但是却可以正常调用Money类。
31 money = Money(27, 12)
32 message = "I have {:d} dollars and {:d} cents."
33 print(message.format(money.dollars, money.cents))
34 # "I have 27 dollars and 12 cents."
35 money.dollars += 2
36 money.cents += 20
37 print(message.format(money.dollars, money.cents))
38 # "I have 29 dollars and 32 cents."# 代码逻辑也没有问题。
39 money.cents += 112
40 print(message.format(money.dollars, money.cents))
41 # "I have 30 dollars and 44 cents."
View Code

 

posted @ 2017-08-29 21:40  Peaunt  阅读(288)  评论(0编辑  收藏  举报