【第8篇】:Python之面向對象
阿新 • • 發佈:2019-02-27
查看 event news 衡量 goods 執行 init 隱藏 ecb
python之--------封裝
一、封裝:
補充封裝:
封裝: 體現在兩點: 1、數據的封裝(將數據封裝到對象中) obj = Foo(‘寶寶‘,22) 2、封裝方法和屬性,將一類操作封裝到一個類中
class Foo: def __init__(self,name,age): self.name = name self.age = agedef 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‘] = 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)#就可以看到了View Code
【第8篇】:Python之面向對象