zoukankan      html  css  js  c++  java
  • Day8 封装 静态属性property

    封装:将类的属性隐藏

    #先看如何隐藏

    1,在定义的属性之前加入__.

    class Foo:
        __N=111111 #_Foo__N
        def __init__(self,name):
            self.__Name=name #self._Foo__Name=name
    
        def __f1(self): #_Foo__f1
            print('f1')
        def f2(self):
            self.__f1() #self._Foo__f1()    #在类内部调用的话可以
    f=Foo('egon')


    #这种隐藏需要注意的问题: 
    #1:这种隐藏只是一种语法上变形操作,并不会将属性真正隐藏起来
    # print(Foo.__dict__)
    # print(f.__dict__)
    # print(f._Foo__Name)
    # print(f._Foo__N)

    第二个问题:这种语法上的变形是在什么时候发生的

    #在定义类阶段发生,并且只在这个阶段发生

    比如说在上面的基础上,再定义一个Foo.__x=12121212121212121212

    再去访问Foo.__x这个属性,

    是可以访问的到的,不会被隐藏

    第三个问题:在子类定义的__x不会覆盖在父类定义的__x,因为子类中变形成了:_子类名__x,而父类中变形成了:_父类名__x,即双下滑线开头的属性在继承给子类时,子类是无法覆盖的。

    #封装不是单纯意义上的隐藏

    1,封装数据属性(内部能用,外部不能用,开一个接口给其他人使用,保证代码安全性)

      

      将属性隐藏起来,然后提供对外访问属性的接口,关键是我们在接口内定制一些控制逻辑从而严格控制对数据属性的使用

     1 class People:
     2     def __init__(self,name,age):
     3         if not isinstance(name,str):
     4             raise TypeError('%s must be str' %name)
     5         if not isinstance(age,int):
     6             raise TypeError('%s must be int' %age)
     7         self.__Name=name
     8         self.__Age=age
     9     def tell_info(self):
    10         print('<名字:%s 年龄:%s>' %(self.__Name,self.__Age))
    11 
    12     def set_info(self,x,y):
    13         if not isinstance(x,str):
    14             raise TypeError('%s must be str' %x)
    15         if not isinstance(y,int):
    16             raise TypeError('%s must be int' %y)
    17         self.__Name=x
    18         self.__Age=y
    19 
    20 #p=People('egon',18)
    21 #p.tell_info()
    22 
    23 # p.set_info('Egon','19')
    24 #p.set_info('Egon',19)
    25 #p.tell_info()

    2,封装函数属性

       目标隔离复杂度。

      例如ATM内部有很多负复杂的函数,内部定义,但是对于用户来说,只需要记住取款,存款这几个功能就可以了。

     1 class ATM:
     2     def __card(self):
     3         print('插卡')
     4     def __auth(self):
     5         print('用户认证')
     6     def __input(self):
     7         print('输入取款金额')
     8     def __print_bill(self):
     9         print('打印账单')
    10     def __take_money(self):
    11         print('取款')
    12 
    13     def withdraw(self):
    14         self.__card()
    15         self.__auth()
    16         self.__input()
    17         self.__print_bill()
    18         self.__take_money()
    19 
    20 a=ATM()
    21 a.withdraw()

    静态属性property:

    在类里面加入这个参数以后,调用函数不用加括号了。(加括号会报错)

    相当于把功能伪装成一个数据,eg:

     1 class Foo:
     2     @property    #这里相当于把函数直接伪装了
     3     def f1(self):
     4          print('f1')
     5 
     6 
     7 f=Foo()
     8 
     9 # f.f1()
    10 
    11 f.f1

    写一个例子:

    '''
    例:BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,如果我们将其做成一个属性,更便于理解)
    成人的BMI数值:
    过轻:低于18.5
    正常:18.5-23.9
    过重:24-27
    肥胖:28-32
    非常肥胖, 高于32
      体质指数(BMI)=体重(kg)÷身高^2(m)
      EX:70kg÷(1.75×1.75)=22.86
    '''
    
    class People:
        def __init__(self,name,weight,height):
            self.name=name
            self.weight=weight
            self.height=height
        @property
        def bmi(self):
            return self.weight / (self.height**2)
    
    # p=People('egon',75,1.80)
    # p.height=1.86
    # print(p.bmi())  #这里是在没有加property这个属性的时候用的
    # print(p.bmi)    #在这里就可以直接输出值了

    怎么功能添加访问,设置,删除的属性。

    是在函数已经设置了静态属性的前提下,在设置函数.setter,函数.deleter等属性

     1 class Foo:
     2     def __init__(self,x):
     3         self.__Name=x
     4 
     5     @property
     6     def name(self):
     7         return self.__Name
     8 
     9     @name.setter
    10     def name(self,val):
    11         if not isinstance(val,str):
    12             raise TypeError
    13         self.__Name=val
    14 
    15     @name.deleter
    16     def name(self):
    17         # print('=-====>')
    18         # del self.__Name
    19         raise PermissionError
    20 
    21 # f=Foo('egon')
    22 # print(f.name)
    23 # 
    24 # # f.name='Egon'
    25 # f.name=123123123213
    26 # print(f.name)
    27 # 
    28 # del f.name
    29 # print(f.name)

      

  • 相关阅读:
    关于类型转换构造函数的疑惑点
    类模板与静态 成员变量
    模板与友元
    类模板与派生
    类模板
    函数模板
    泛型程序设计基本概念
    3、成员函数
    条款 06:若不想使用编译器自动生成的函数,就该明确拒绝
    PHP操作redis
  • 原文地址:https://www.cnblogs.com/sexiaoshuai/p/7417003.html
Copyright © 2011-2022 走看看