• python之路_面向对象三大特性之封装


    1、私有属性

    (1)动态属性

      在python中用双下划线开头的方式将属性隐藏起来。类中所有双下划线开头的名称,如__x都会自动变形成:_类名__x的形式。这种自动变形的特点是:

      a.类中定义的__x只能在内部使用,如self.__x,引用的就是变形的结果。b.这种变形其实正是针对外部的变形,在外部是无法通过__x这个名字访问到的。c.在子类定义的__x不会覆盖在父类定义的__x,因为子类中变形成了:_子类名__x,而父类中变形成了:_父类名__x,即双下滑线开头的属性在继承给子类时,子类是无法覆盖的。

    class Teacher:
        def __init__(self,name,pswd):
            self.name=name
            self.__pswd=pswd                                       #私有属性
        def func(self):
            print(self.__pswd)
    alex=Teacher('alex','3714')
    alex.func()
    # print(alex.__pswd)                                           #私有属性不可以通过此方式查看
    print(alex._Teacher__pswd)                                     #私有属性外部查看的方式:_Teacher__pswd储存

    (2)静态属性

      私有化的方式同样为在属性名前加双下划线,只能在内部进行使用,外部查看方式与动态属性一样。

    class Teacher:
        __identifier='teacher'                                     #私有静态属性
        def __init__(self,name,pwd):
            self.name=name
            self.__pwd=pwd                                         #私有属性
        def func(self):       
            print(self.__pwd,Teacher.__identifier)
    print(Teacher._Teacher__identifier)                            #在外面查看静态属性方法
    alex=Teacher('alex','1234')
    alex.__a='aaa'                                                 #在外部定义,并不会形成私有化,__a即为一个合法的正常变量名
    print(alex.__dict__)                                           #查看动态属性字典,结果为:{'name': 'alex', '_Teacher__pwd': '1234', '__a': 'aaa'}

    问题点总结:

      (a).这种机制也并没有真正意义上限制我们从外部直接访问属性,知道了类名和属性名就可以拼出名字:_类名__属性,然后就可以访问了,如a._A__N。

      (b).“__属性”变形到“_类名__属性”只在类的内部生效,在定义后的进行的近似私有化赋值操作,不会变形,为正常的赋值过程。

    2、私有方法

      私有化方法也只能在类的内部进行进行使用,有一些方法的返回值只是用来作为中间结果,可以进行私有化,如下例:

    class Teacher:
        def __init__(self,name,pwd):
            self.name=name
            self.__pwd=pwd                                    #私有属性
        def __func(self):                                     #私有方法
            return hash(self.__pwd)
        def login(self,password):
            return hash(password)==self.__func()
    
    alex=Teacher('alex','1234')
    ret=alex.login('2234')
    print(ret)                                                #输出结果为:False    

      在继承中,父类如果不想让子类覆盖自己的方法,可以将方法定义为私有的。

    class Foo:
        def __jinghong_sb(self):                             #变形为:_Foo__jinghong_sb
            print('Foo')
    class Son(Foo):
        def __jinghong_sb(self):                             #变形为:_Son__jinghong_sb
            print('Son')
        def func(self):
            self.__jinghong_sb()                             #变形为:_Son__jinghong_sb,
    
    son = Son()
    son.func()                                               #结果为:son

    3、property方法

      实现类中的方法时,以查看类的属性的方式进行,即将类中的方法看起来像属性而不是方法。如下例:

    #例1:
    class
    Person: def __init__(self,name,height,weight): self.name = name self.__height = height self.__weight = weight @property def bmi(self): return self.__weight / (self.__height**2) jinghong = Person('景弘',1.8,94) print(jinghong.name,jinghong.bmi) #输出结果:景弘 29.012345679012345

     

    #例2:
    import math
    class Circle:
        def __init__(self,radius): 
            self.radius=radius
    
        @property
        def area(self):
            return math.pi * self.radius**2               #计算面积
    
        @property
        def perimeter(self):
            return 2*math.pi*self.radius                  #计算周长
    
    c=Circle(10)
    print(c.radius)
    print(c.area)                                         #可以向访问数据属性一样去访问area,会触发一个函数的执行,动态计算出一个值
    print(c.perimeter)                                    #可以向访问数据属性一样去访问area,会触发一个函数的执行,动态计算出一个值

      将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则。以上不可以通过赋值对jinghong.bmi、c.area、c.perimeter进行更改。一个静态属性property本质就是实现了get,set,delete三种方法,具体实例如下:

    class Shop:
        discount = 0.75
        def __init__(self,name,price):
            self.name = name
            self.__price = price
        @property          
        def price(self):
            return self.__price * Shop.discount
        @price.setter      
        def price(self,new_price):
            self.__price = new_price
        @price.deleter
        def price(self):
            del self.__price
    
    apple = Shop('apple',5)
    print(apple.price)                                   #获取商品价格
    print(apple.__dict__)                                #输出结果:{'name': 'apple', '_Shop__price': 5}
    apple.price = 6                                      #修改商品原价
    print(apple.price)
    print(apple.__dict__)                                #输出结果:{'name': 'apple', '_Shop__price': 6}
    del apple.price                                      #删除商品原价
    print(apple.__dict__)                                #输出结果:{'name': 'apple'}
      注意:只有在属性AAA定义property后才能定义AAA.setter,AAA.deleter,如上例且各属性方法名需一样,均为price。
    4、classmethod和staticmethod
      (1)普通方法:
    必须传一个对象 可以使用对象的属性和类的属性
    class A:
        def __init__(self,name):
            self.name = name
    
        def func(self):                                 #普通方法,self为形式参数
            print( self.name)
      (2)类方法(classmethod):必须传一个类,方法不需要使用对象的属性,但可以使用类的属性
    class A:
        role = 'a'
        @classmethod
        def class_method(cls):                          #类方法,cls代表类
            print(cls.role)
    A.class_method()                                    #输出结果:a类名.方法名()调用

      (3)静态方法(staticmethod):没有必须传的参数,方法不需要用对象的属性和类的属性

    class Staticmethod_Demo():
        role = 'dog'
        @staticmethod
        def func():                                   #静态方法,不需要参数
            print("a")
    Staticmethod_Demo.func()                          #调用方式:类名.方法名()
      使用情况:不能将函数独立的放在类外面 完全使用面向对象编程的时候,并且这个函数完全不需要依赖对象的属性和类的属性, 就可以用staticmethod装饰这个函数。
     
     
     
     
  • 相关阅读:
    Linux中设置tomcat启动内存
    Linux访问Windows磁盘实现共享
    mysql 5.7 ONLY_FULL_GROUP_BY问题
    MAVENCOMPILERPLUGIN编译错误FATAL ERROR: UNABLE TO FIND PACKAGE JAVA.LANG IN CLASSPATH OR BOOTCLASSPATH
    Linux共享Window文件夹权限问题
    Linux之解决每次git pull/git push都需输入密码设置
    20192427李睿智汇编语言学习笔记(14章)
    双亲委派机制
    字体颜色渐变
    视频播放器
  • 原文地址:https://www.cnblogs.com/seven-007/p/7562522.html
Copyright © 2020-2023  润新知