前戏
首先,先要弄清楚一个类里面的,各个组成部分都应该怎么称呼。
- 注:可能叫法会不太一样。
关于@property
顾名思义:它的意思为‘属性’。
作用:
1:使用它你将会把类方法,变为类属性。并且是只读属性。
2:它会重新实现getter和setter方法。
看代码:
class Person: def __init__(self,first_name,last_name): self.first_name = first_name self.last_name = last_name @property def full_name(self): return ('%s?%s'%(self.first_name,self.last_name)) #用法 # 实例化类对象 person = Person('狗', 'ride') # 调用类下面的字段 print(person.first_name) print(person.last_name) # 调用类下面加过property装饰器的方法。 print(person.full_name) # 不需要加括号哦!!!因为我有property # 输出结果: # 狗 # ride # 狗?ride # 字段赋个值,看是否可以。 person.first_name = 'ri' person.last_name = '狗地' print(person.full_name) # 输出结果:ri?狗地 # 给属性赋值 person.full_name = 'gougou' #Traceback (most recent call last): # File "/property.py", line 37, in <module> # person.full_name = 'ff' # AttributeError: can't set attribute
# 在此验证了它的只读属性哦
因为我们将方法通过加@property变成了属性。(因此这里我们可以通过调用静态属性的方法,来调用属性)
But,属性是只读的!!!不可以将该属性设为其他值。
第二个功能
代码示例:
from decimal import Decimal ################################################# class Fees(object): #---------------------------------------------------------------------- def __init__(self): """Constructor""" self._fee = None #---------------------------------------------------------------------- def get_fee(self): """ Return the current fee """ return self._fee #---------------------------------------------------------------------- def set_fee(self, value): """ Set the fee """ if isinstance(value, str): self._fee = Decimal(value) elif isinstance(value, Decimal): self._fee = value
fee = property(get_fee, set_fee)
>>> f = Fees()
>>> f.set_fee("1")
>>> f.fee
Decimal('1')
>>> f.fee = "2"
>>> f.get_fee()
Decimal('2')
当我们以这种方式使用属性函数时,它允许fee属性设置并获取值本身而不破坏原有代码。让我们使用属性装饰器来重写这段代码,看看我们是否能得到一个允许设置的属性值。
1 from decimal import Decimal 2 3 ################################################# 4 5 class Fees(object): 6 """""" 7 8 #---------------------------------------------------------------------- 9 def __init__(self): 10 """Constructor""" 11 self._fee = None 12 13 #---------------------------------------------------------------------- 14 @property 15 def fee(self): 16 """ 17 The fee property - the getter 18 """ 19 return self._fee 20 21 #---------------------------------------------------------------------- 22 @fee.setter 23 def fee(self, value): 24 """ 25 The setter of the fee property 26 """ 27 if isinstance(value, str): 28 self._fee = Decimal(value) 29 elif isinstance(value, Decimal): 30 self._fee = value 31 32 #---------------------------------------------------------------------- 33 if __name__ == "__main__": 34 f = Fees() 35 36 # 上面的代码演示了如何为fee属性创建一个setter方法。你可以用一个名为@fee.setter的# 装饰器装饰第二个方法名也为fee的方法来实现这个。当你如下所做时,setter被调用: 37 38 >>> f = Fees() 39 >>> f.fee = "1"
如果你想对属性使用del命令,你可以使用@fee.deleter创建另一个装饰器来装饰相同名字的函数从而实现删除的同样效果。
关于@classmethod和@staticmethod
一般来说,要使用某个类的方法,需要先实例化一个对象再调用方法。
而使用@staticmethod或@classmethod,就可以不需要实例化,直接类名.方法名()来调用。
这有利于组织代码,把某些应该属于某个类的函数给放到那个类里去,同时有利于命名空间的整洁。
既然@staticmethod和@classmethod都可以直接类名.方法名()来调用,那他们有什么区别呢
从它们的使用上来看,
- @staticmethod不需要表示自身对象的self和自身类的cls参数,就跟使用函数一样。
- @classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数。
如果在@staticmethod中要调用到这个类的一些属性方法,只能直接类名.属性名或类名.方法名。
而@classmethod因为持有cls参数,可以来调用类的属性,类的方法,实例化对象等,避免硬编码。