类的封装(property)

封装

封装程序的主要原因:保护隐私;而封装方法的主要原因是:隔离复杂的执行过程

  • property的特性

将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则

import math
class circular:
    def __init__(self,radius,):
        self.radius=radius
    @property       #area=property(area)
    def area(self):
        #print("圆的面积是:%s"%(int(self.radius)**2*self.Pi))
        res=int(self.radius)**2*math.pi
        print(res)
        return res
    @property       #circumference=property(circumference)
    def circumference(self):
       # print("圆的周长是:%s"%(self.Pi*2*int(self.radius)))
        res1=math.pi*2*int(self.radius)
        print(res1)
        return res1
t=circular("3")
t.area
t.circumference

"D:Program Filespython.exe" "E:/py_code/day 12/类的封装.py"
28.274333882308138
18.84955592153876

Process finished with exit code 0

这里需要知道的用户在执行obj.area或者obj.circumference不能被赋值的,因为实际上执行的过程我们是调用的是一个函数,这里只是被伪装成一个对象的属性。所以这里需要特别注意

  • 隐藏--功能

其次也有另一种方式:

class people:
    def __init__(self,name,age,sex,height,weight):
        self.__name=name  #self.__name=_people__name
        self.__age=age
        self.__sex=sex
        self.__height=height
        self.__weight=weight
    def tell_name(self):
        print(self._name)
    def set_name(self,val):
        if not isinstance(val,str):
            raise TypeError("名字必须是字符串类型")
        self.__name=val
    def tell_info(self):
        print('''
        ------------%s info----------
        name:%s
        age:%s
        sex:%s
        height:%s
        weight:%s
        ----------- info------------
        ''' %(self.__name,
                self.__name,
                self.__age,
                self.__sex,
                self.__height,
                self.__weight))


t1=people("whatmini",18,"man","64kg","1.75")
t1.tell_info()
print(t1._people__age)



"D:Program Filespython.exe" "E:/py_code/day 12/类.py"

        ------------whatmini info----------
        name:whatmini
        age:18
        sex:man
        height:64kg
        weight:1.75
        ----------- info------------
        
18

Process finished with exit code 0

上述中self.__name=name实际就是将name的结果封装起来,真实存放的位置在self._people中,但是我们如果想要去访问则需要obj._people__name才能找到真实信息。很明显我们需要给用户提供提供一个封装好的接口给到其访问所以如下:

class people:
    def __init__(self,name,age,sex,height,weight):
        self.__name=name  #self.__name=_people__name
        self.__age=age
        self.__sex=sex
        self.__height=height
        self.__weight=weight
    @property
    def name(self):
        return self.__name   # 用户查询name时会直接将name返回
    def set_name(self,val):
        if not isinstance(val,str):
            raise TypeError("名字必须是字符串类型")
        self.__name=val
    def tell_info(self):
        print('''
        ------------%s info----------
        name:%s
        age:%s
        sex:%s
        height:%s
        weight:%s
        ----------- info------------
        ''' %(self.__name,
                self.__name,
                self.__age,
                self.__sex,
                self.__height,
                self.__weight))


t1=people("whatmini",18,"man","64kg","1.75")
print(t1.name)


"D:Program Filespython.exe" "E:/py_code/day 12/类.py"
whatmini

Process finished with exit code 0

这里同样我们会遇到一个问题就是如何去修改对象的属性,用户在调用对象属性时有时会对属性进行修改和删除的操作,但是此时的属性是被封装后的一个函数,所以这里要用到下面的两个函数:

  • obj.setter
class people:
    def __init__(self,name,age,sex,height,weight):
        self.__name=name  #self.__name=_people__name
        self.__age=age
        self.__sex=sex
        self.__height=height
        self.__weight=weight
    @property
    def name(self):
        return self.__name   # 用户查询name时会直接将name返回

    @name.setter
    def name(self,val):
        if not isinstance(val,str):
            raise TypeError("%s must be str"%val)   #设置报错机制当指定用户的输入类型
        self.__name=val #当用户输入的类型合格后则将用户的修改的值进行重新赋值
    def tell_info(self):
        print('''
        ------------%s info----------
        name:%s
        age:%s
        sex:%s
        height:%s
        weight:%s
        ----------- info------------
        ''' %(self.__name,
                self.__name,
                self.__age,
                self.__sex,
                self.__height,
                self.__weight))


t1=people("whatmini",18,"man","64kg","1.75")
t1.name="shan"
print(t1.name)


"D:Program Filespython.exe" "E:/py_code/day 12/类.py"
shan

Process finished with exit code 0
  • obj.name
class people:
    def __init__(self,name,age,sex,height,weight,tag=False):
        self.__name=name  #self.__name=_people__name
        self.__age=age
        self.__sex=sex
        self.__height=height
        self.__weight=weight
        self.tag=tag               #设定标志位,当tag=True
    @property
    def name(self):
        return self.__name   # 用户查询name时会直接将name返回

    @name.setter
    def name(self,val):
        if not isinstance(val,str):
            raise TypeError("%s must be str"%val)   #设置报错机制当指定用户的输入类型
        self.__name=val #当用户输入的类型合格后则将用户的修改的值进行重新赋值
    @name.deleter
    def name(self):
        if not self.tag:
            raise PermissionError("Cannot perform")
        del self.__name

    def tell_info(self):
        print('''
        ------------%s info----------
        name:%s
        age:%s
        sex:%s
        height:%s
        weight:%s
        ----------- info------------
        ''' %(self.__name,
                self.__name,
                self.__age,
                self.__sex,
                self.__height,
                self.__weight))


t1=people("whatmini",18,"man","64kg","1.75",True)
t1.name="shan"
del t1.name
print(t1.name)


"D:Program Filespython.exe" "E:/py_code/day 12/类.py"
Traceback (most recent call last):
  File "E:/py_code/day 12/类.py", line 262, in <module>
    print(t1.name)
  File "E:/py_code/day 12/类.py", line 229, in name
    return self.__name   # 用户查询name时会直接将name返回
AttributeError: 'people' object has no attribute '_people__name'

Process finished with exit code 1

这里可以看到我们已经将name这个对象属性删掉了。所以查看时编译器会进行报错。

原文地址:https://www.cnblogs.com/lijian-22huxiaoshan/p/7133158.html