封装1

 将一个方法伪装成成一个属性

  并不会让你代码有什么逻辑上的提高

  只是从调用者的角度上换了一种方式,使之看起来更符合哲理。

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静态方法

猜你喜欢

转载自www.cnblogs.com/hanjiahao/p/8902979.html