初识property属性
说道属性,我们马上想到实例属性、类属性等
那么回顾一下类属性
clsas Provice(object):
country = 'china'
def xxx(self):
pass
如上代码中 country就是类属性,我们可以通过以下方式去设置值和获取值
beijing = Probice()
# 调用实力方法
beijing.xxx()
# 获取类属性
my_country = beijing.country
那么如果我们这个需要在这个country的值需要一些逻辑运算才能得到怎么办?
python为我们提供了property属性可以很方便的解决这个问题 如下:
clsas Provice(object):
# 定义property属性
@property
def country(self):
return 'china'
def xxx(self):
pass
调用:
beijing = Probice()
# 调用方法
beijing.xxx()
# 调用property属性
my_country = beijing .country
由上面的代码,我们很清楚明白了,什么是property属性?
一种用起来像是使用的实例属性一样的特殊属性,可以对应于某个方法
property属性的定义和调用注意点
- 在实例方法的基础上添加 @property 装饰器;并且仅有一个self参数
- 调用时,无需括号
实例
分页操作:
功能包括:
- 根据用户请求的当前页和数据条数计算分页 的start_index和end_index:
- 根据start_index和end_index去数据库中请求数据
class Pager:
def __init__(self, current_page):
# 用户当前请求的页码(第一页、第二页...)
self.current_page = current_page
# 每页默认显示10条数据
self.per_items = 10
@property
def start_index(self):
val = (self.current_page - 1) * self.per_items
return val
@property
def end_index(self):
val = self.current_page * self.per_items
return val
# ############### 调用 ###############
p = Pager(1)
p.start_index # 就是起始值,即:m
p.end_index # 就是结束值,即:n
由此,我们得出结论:
Python的property属性的功能是:property属性内部进行一系列的逻辑计算,最终将计算结果返回。
property属性的俩种应用方式
- 装饰器方式 : 在方法上加装饰器
- 类属性 在类中定义值为property对象的类属性
装饰器方式
在类的实例方法上应用@property装饰器
Python中的类有经典类和新式类,新式类的属性比经典类的属性丰富。( 如果类继object,那么该类是新式类 )
经典类,具有一种@property装饰器:
clsas Provice(object):
# 定义property属性
@property
def country(self):
return 'china'
新式类,具有三种@property装饰器:
clsas Provice(object):
'''
python3中默认继承object类
以python2、3执行此程序的结果不同,因为只有在python3中才有@xxx.setter @xxx.deleter
'''
def __init__(self):
self.country = 'china'
@property
def country(self):
return self.country.upper()
@country.setter
def country(self,value):
# 必须俩个参数
self.country = value
@country.deleter
def country(self):
del self.country
调用方式
beijing = Provice()
beijing.country # 自动执行 @property 修饰的 country方法,并获取方法的返回值'
beijing,country = 'china' # 自动执行 @country.setter 修饰的 country方法,并将 china 赋值给方法的参数
del beijing.country # 自动执行 @country.deleter 修饰的 country方法
类属性方式
当使用类属性的方式创建property属性时,经典类和新式类无区别
clsas Provice(object):
'''
python3中默认继承object类
以python2、3执行此程序的结果不同,因为只有在python3中才有@xxx.setter @xxx.deleter
'''
def __init__(self):
self.country = 'china'
def get_country(self):
return self.country.upper()
def set_country(self,value):
# 必须俩个参数
self.country = value
def del_country(self):
del self.country
country = property(get_country,set_country,del_country,'descroption...')
# 调用
beijing = Provice()
beijing.country # 获取 - 自动调用第一个参数中定义的方法:get_country
beijing.country= "china" # 修改 - 自动调用第二个参数中定义的方法:set_country方法,并将'china'当作参数传入
desc= beijing.country.__doc__ # 自动获取第四个参数中设置的值:description...
print(desc)
del beijing.country # 删除 - 自动调用第三个参数中定义的方法:del_country方法
property方法中四个参数详解 :
- 第一个参数是方法名,调用 对象.属性 时自动触发执行方法
- 第二个参数是方法名,调用 对象.属性 = XXX 时自动触发执行方法
- 第三个参数是方法名,调用 del 对象.属性 时自动触发执行方法
- 第四个参数是字符串,调用 对象.属性__doc__ ,此参数是该属性的描述信息
总结
- 定义property属性共有两种方式,分别是【装饰器】和【类属性】,而【装饰器】方式针对经典类和新式类又有所不同。
- 通过使用property属性,能够简化调用者在获取数据的流程
应用
如果我们学过java 就知道私有属性 set() 和 get() 方法。 如下java代码:
class Student{
// 声明私有属性name
private String name;
/**
name 的set方法,对name值做非空判断
*/
public void setName(String name){
if(null!=name && name.length > 0){
this.name = name;
} else {
print("name值不能为空")
}
}
public void getName(){
return this.name;
}
}
// 调用
Student s1 = new Srudent(); // 创建实例对象
s1.setName('张三'); // 设置name
name = s1.getName() // 获取name
那么我们也仿照上面java实现的方式来实现一个python的setter和getter方法
class Student(object):
def __init__(self):
# 创建私有属性__name
self.__name = ''
def getName(self):
return self.__name
def setName(self,name):
if None!=name and len(name) > 0:
self.__name = name
else:
print("name值不能为空")
# 调用
s1 = Student() // 创建实例
s1.setName('张三') // 设置名称
name = s1.getName() // 获取名称
python实现后,我们发现通过property 可以作进一步优化
class Student(object):
def __init__(self):
# 创建私有属性__name
self.__name = ''
def getName(self):
return self.__name
def setName(self,name):
if None!=name and len(name) > 0:
self.__name = name
else:
print("name值不能为空")
NAME = property(getName,setName)
# 调用
s1 = Student() # 创建实例
s1.NAME = '张三' # 设置name
name = s1.NAME # 获取name
用装饰器实现property的方式
class Student(object):
def __init__(self):
# 创建私有属性__name
self.__name = ''
# 使用装饰器对name进行装饰,那么会自动添加一个叫name的属性,当调用获取name的值时,调用装饰的方法
@property
def name(self):
return self.__name
# 使用装饰器对name进行装饰,当对name设置值时,调用装饰的方法
@name.setter
def name(self,name):
if None!=name and len(name) > 0:
self.__name = name
else:
print("name值不能为空")
NAME = property(getName,setName)
# 调用
s1 = Student() # 创建实例
s1.NAME = '张三' # 设置name
name = s1.NAME # 获取name