Python隨心記--函式之面向物件
阿新 • • 發佈:2018-12-30
函式之面向物件
def dog(name,type): def jiao(dog): ret = '一隻%s再叫,哈哈哈' % dog['name'] return ret def chi(dog): ret = '一隻%s在吃飯,吃吃吃' % dog['type'] return ret def init(name,type): dog = { 'name':name, 'type':type, 'jiao':jiao,'chi':chi, } return dog return init(name,type) d1 = dog('小白兔','哈士奇') d2 = dog('小黑兔','阿拉斯加') print(d1['jiao'](d1)) print(d1['chi'](d1)) print(d1['jiao'](d2)) print(d1['chi'](d2))
#面向物件:
類:
動作跟特徵的結合(共同的特徵,共同的動作)
把一類事物的相同的特徵和動作整合到一起
是一個抽象的概念
物件:就是居於類而建立的一個具體的事物
#用面嚮物件語言寫程式和一個程式的設計是面向物件程式設計
#新式類(python2中)
class School(object): def __init__(self,name,type): self.name = name self.type = type def bark(self): return '%s在招生' %self.name d = School('清華','公立') #例項化物件 print(d.bark())
#經典類 (__init__裡面不能return值)
class School: #宣告一個類 def__init__(self,name,type): self.name = name self.type = type def bark(self): return '%s在招生' %self.name d = School('清華','公立') #例項化物件 print(d.bark())
class Chinese: '這是一箇中國類' nationality = '中國' #屬性 ancestralhome = '廣東' #屬性 def __init__(self,name,age,gender): self.name = name self.age = age self.gender = gender def common(self): return '%s人不吃辣' %self.name def commons(self): return '%s人喜歡吃辣' %self print(Chinese.__name__) #列印類名 print(Chinese.__doc__) #列印文件 print(Chinese.__base__) print(Chinese.__bases__) print(Chinese.__module__) #模組 print(Chinese.__class__) chainese = Chinese() print(Chinese.nationality) #訪問屬性 print(Chinese.ancestralhome) #訪問屬性 print(Chinese.common(chainese)) #訪問方法 print(dir(Chinese)) print(Chinese.__dict__) #檢視類的屬性字典 print(Chinese.__dict__['nationality']) #列印類的屬性 print(Chinese.__dict__['ancestralhome']) #列印類的屬性 print(Chinese.__dict__['commons']()) #執行類的方法 chainese = Chinese('廣東','13','中國') print(chainese.__dict__) print(chainese.common())
class Chinese: '這是一箇中國類' nationality = '中國' #屬性 ancestralhome = '廣東' #屬性 def __init__(self,name,age,gender): self.name = name self.age = age self.gender = gender def common(self): return '%s人不吃辣' %self.name def eatfood(self,food): return '%s人喜歡喝%s' %(self.name,food) chainese = Chinese('廣東','13','中國') print(chainese.common()) print(chainese.eatfood('早茶')) Chinese.ancestralhome = '深圳' #修改屬性 chainese.addr = '廣州' #增加屬性 del Chinese.ancestralhome #刪除屬性 def eat_food(self,food): return '%s人喜歡喝%s' % (self.name, food) Chinese.eat = eat_food #增加方法 把eat_food方法增加到Chinese類中 Chinese.common = eat_food #修改 把common方法修改為eat_food # print(chainese.__dict__) print(chainese.eat('茶'))
county = '北京' class Chinese: '這是一箇中國類' nationality = '中國' #屬性 ancestralhome = '廣東' #屬性 def __init__(self,name,age,gender): #print(county) #能列印北京,這裡跟普通變數沒什麼差別,如果用self.county就會報錯 self.name = name self.age = age self.gender = gender def common(self): return '%s人不吃辣' %self.name def eatfood(self,food): return '%s人喜歡喝%s' %(self.name,food) chainese = Chinese('廣東','13','中國')
面向物件之靜態屬性
class Room: tag = 1 #靜態屬性 def __init__(self,name,length,width,hiegh): self.Name = name self.Length = length self.Width = width self.Hiegh = hiegh @property #加上裝飾器 def cal_area(self): return self.Width * self.Length def test(self): print('from test',self.Name) def tall_info(self): print('--->',self.tag) @classmethod # 加上只會tall_info就會變成專門給類使用的方法 def tall_info1(cls): print(cls) print('--->', cls.tag) print('--->', Room.tag) @classmethod # 加上只會tall_info就會變成專門給類使用的方法 def tall_info2(cls,x): print(cls) print('--->', cls.tag, x) room = Room('臥室',100,100,100) print(room.cal_area()) #加上裝飾器@property之前呼叫 print(room.cal_area) #加上裝飾器@property之後呼叫 print(Room.tag) #呼叫屬性 Room.test(room) Room.tall_info(room) 加上裝飾器@classmethod之前呼叫 Room.tall_info1() #加上裝飾器@classmethod之後呼叫 Room.tall_info2(10) #加上裝飾器@classmethod之後呼叫
#靜態方法
class Room: tag = 1 #靜態屬性 def __init__(self,name,length,width,hiegh): self.Name = name self.Length = length self.Width = width self.Hiegh = hiegh @property #加上裝飾器 def cal_area(self): return self.Width * self.Length def test(self): print('from test',self.Name) def tall_info(self): print('--->',self.tag) @classmethod # 加上只會tall_info就會變成專門給類使用的方法 def tall_info1(cls): print(cls) print('--->', cls.tag) print('--->', Room.tag) @classmethod # 加上只會tall_info就會變成專門給類使用的方法 def tall_info2(cls,x): print(cls) print('--->', cls.tag, x) @staticmethod #類的工具包 不能呼叫類變數和例項變數 def wash_boyd(): #可以傳引數也可以不傳引數 print('正在洗澡') room = Room('臥室',100,100,100) Room.wash_boyd() room.wash_boyd()
組合
class Hand: pass class Foot: pass class Head: pass class Trunk: pass class Person: def __init__(self,id_num,name): self.id_num = id_num self.name = name self.hand = Hand() self.food = Foot() self.trunk = Trunk() self.head = Head()
組合(查詢學校資訊)
#學校類 class School: def __init__(self,name,addr): self.name = name self.addr = addr #課程類 class Course: def __init__(self,name,price,perioc,school): self.name = name self.price = price self.perioc = perioc self.school = school schoolo = School('老男孩','北京') schoolt = School('傳 智','天津') schoolh = School('泰 牛','上海') # print(c1.__dict__) msg = ''' 1 老男孩北京校區 2 老男孩天津校區 3 老男孩上海校區 ''' while True: print(msg) menu = { '1' : schoolo, '2' : schoolt, '3' : schoolh, } choice = input('請選擇您想要了解的校區序號>>>:') course = Course('liunx', '10000', '6', menu[choice]) # 把學校類傳給課程類 print('課程屬於【%s】,地址在【%s】' %(course.school.name,course.school.addr)) # 拿到oldboy
#繼承、多型、封裝
繼承
#面向物件之繼承 class ParentClass: money = 100 def __init__(self,name): self.name = name def hit_son(self): return '%s 正在執行' %self.name class ParentClasss: pass class SubClass(ParentClass): #單繼承 pass class SubClasss(ParentClass,ParentClasss): #多繼承 pass sub = SubClass('函式') # print(sub.money) print('子類呼叫父類的hit_son函式',sub.hit_son())
介面繼承:
子類必須實現父類的所有方法
import abc #介面模組 class AllFile(metaclass=abc.ABCMeta): @abc.abstractmethod def read(self): pass @abc.abstractmethod def write(self): pass class Disk(AllFile): def read(self): print('Disk rand') def write(self): print('Disk write') class Cdrom(AllFile): def read(self): print('Cdrom rand') def write(self): print('Cdrom write') class Mem(AllFile): def read(self): print('Mem rand') def write(self): print('Mem write')
#介面繼承順序之mro線性(python3)
class D: pass class E: pass class F(D,E): pass print(F.__mro__)
#在子類中呼叫父類的方法
class Vehicle: Country = 'China' def __init__(self,name,speed,load,power): self.name = name self.speed = speed self.load = load self.power = power def run(self): return '【父類】開動啦............' class Subway(Vehicle): def __init__(self,name,speed,load,power): super().__init__(name,speed,load,power) # super(Subway,self).__init__(name,speed,load,power) # Vehicle.__init__(self,name,speed,load,power) def show_info(self): return self.name,self.speed def run(self): super().run() # Vehicle.run(self) return '%s線開動了' %(self.name),super().run() lin13 = Subway('深圳13號線','10km/h',1000,'電') print(lin13.show_info()) print(lin13.run())
例項
import uuid import pickle import hashlib import time def creat_md5(): m = hashlib.md5() m.update(str(time.time()).encode('utf8')) return m.hexdigest() # id = creat_md5() class Base: def save(self): #把例項物件永久化儲存(檔案方式) with open('school.db','wb') as f: pickle.dump(self,f) class School(Base): def __init__(self,name,addr): self.id = creat_md5() self.name = name self.addr = addr #課程類 class Course(Base): def __init__(self,name,price,perioc,school): self.id = creat_md5() self.name = name self.price = price self.perioc = perioc self.school = school school = School('老男孩','沙河') school.save() school_obj = pickle.load(open('school.db','rb')) #讀出儲存的物件 print(school_obj)
#面向物件之多型
class H2o: def __init__(self,name,temperature): self.name = name self.temperature = temperature def turn_ice(self): if self.temperature < 0: return '【%s】溫度太低結冰了' %self.name elif self.temperature > 100: return '【%s】溫度太高變成蒸汽了' % self.name else: return '【%s】液化成水了' % self.name class Water(H2o): pass class Ice(H2o): pass class Steem(H2o): pass water = Water('水',10) ice = Ice('冰',-20) steem = Steem('蒸汽',123) print(water.turn_ice()) print(ice.turn_ice()) print(steem.turn_ice())
#面向物件之封裝:
腦子不好使的先別封,沒想全面的別封,不然最後你會瘋
1 改變 2 擴充套件
明確內外可否呼叫,內部能用外部不能用
多型就是類的這兩層意義的一個具體的實現機制,即呼叫不同的類例項化的物件下的相同方法,實現的過程不一樣,python中的標準型別就是多型概念的一個很好的示範
真正意義的封裝不是停留在封裝的層面上
class People: stars = 'earth' _star = 'earth' #被隱藏的屬性 類之外不應該被呼叫,能呼叫 __star = 'earth' #被隱藏的屬性(類似私有的) 類之外不能被呼叫 如非要呼叫可如: peoplo._People__star 原因是pythonn會重新命名 __width = 23 __lenfth = 24 def __init__(self,id,name,age,salary): self.id = id self.name = name self.age = age self.salary = salary def _get_id(self): print('這是我的私有方法,我找到的id是[%s]' %self.id) def teststar(): print(self.__star) #外部人可呼叫該函式求面積 def tell_area(): return self.__width * self.__lenfth peoplo = People('232333233','linm','13',1000000) peoplo._get_id() print(peoplo.__star) peoplo.teststar()