将一个方法伪装成成一个属性
并不会让你代码有什么逻辑上的提高
只是从调用者的角度上换了一种方式,使之看起来更符合哲理。
class Person: def __init__(self,name,kg,m): self.name = name self.kg = kg self.m = m @property def cal_BMI(self): return self.kg / self.m ** 2 @property def BMI(self): return self.kg / self.m ** 2 p = Person('毛',70,1.85) print(p.cal_BMI) print(p.BMI)
被property装饰的bmi仍然是一个方法 存在Person.__dict__
对象的.__dict__中不会存储这个属性的
在一个类加载的过程中,会先加载这个中的名字,包括被property装饰的
在实例化对象的时候,python解释器会先到类的空间里看看有没有这个被装饰的属性
如果有就不能再在自己对象的空间中创建这个属性了
@property 能够将一个方法伪装成一个属性
从原的对象名.方法名(),变成了对象名.方法名
只是让代码变得更美观。
将方法伪装成属性,方法中一般涉及的都是一些计算方法
计算圆周长和面积
from math import pi class Circle(): def __init__(self,r): self.r = r @property def cal_area(self): # def area return pi*self.r*2 @property def cal_perimeter(self): #def cal_perimeter return pi*self.r**2 c = Circle(10) print(c.cal_area) print(c.cal_perimeter) #c.r = 15 #print(c.area) #print(c.perimeter)
将方法伪装成属性的修改
class Preson: def __init__(self,n): self.__name = n @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('您提供的姓名数据类型不合法') p = Preson('alex') print(p.name) p.name = 'alex_sb' print(p.name) p.name = 123 print(p.name)
方法伪装成的属性删除
class Preson: def __init__(self,n): self.__name = n @property def name(self): return self.__name @name.deleter def name(self): print('name 已经被删除') # @name.deleter # def name(self): # del self.name p =Preson('alex') print(p.name) del p.name print(p.name)
@property --> func 将方法伪装成属性,只观看的事
@func.setter -->func 对伪装的属性进行复制的时候偶调用这个方法,一般情况下用来修改
@func.deleter --> func 在执行del 对象.func的时候调用这个方法 一般情况下用来删除 基本不用
例题:
商品的折扣
有一个商品:原价 折扣
当我要查看价格的时候 我想看折后价
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) in int or type(new_price) is float: self.__price = new_price a = Goods('apple',5,0.8) print(a.price)
将一些需要随着一部分属性的变化而变化的值的计算过程,从方法 伪装成属性
将私有的属性保护起来,让修改的本分增加一些约束,来提高程序的稳定行和数据的安全性
# 店庆 全场八折 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 Goods.change_discount(1) # 不依赖对象的方法 就应该定义成类方法 类方法可以任意的操作类中的静态变量 apple = Goods('apple',5) banana = Goods('banana',8) print(apple.price) print(banana.price)
# 折扣变了 店庆结束 恢复折扣
# apple.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 == 'alex': print('success') else: print('faild') Student.login(1)
完全面向对象编程
先登录后实例化
还没有一个具体的对象的时候 就要执行login方法
使用什么样的方法要看具体用到了那些名称空间中的变量
当一个方法要使用对象的属性时,就是用普通的方法
当一个方法要使用类中的静态属性时,就是用类方法
当一个方法要既不使用对象的属性也不使用类中的静态属性是,就可以使用staticmethod静态方法