• day 22 封装 + property + classmethod + staticmethod


    面向对象的三大特性:继承  多态  封装

    封装:()

      广义上的:

      狭义上的:会为一种现象起一个专属它的名字

    把函数和属性封装到一个非全局的命名空间

    class A:

      __N = 'aaa'  静态变量

    print(A.__N)

    python

    1.public

    2.private

    java(完全是面向对象的语言)

    1.public

    2.protect

    3.private

    定义一个私有的名字:就是在私有的名字面前加上双下划线 __N = 'aaa'

    所谓私有就是不能再类的外面引用它

     class A:
    # __N = 'aaa' # 静态变量
    # def func(self):
    # print(A.__N) # 在类的内部使用正常
    #
    # a = A()
    # a.func()
    # print(A.__N) # 在类的外部直接使用 报错

    class A:
    __N = 'aaa'
    def func(self):
    print(A.__N)

    print(A.__dict__)
    print(A._A__N)

    #{'func': <function A.func at 0x0000011B197637B8>, '__module__': '__main__', '__dict__': <attribute '__dict__' of 'A' objects>, '_A__N': 'aaa', '__doc__': None, '__weakref__': <attribute '__weakref__' of 'A' objects>}
    #aaa


    
    
    # 一个私有的名字 在存储的过程中仍然会出现在A.__dict__中,所以我们仍然可以调用到。
    # python对其的名字进行了修改: _类名__名字
    # 只不过在类的外部调用 :需要“_类名__名字”去使用
    # 在类的内部可以正常的使用名字
     _A__N
    # 在类内 只要你的代码遇到__名字,就会被python解释器自动的转换成_类名__名字



    # 私有的名字,在类内使用的时候,就是会变形成_该类名__方法名
    # 以此为例 :没有双下换线会先找E中的func
    # 但是有了双下划线,会在调用这个名字的类D中直接找_D__func
    # 变形只在类的内部发生
    
    
    # class D:
    #     def __init__(self):
    #         self.__func()
    #     def __func(self):
    #         print('in D')
    #
    # class E(D):
    #     def __func(self):
    #         print('in E')
    # e = E()

    # class F:pass
    # print(F.__dict__)
    # F.__name = 'aaa'
    # f = F()
    # print(f.__name)
    # print(F.__dict__)
     
    
    
    # class F:pass
    # print(F.__dict__)
    # F.__name = 'aaa'
    # f = F()
    # print(f.__name)
    # print(F.__dict__)
    # class F:
    #     def ADC(self):
    #         self.__name = 'alex'
    #
    # f = F()
    # f.ADC()
    # print(F.__dict__)
    # print(f.__dict__)

    这个实例说明:在对象中创建的静态属性

    Java中的对比:

    public 共有的: 在类的内部可以使用,子类可以使用,在类的外部也可以使用  python中所有正常的名字

    protect 保护的:在类的内部可以使用,子类可以使用,在类的外部不可使用  python中没有

    private 私有的: 在类的内部可以使用,字类和在类的外部都不可使用。    python中的__名字

    私有的用法:

      当一个方法不想被子类继承的时候:

      有些属性和方法不希望从外部调用,只希望从内部调用

    # 人体BMI指数
    # 体质指数(BMI)=体重(kg)÷身高^2(m)
    # 写一个类 描述人体BMI指数
    
    class Person:
        def __init__(self,name,weight,height):
            self.name = name
            self.__height = height
            self.__weight = weight
            # self.bmi = self.__weight / self.__height ** 2
            # self.bmi = self.cal_BMI()
    
        def cal_BMI(self):
            return self.__weight / self.__height ** 2
    
        @property
        def bmi(self):
            return self.__weight / self.__height ** 2
    p = Person('大表哥',92,1.85)
    # print(p.cal_BMI())
    # p.cal_BMI() # bmi是一个名词
    # print(p.bmi) # bmi是一个名词
    # p._Person__weight = 90
    # print(p.bmi)
    # 将一个方法伪装成一个属性
    # 并不会让你的代码有什么逻辑上的提高
    # 只是从调用者的角度上换了一种方式,使之看起来更合理
    # @property 能够将一个方法伪装成一个属性
    # 从原来的的对象名.方法名(),变成了对象名.方法名
    # 只是让代码变的更美观

    注意:如果出现了重名的名字:程序就会报错


    
    
    # 将方法伪装成属性,方法中一般涉及的都是一些计算过程
    # from math import pi
    # class Circle:
    #     def __init__(self,r):
    #         self.r = r
    #     @property
    #     def area(self):
    #         return self.r**2*pi
    #
    #     @property
    #     def perimeter(self):
    #         return 2*pi*self.r
    # c = Circle(10)
    # print(c.area)
    # print(c.perimeter)
    # c.r = 15
    # print(c.area)
    # print(c.perimeter)
    
    

    因为property不能传参,所有如果还想要将动态函数名改为名词性函数名,就需要用到名词性函数名.settle

     方法伪装成的属性的修改
    # class Person:
    #     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 = Person('alex')
    # print(p.name)       #def name(self):
    # p.name = 'alex_sb' #def name(self,new_name):
    # print(p.name)       #def name(self):
    # p.name = 123 #def name(self,new_name):
    # print(p.name)       #def name(self):
    
    
    # 方法伪装成的属性的删除
    class Person:
    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 = Person('alex')
    # print(p.name)
    # del p.name # 只是执行了被@name.deleter装饰的函数
    # 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) 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)


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

    # def login():
    # user= input('user :')
    # if user == 'alex':print('success')
    # else :print('faild')
    #
    # login()
    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静态方法
     
     
    
    
     



     



  • 相关阅读:
    bzoj5157: [Tjoi2014]上升子序列(树状数组LIS)
    2435: [Noi2011]道路修建(树上操作)
    bzoj1019: [SHOI2008]汉诺塔(动态规划)
    bzoj1103: [POI2007]大都市meg(树链剖分)
    bzoj2190: [SDOI2008]仪仗队(欧拉)
    bzoj4519: [Cqoi2016]不同的最小割(分治最小割)
    bzoj2229: [Zjoi2011]最小割(分治最小割+最小割树思想)
    bzoj1816: [Cqoi2010]扑克牌(二分答案判断)
    [HEOI2015]兔子与樱花
    [POI2009]KAM-Pebbles
  • 原文地址:https://www.cnblogs.com/zsdbk/p/8866649.html
Copyright © 2020-2023  润新知