zoukankan      html  css  js  c++  java
  • python之封装

    python之封装

    一、封装:

    什么是封装呢?(封装不是单纯意义的隐藏,其实它还是可以查看的)

      就是把一些不想让别人看的给隐藏起来了

    封装数据:目的是保护隐私

    功能封装:目的是隔离复杂度

    如果用了私有的,在类的外部,无法直接使用变形的属性,但是在类的内部可以直接使用

     1 1.用我们常用的__init__方法里的self取值
     2 class Course:#恰好给我们提供了实现这种思路的方法
     3 #             #一种思路,python
     4     def __init__(self,price,period,name):
     5         self.price = price
     6         self.period = period
     7         self.name = name
     8 c = Course(2000,'linux','6 months')
     9 print(c.period)
    10
    11 2.在类里面定义一个空字典,然后装在字典里面取值
    12 def course(price,name ,period):
    13     dic = {}
    14     dic['price'] = price
    15     dic ['name'] = name
    16     dic ['period'] = period
    17     return dic
    18
    19 c = Course(2000,'python','6 months')
    20 print(c.period)  #对象名.属性名     查看属性的值
    21
    22 3.利用namedtuple方法
    23 from collections import namedtuple  #只有属性没有方法的类
    24 Course = namedtuple('Course',['name','price','period']) #传两个参数,第一个为自定义的名字,第二个传进去的是属性
    25 python = Course('python',10000,'6 moths')  #相当于实例化了
    26 print(python.name)
    对象名.属性名取值的三种方法

    2.封装类属性的私有属性(就是类属性前面加__)

     1 class Goods:
     2     # 按照打八折计算 (定义了一个私有类属性)
     3     __discount = 0.8  #变形后:_Goods__discount
     4     def __init__(self,name,price):
     5         self.name = name
     6         self.price = price
     7     def goods_price(self):
     8         return  self.price * Goods.__discount
     9 apple = Goods('apple',10)
    10 print(apple.goods_price())
    11 # print(Goods.__dict__)  #类名.__dict__
    12 print(Goods._Goods__discount)
    类属性1
     1 # 封装:把你不想让人看的隐藏起来
     2 # 数据封装:目的保护隐私
     3 class Teacher:
     4     __School = 'oldboy'  #类属性
     5     def __init__(self,name,salary):
     6         self.name = name
     7         self .__salary  =  salary  #_Teacher__salary
     8             # 老师的属性   值
     9         #怎么把薪水隐藏起来?
    10         self.__salary=salary
    11     def foo(self):
    12         print('------')
    13
    14 t=Teacher('egon',2000)
    15 print(t.__dict__)
    16 # print(t.name)
    17 print(t._Teacher__salary)#让显示出来
    18 print(Teacher._Teacher__School)  #类属性使用_类名__属性名
    19 t.foo()
    20 #在本类内是可以正常调用的
    21 #在本类外就必须以_类名__属性名调用(但是不建议你调)
    类属性的私有方法

    3.封装类对象的私有属性

    成人的BMI数值:
    过轻:低于18.5
    正常:18.5-23.9
    过重:24-27
    肥胖:28-32
    非常肥胖, 高于32
      体质指数(BMI)=体重(kg)÷身高^2(m)
      EX:70kg÷(1.75×1.75)=22.86
    

      如上面的指标来计算下你自己的体质指数

     1 class Person:
     2     def __init__(self,height,weight,name,sex):
     3         self.__height = height  #私有属性(让你不再外面调它)
     4                                 # 在本类中可以调用,在类外就不可以调用了
     5         self.__weigth = weight
     6         self.__name = name
     7         self.__sex = sex
     8     def tell_bmi(self):  #体重指数
     9         return self.__weigth/self.__height ** 2  #在本类中可以调用
    10
    11     def tell_height(self):
    12         print(self.__height)
    13     def tell_weight(self):  #告诉体重
    14         return  self.__weigth
    15     def set_weigth(self,new_weight):   #修改体重
    16         if new_weight >20:
    17              self.__weigth = new_weight
    18         else:
    19             raise TypeError('你也太瘦了,瘦的连斤数都(快)没了')   #如果体重小于20或者负的,就主动提示一个报错
    20 egg = Person(1.6,96,'haiyan','female')
    21 print(egg.tell_bmi())
    22 # egg.__height #在类外不能调用
    23 # print(egg._Person__height)  #在类外查看得这样调用
    24 print(egg.__dict__)  #查看变形后的类型
    25 # egg.set_weigth(-10)
    26 # print(egg.tell_weigth())
    27 egg.set_weigth(66)  #修改体重为66
    28 print(egg.tell_weight())
    计算体质指数,衡量人健康的标准(对象的私有属性一)
     1 class People:
     2     def __init__(self,name,age,sex,height):
     3         self.__name = name
     4         self.__age = age
     5         self.__sex = sex
     6         self.__height = height
     7
     8     def tell_name(self):  #看人名字
     9         print(self.name)
    10     def set_name(self,val): #修改名字
    11         if not isinstance(val, str):
    12             raise TypeError('名字必须是字符串类型')
    13         self.__name = val
    14     def tell_info(self):
    15          print('''
    16            ---------%s info-----------
    17            name:%s
    18            age:%s
    19            sex:%s
    20            height:%s'''%(self.__name,self.__name,self.__age,self.__sex,self.__height))
    21
    22 p=People('egon',21,'male','180')
    23 p.tell_info()
    24 p.set_name('haiyan')   #调用修改名字的方法
    25 p.tell_info()
    26 # print(p._People__name)#就可以看到了
    对象属性的私有属性二

    4.封装类方法的私有属性

     1 # 方法的私有属性
     2 class Parent:
     3     def __init__(self):
     4         self.__func()  #__func==_Parent__func
     5     def __func(self):
     6         print('Parent func')
     7
     8 class Son(Parent):
     9     def __init__(self):
    10         self.__func()  #_Son__func
    11     def __func(self):
    12         print('Son func')
    13
    14     def _Parent__func(self):
    15         print('son _Parent__func')
    16 s = Son()
    17 print(Parent.__dict__)  #类名.__dict__查看变形后的结果
    18
    19 # 私有属性:在本类内是可以正常调用的
    20 #           在本类外就必须以_类名__属性名调用(但是不建议你调)
    类方法的私有属性1
    1 class Foo:
    2     def __func(self):
    3         print('from foo')
    4 class Bar(Foo):
    5     def __func(self):
    6         print('from bar')
    7 b = Bar()
    8 b._Foo__func()
    9 b._Bar__func()
    方法的私有属性2
     1 class Foo:
     2     def __init__(self,height,weight):
     3         self.height = height
     4         self.weight = weight
     5     def __heightpow(self):  #私有方法
     6         return self.height * self.height
     7     def tell_bmi(self):
     8         return self.weight/self.__heightpow()
     9
    10 egon = Foo(1.7,120)
    11 print(egon.tell_bmi())
    12 print(Foo.__dict__)
    13 print(egon._Foo__heightpow())  #虽说是私有的,但是还是可以查看的
    装饰方法的私有属性3

     5.property

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

    1.计算圆的面积和周长

     1 from math import pi
     2 class Circle:
     3     def __init__(self,radius):
     4         self.radius = radius
     5     @property  #装饰器:把一个方法当成一个属性用了
     6     def area(self):
     7         return self.radius * self.radius* pi
     8     @property
     9     def peimeter(self):
    10         return 2*pi*self.radius
    11
    12 c = Circle(10)
    13 print(c.area)  #当成一个属性来调了,就不用加括号了
    14 print(c.peimeter)
    property

     2.缓存网页信息

     1 from urllib.request import urlopen
     2 class Web_page:
     3     def __init__(self,url):
     4         self.url = url
     5         self.__content = None  #内容设置为None
     6     @property
     7     def content(self):
     8         if self.__content:  #如果不为空,就说明已经下载了  _Web_page__content
     9             return self.__content
    10         else:
    11             self.__content = urlopen(self.url).read()#做缓存
    12             return self.__content
    13 mypage = Web_page('http://www.baidu.com')
    14 print(mypage.content)
    15 print(mypage.content)
    16 print(mypage.content)
    property(2)

    3.求和,平均值,最大值,最小值

     1 class Num:
     2     def __init__(self,*args):
     3         print(args)
     4         if len(args)==1 and (type(args[0]) is list or type(args[0]) is tuple):
     5             self.numbers=args[0]
     6         else:
     7             self.numbers = args
     8
     9     @property
    10     def sum(self):
    11         return sum(self.numbers)
    12
    13     @property
    14     def avg(self):
    15         return self.sum/len(self.numbers)
    16
    17     @property
    18     def min(self):
    19         return min(self.numbers)
    20
    21     @property
    22     def max(self):
    23         return max(self.numbers)
    24 num = Num([3,1,3])
    25 vvv = Num(8,2,3)
    26 print(num.sum)
    27 print(num.min)
    28 print(num.avg)
    29 print(num.max)
    30 print('-----------')
    31 print(vvv.sum)
    32 print(vvv.min)
    33 print(vvv.avg)
    34 print(vvv.max)
    property(3)

     6.setter

     1 class Goods:
     2     __discount = 0.8  #类的私有属性
     3     def __init__(self,name,price):
     4         self.name = name
     5         self.__price = price
     6
     7     @property
     8     def price(self):
     9         # if hasattr(self,'__price'):
    10             return self.__price * Goods.__discount
    11         # else:
    12         #     raise NameError
    13
    14     @price.setter
    15     def price(self,new_price):
    16         if type(new_price) is int:
    17             self.__price = new_price
    18
    19     @price.deleter
    20     def price(self):
    21         del self.__price
    22
    23 apple = Goods('apple',10)
    24 # print(apple.price)
    25 apple.price = 20
    26 print(apple.price)
    27
    28 # del apple.price
    29 # print(apple.price)
    30 # apple.set_price(20)
    31 # apple._Goods__apple
    买东西
    @property把一个类中的方法 伪装成属性
    原来是obj.func()
    现在是obj.func -->属性
    1.因为属性不能被修改
    所以用了@funcname.setter
    obj.func = new_value 调用的是被@funcname.setter装饰器装饰的方法
    被@property装饰的方法名必须和被@funcname.setter装饰的方法同名
    2.也可以另一种方法修改,但是上一种方法吧一个类中的方法伪装成属性来调用了,而这种方法
    还是原来实例化一样调用
    例如:
     1 class People:
     2     def __init__(self,name,age,sex,height):
     3         self.__name = name
     4         self.__age = age
     5         self.__sex = sex
     6         self.__height = height
     7
     8     def tell_name(self):  #看人名字
     9         print(self.name)
    10     def set_name(self,val): #修改名字
    11         if not isinstance(val, str):
    12             raise TypeError('名字必须是字符串类型')
    13         self.__name = val
    14     def tell_info(self):
    15          print('''
    16            ---------%s info-----------
    17            name:%s
    18            age:%s
    19            sex:%s
    20            height:%s'''%(self.__name,self.__name,self.__age,self.__sex,self.__height))
    21
    22 p=People('egon',21,'male','180')
    23 p.tell_info()
    24 p.set_name('haiyan')   #调用修改名字的方法
    25 p.tell_info()
    26 # print(p._People__name)#就可以看到了
  • 相关阅读:
    javaweb请求编码 url编码 响应编码 乱码问题 post编码 get请求编码 中文乱码问题 GET POST参数乱码问题 url乱码问题 get post请求乱码 字符编码
    windows查看端口占用 windows端口占用 查找端口占用程序 强制结束端口占用 查看某个端口被占用的解决方法 如何查看Windows下端口占用情况
    javaWeb项目中的路径格式 请求url地址 客户端路径 服务端路径 url-pattern 路径 获取资源路径 地址 url
    ServletRequest HttpServletRequest 请求方法 获取请求参数 请求转发 请求包含 请求转发与重定向区别 获取请求头字段
    HttpServletResponse ServletResponse 返回响应 设置响应头设置响应正文体 重定向 常用方法 如何重定向 响应编码 响应乱码
    Servlet主要相关类核心类 容器调用的过程浅析 servlet解读 怎么调用 Servlet是什么 工作机制
    linq查询语句转mongodb
    winddows rabbitmq安装与配置
    Redis For Windows安装及密码
    出现,视图必须派生自 WebViewPage 或 WebViewPage错误解决方法
  • 原文地址:https://www.cnblogs.com/morgana/p/8491247.html
Copyright © 2011-2022 走看看