博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python之封装
阅读量:4668 次
发布时间:2019-06-09

本文共 8621 字,大约阅读时间需要 28 分钟。

一、封装:

体现在两点:1、数据的封装(将数据封装到对象中)	obj = Foo('宝宝',22)2、封装方法和属性,将一类操作封装到一个类中   class Foo:	def __init__(self,name,age):	    self.name = name	    self.age = age 	def show (self):	    print(self.name,self.age)

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

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

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

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

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

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'] = price15     dic ['name'] = name16     dic ['period'] = period17     return dic18 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)
对象名.属性名取值的三种方法

 二、封装类属性的私有属性(就是类属性前加__)

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

三、封装类对象的私有属性

成人的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.__weigth15     def set_weigth(self,new_weight):   #修改体重16         if new_weight >20:17              self.__weigth = new_weight18         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)  #修改体重为6628 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 = val14     def tell_info(self):15          print('''16            ---------%s info-----------17            name:%s18            age:%s19            sex:%s20            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)#就可以看到了
对象属性的私有属性二

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

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__func11     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

 五.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.radius11 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.__content10         else:11             self.__content = urlopen(self.url).read()#做缓存12             return self.__content13 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     @property10     def sum(self):11         return sum(self.numbers)12 13     @property14     def avg(self):15         return self.sum/len(self.numbers)16 17     @property18     def min(self):19         return min(self.numbers)20 21     @property22     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)

 六、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.__discount11         # else:12         #     raise NameError13 14     @price.setter15     def price(self,new_price):16         if type(new_price) is int:17             self.__price = new_price18 19     @price.deleter20     def price(self):21         del self.__price22 23 apple = Goods('apple',10)24 # print(apple.price)25 apple.price = 2026 print(apple.price)27 28 # del apple.price29 # 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 = val14     def tell_info(self):15          print('''16            ---------%s info-----------17            name:%s18            age:%s19            sex:%s20            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)#就可以看到了
View Code
 

转载于:https://www.cnblogs.com/lianxuebin/p/7400077.html

你可能感兴趣的文章
MySQL高可用架构故障自动转移插件MHA
查看>>
lnmp之nginx1.10.2安装
查看>>
recv send 阻塞和非阻塞
查看>>
网络丢包分析
查看>>
打印LIS
查看>>
剑指offer第2章学习(2)
查看>>
java后台验证码的生成
查看>>
Bootstrap辅助类
查看>>
vue项目的骨架及常用组件介绍
查看>>
Spring使用外部的配置文件
查看>>
ctype
查看>>
jsp 修饰 Request 及Response
查看>>
HDU 2389 Rain on your Parade / HUST 1164 4 Rain on your Parade(二分图的最大匹配)
查看>>
对象的类型转换P109
查看>>
sqlite 查询表和字段是否存在
查看>>
http => https 升级
查看>>
Window 分布式学习-好文收藏
查看>>
Android TextUtils类介绍
查看>>
linux echo设置颜色
查看>>
英文参考文献标准格式:论文参考文献格式规范(转载)
查看>>