• Python——封装


    封装指的是将对象的状态信息隐藏在对象内部,不允许外部直接访问对象内部信息,而是通过该类提供的方法来实现对内部信息的操作和访问;封装的含义,实际上,是把该隐藏的隐藏起来,该暴露的暴露出来;Python只需要将类的成员名为以双下划线开头,就可以隐藏类中的成员。

    一、封装数据属性

    例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    class Fraction:
        __grade = 0
        def __init__(self,name):
            self.__name = name
             
        def setting_grade(self,var):
            if isinstance(var,intand var >= 0 and var <=100:
                Fraction.__grade = var
            else:
                print ('请输入正确的分数!')
                 
        def setting_name(self,set_name):
            if isinstance(set_name,str):
                self.__name = set_name
            else:
                print ('请输入正确的姓名!')
                 
        def get_fraction(self):
            print ('%s分数是:%s'%(self.__name,Fraction.__grade))
     
    = Fraction('小黄')   
    print (F.__grade)    # 报错 AttributeError: 'Fraction' object has no attribute '__grade'
    print (F.__name)    # 报错 AttributeError: 'Fraction' object has no attribute '__name'
     
    F.get_fraction()    # 打印 小黄分数是:0
     
    F.setting_name('小明')
    F.setting_grade(100)    # setting_grade()、setting_name()会对用户设置grade、name进行控制,符合条件才能允许设置
     
    F.get_fraction()    # 打印 小明分数是:100
     
    # 可以使用 _类名来访问或修改对象的实例变量
    print (F._Fraction__grade)    # 打印 100
    print (F._Fraction__name)    # 打印 小明

    上面例子中,代码print (F.__grade)和print (F.__name)直接访问私有变量会报错setting_grade()、setting_name()方法用于对grade、name进行设置,只有符合条件才能允许设置;print (F._Fraction__grade)和print (F._Fraction__name)通过 _类名来访问对象的实例变量(通常不要这么做),可以看出Python并没有实现真正隐藏,只是改变以双下划线开头的变量,在这些变量前添加单下画线和变量名。

    二、封装函数属性

    例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    class SumFraction:
        def __init__(self,usually,test):
            self.__usually = usually
            self.__test = test
             
        def set_usually_score(self,usually_var):
            if isinstance(usually_var,intand usually_var >= 0 and usually_var <=100:
                self.__usually = usually_var
            else:
                print ('请输入正确的分数!')
                 
        def set_test_score(self,test_var):
            if isinstance(test_var,intand test_var >= 0 and test_var <=100:
                self.__test = test_var
            else:
                print ('请输入正确的分数!')
                 
        def __calculation(self):    # 私有方法,只能内部使用,对外部隐藏运算逻辑
            return self.__usually * 0.3 + self.__test * 0.7
         
        def final_grade(self):
            return self.__calculation()
     
    = SumFraction(100,50)
    print (S.final_grade())    # 打印 65.0
    print (S.__calculation())    # 调用隐藏的__calculation()方法,会报错 AttributeError: 'SumFraction' object has no attribute '__calculation'
    print (S._SumFraction__calculation())    # 可以使用_类名方法名调用(不推荐这样做),打印 65.0
     
    # 修改__usually和__test
    S.set_usually_score(70)
    S.set_test_score(100)
    print (S.final_grade())    # 通过final_grade()方法内部进行访问__calculation()私有方法,打印 91.0

    上面代码中,set_usually_score()和set_test_score()用于对usually 、test进行设置;__calculation()是私有方法,默认是隐藏的,只允许内部使用,外部使用会报错,当然也可以使用_类名方法名调用,但并不推荐这么做;print (S.final_grade())通过final_grade()方法内部访问__calculation()私有方法。

    三、property

    先看一下帮助文档:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    >>> help(property)
    Help on class property in module builtins:
     
    class property(object)
     |  property(fget=None, fset=None, fdel=None, doc=None)
     
     |  Property attribute.
     
     |    fget
     |      function to be used for getting an attribute value
     |    fset
     |      function to be used for setting an attribute value
     |    fdel
     |      function to be used for del'ing an attribute
     |    doc
     |      docstring
     
     |  Typical use is to define a managed attribute x:
     
     |  class C(object):
     |      def getx(self): return self._x
     |      def setx(self, value): self._x = value
     |      def delx(self): del self._x
     |      x = property(getx, setx, delx, "I'm the 'x' property.")
     
     |  Decorators make defining new properties or modifying existing ones easy:
     
     |  class C(object):
     |      @property
     |      def x(self):
     |          "I am the 'x' property."
     |          return self._x
     |      @x.setter
     |      def x(self, value):
     |          self._x = value
     |      @x.deleter
     |      def x(self):
     |          del self._x
     
     |  Methods defined here:
     
     |  __delete__(self, instance, /)
     |      Delete an attribute of instance.
     
     |  __get__(self, instance, owner, /)
     |      Return an attribute of instance, which is of type owner.
     
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     
     |  __init__(self/*args, **kwargs)
     |      Initialize self.  See help(type(self)) for accurate signature.
     
     |  __set__(self, instance, value, /)
     |      Set an attribute of instance to value.
     
     |  deleter(...)
     |      Descriptor to change the deleter on a property.
     
     |  getter(...)
     |      Descriptor to change the getter on a property.
     
     |  setter(...)
     |      Descriptor to change the setter on a property.
     
     |  ----------------------------------------------------------------------
     |  Static methods defined here:
     
     |  __new__(*args, **kwargs) from builtins.type
     |      Create and return a new object.  See help(typefor accurate signature.
     
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     
     |  __isabstractmethod__
     
     |  fdel
     
     |  fget
     
     |  fset

      

    @property 可以在一个类中把方法变成同名属性调用,能用属性的方式来访问该属性。

    @x.setter 表示可写,最大作用是用于限制属性的定义,x是被@property修饰的方法名,@x.setter修饰的方法名@property修饰的方法名必须同名。

    @x.deleter 表示可删除,x是被@property修饰的方法名,@x.deleter修饰的方法名@property修饰的方法名必须同名。

    例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    class SumFraction:
         
        def __init__(self,value):
            self.__score = value
     
        @property    # 读
        def score(self):
            print ('读......')
            return self.__score
             
        @score.setter       # 写
        def score(self,var):
            print ('写......')
            if isinstance(var,intand var >= 0 and var <=100:
                self.__score = var
                return self.__score
            else:
                print ('请输入正确的分数!')
                return
     
        @score.deleter    # 删除
        def score(self):
            print ("删除self.__score......")
            del self.__score
     
                     
     
    = SumFraction(100)
    S.score = 80    # 写,打印 改......
     
    print (S.score)   
    '''
    读,打印
    读......
    80
    '''
     
    del S.score    # 删除,打印 删除self.__score......
    print (S.score)    # __score已被删除,打印 AttributeError: 'SumFraction' object has no attribute '_SumFraction__score'

      

    用property类来实现,例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    class SumFraction:
         
        def __init__(self,value):
            self.__score = value
     
        def get_score(self):
            print ('读......')
            return self.__score
                 
        def set_score(self,var):
            print ('写......')
            if isinstance(var,intand var >= 0 and var <=100:
                self.__score = var
                return self.__score
            else:
                print ('请输入正确的分数!')
                return
     
        def del_score(self):
            print ("删除self.__score......")
            del self.__score
     
        score = property(get_score,set_score,del_score,'这里是属性含义~ ')
                     
     
    = SumFraction(100)
    S.score = 80    # 写,打印 改......
     
    print (S.score)   
    '''
    读,打印
    读......
    80
    '''
     
    print (SumFraction.score.__doc__)  # 属性含义,打印 这里是属性含义~
     
    del S.score    # 删除,打印 删除self.__score......
    print (S.score)    # __score已被删除,打印 AttributeError: 'SumFraction' object has no attribute '_SumFraction__score'
  • 相关阅读:
    [HEOI2014]人人尽说江南好 博弈论
    [HNOI2014]江南乐 博弈论
    [SDOI2011]黑白棋 kth
    [NOI2011]兔兔与蛋蛋游戏 二分图博弈
    [JSOI2009]游戏 二分图博弈
    口胡:[HNOI2011]数学作业
    【POJ】【2068】Art Gallery
    【CTSC 2015】&【APIO 2015】酱油记
    【BZOJ】【4052】【CERC2013】Magical GCD
    【BZOJ】【2750】【HAOI2012】Road
  • 原文地址:https://www.cnblogs.com/qqmb/p/11165556.html
Copyright © 2020-2023  润新知