property属性
什么是特性property
property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值,就是以前我们要调用方法,形式是对象.方法名(),有了这个属性就可以直接以调用属性的方式进行调用
property装饰的bmi仍然是一个方法 存在Person.dict
对象的.__dict__中不会存储这个属性
在一个类加载的过程中,会先加载这个中的名字,包括被property装饰的
在实例化对象的时候,python解释器会先到类的空间里看看有没有这个被装饰的属性,
如果有就不能再在自己对象的空间中创建这个属性了
例一:人体的BMI指数:
class Person():
def __init__(self, name, weight, height):
self.name = name
self.__height = height
self.__weight = weight
@property
def cal_BIM(self):
return self.__weight/self.__height ** 2
p = Person('dear', 65, 1.73)
print(p.cal_BIM)
例二:圆的面积
import math
class Circle:
def __init__(self, r):
self.r = r
@property
def area(self):
return self.r **2 * math.pi
@property
def perimeter(self):
return self.r *2 * math.pi
c=Circle(10)
print(c.r)
print(c.area) #可以向访问数据属性一样去访问area,会触发一个函数的执行,动态计算出一个值
print(c.perimeter) #同上
#注意:此时的特性area和perimeter不能被赋值
c.area=3 #为特性area赋值
‘’’
抛出异常:
AttributeError: can’t set attribute
‘’’
为什么要用property
将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则
ps:面向对象的封装有三种方式:
【public】
这种其实就是不封装,是对外公开的
【protected】
这种封装方式对外不公开,但对朋友(friend)或者子类(形象的说法是“儿子”,但我不知道为什么大家 不说“女儿”,就像“parent”本来是“父母”的意思,但中文都是叫“父类”)公开
【private】
这种封装对谁都不公开
但是Python中只有两种,【public】,【private】
python并没有在语法上把它们三个内建到自己的class机制中,在C++里一般会将所有的所有的数据都设置为私有的,然后提供set和get方法(接口)去设置和获取,在python中通过property方法可以实现。
一个静态属性property本质就是实现了get,set,delete三种方法
class Person:
def __init__(self, name):
self.__name = name #私有属性
@property
def name(self):
return self.__name
# 方法伪装成的属性的修改
@name.setter
def name(self, new_name):
if type(new_name) is str:
self.__name = new_name
else:
print('您提供的姓名数据类型不合法')
# 方法伪装成的属性的删除
@name.deleter
def name(self):
del self.__name
p = Person('happy')
print(p.name) #执行def name(self):
p.name = 'like' #修改名字,执行def name(self, new_name):
del p.name #执行了被@name.deleter装饰的函数
具体实例用法:
# 商品的 折扣
# 有一个商品 : 原价 折扣
# 当我要查看价格的时候 我想看折后价
class Goods:
def __init__(self, name, origin_price, discount):
self.name = name
self.__price = origin_price
self.__discount = discount
@property
def price(self):
return self.__price * self.__discount
@price.setter
def price(self, new_price):
if type(new_price) is int or type(new_price) is float:
self.__price = new_price
apple = Goods('apple',5,0.8)
print(apple.price)
# # 修改苹果的原价
apple.price = 8
print(apple.price)
作用:
将一些需要随着一部分属性的变化而变化的值的计算过程 从方法 伪装成属性
将私有的属性保护起来,让修改的部分增加一些约束,来提高程序的稳定性和数据的安全性
classmethod
# 店庆 全场八折
class Goods:
__discount = 0.8
def __init__(self,name,origin_price):
self.name = name
self.__price = origin_price
@property
def price(self):
return self.__price * Goods.__discount
@classmethod
def change_discount(cls, new_discount): # 类方法可以直接被类调用 不需要默认传对象参数 只需要传一个类参数就可以了
cls.__discount = new_discount
apple = Goods('apple',5)
banana = Goods('banana',8)
print(apple.price)
print(banana.price)
#折扣变了
Goods.change_discount(1) # 不依赖对象的方法 就应该定义成类方法 类方法可以任意的操作类中的静态变量
print(apple.price)
print(banana.price)
staticmethod
当一个方法要使用对象的属性时 就是用普通的方法
当一个方法要使用类中的静态属性时 就是用类方法
当一个方法要既不使用对象的属性也不使用类中的静态属性时,就可以使用staticmethod静态方法
class Student:
def __init__(self,name):pass
@staticmethod
def login( a ): # login就是一个类中的静态方法 静态方法没有默认参数 就当成普通的函数使用即可
user = input('user :')
if user == 'haha':
print('success')
else:
print('faild')
Student.login(1)