封装 python之--------封装

一、封装:

补充封装:

复制代码
封装:
        体现在两点:
            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'] = 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 # 封装:把你不想让人看的隐藏起来
 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.封装类对象的私有属性

?
1
2
3
4
5
6
7
8
成人的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 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()
复制代码
复制代码
 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()) #虽说是私有的,但是还是可以查看的
复制代码

 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)
复制代码

 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)
复制代码

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)
复制代码

 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)#就可以看到了
复制代码
 
       
       
     

一、封装:

补充封装:

复制代码
封装:
        体现在两点:
            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'] = 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 # 封装:把你不想让人看的隐藏起来
 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.封装类对象的私有属性

?
1
2
3
4
5
6
7
8
成人的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 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()
复制代码
复制代码
 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()) #虽说是私有的,但是还是可以查看的
复制代码

 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)
复制代码

 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)
复制代码

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)
复制代码

 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)#就可以看到了
复制代码
 
 

猜你喜欢

转载自www.cnblogs.com/kcwxx/p/10145146.html