面向物件--第一部分
阿新 • • 發佈:2018-11-11
-
與面向過程對比
-
面向過程:數學邏輯的對映,學會做個好員工。
-
面向物件:生活邏輯的對映,學會做個好領導。
-
-
生活例項
-
類: 人 手機 電腦
-
物件: 習大大、普京 二狗的iphoneX 生輝桌上的電腦
-
-
官方定義
-
類:具有相同特徵(屬性和行為)事物的抽象
-
物件:某個類的具象
-
-
程式語言
-
類:是一種自定義的資料型別
-
物件:某個類型別的變數
-
面向物件語法
-
類的定義
class 類名:
pass -
語法說明
-
定義類需要使用關鍵字
class
-
類名:原則上符合識別符號命名規範即可,但是通常我們都採用大駝峰風格命名,如:UserName
-
類名後面的':'不要忘記
-
類的內容要進行整體縮排
-
行為通過方法體現
-
屬性通過變數體現,需要動態新增
-
成員訪問:
-
屬性:物件.屬性名
-
方法:物件.方法名()
-
-
示例:
# 定義類 class Person: # 行為時通過方法體現的 # 吃飯 def
-
-
self使用
class Person: def run(self): # self表示當前物件,就是呼叫該方法的物件 print
-
__str__方法
class Person: # 預設列印物件,顯示類名+地址 # 重寫該方法,列印該方法的返回值 def __str__(self): return '我叫{},今年{}歲'.format(self.name, self.age) james = Person() james.name = '勒布朗.詹姆斯' james.age = 33 print(james)
-
__init__方法
class Cat: def __str__(self): return 'name:{},age:{},color:{}'.format(self.name, self.age, self.color) # 構造方法:建立物件後,會自動呼叫該方法完成初始化設定 def __init__(self, name, age, color): # print('__init__', name, age, color) self.name = name self.age = age self.color = color # 這種方案比較繁瑣 # jiafei = Cat() # jiafei.name = '加菲' # jiafei.age = 2 # jiafei.color = '橘黃色' # print(jiafei) jiafei = Cat('加菲', 2, '橘黃色') print(jiafei)
-
__del__方法
class Pig: # 析構方法:當物件釋放時,系統會自動呼叫 # 若手動使用del刪除:則會立即呼叫該方法 # 該方法一般做資源釋放操作,如:資料庫斷開連線,檔案關閉 def __del__(self): print('大師兄,我不行了') bajie = Pig() del bajie print('八戒,一路走好')
-
思考:小明手裡有2張牌,左手♥K,右手♠A,小明交換兩手的牌後,手裡分別有什麼?
-
先找到物件:小明、左手、右手、♥K、♠A
-
根據物件抽象類:人、手、牌
-
根據需求完善設計對應的類
-
示例
# 撲克牌 class Poker: def __init__(self, color, number): self.color = color self.number = number def __str__(self): return '{}{}'.format(self.color, self.number) # 建立兩張牌 p1 = Poker('♥', 'K') p2 = Poker('♠', 'A') # 手的類 class Hand: def __init__(self, poker=None): self.poker = poker def hold_poker(self, poker): self.poker = poker # 建立兩隻手 left_hand = Hand(p1) right_hand = Hand(p2) # 人的類 class Person: def __init__(self, name, left_hand, right_hand): self.name = name self.left_hand = left_hand self.right_hand = right_hand # 展示手中的牌 def show(self): print('{}張開手'.format(self.name), end=' ') print('左手:{}'.format(self.left_hand.poker), end=',') print('右手:{}'.format(self.right_hand.poker)) # 交換兩手的牌 def swap(self): self.left_hand.poker, self.right_hand.poker = self.right_hand.poker, self.left_hand.poker print('{}交換兩手的牌'.format(self.name)) # 建立小明物件 xiaoming = Person('小明', left_hand, right_hand) # 展示手中的牌 xiaoming.show() # 交換兩手的牌 xiaoming.swap() # 再次展示牌 xiaoming.show()
-
-
練習:設計一個數學類,屬性有兩個數,方法:加、減、乘、除,展示成員
第一種: class Math: def __init__(self,one,two): self.one = one self.two = two def add(self): print('{}+{}'.format(self.one,self.two)) def sub(self): print('{}-{}'.format(self.one, self.two)) def mul(self): print('{}*{}'.format(self.one, self.two)) def div(self): print('{}/{}'.format(self.one, self.two)) show = Math(10,5) show.add() show.mul() show.div() show.sub() 第二種: class Number: def __init__(self,num1,num2): self.num1 = num1 self.num2 =num2【 def add(self): return self.num1 + self.num2 def sub(self): return self.num1 - self.num2 def mul(self): return self.num1 * self.num2 def div(self): if self.num2 == 0: return None return self.num1 / self.num2 a = Number(3,3) print(a.add()) print(a.sub()) print(a.mul()) print(a.div())
-
實現平方和
#對外提供簡單易用的介面 class Number: def __init__(self,num1,num2): self.num1 = num1 self.num2 =num2 def add(self): return self.num1 + self.num2 def sub(self): return self.num1 - self.num2 def mul(self): return self.num1 * self.num2 def div(self): if self.num2 == 0: return None return self.num1 / self.num2 @classmethod def pingfanghe(cls,num1,num2): a = cls(num1,num1) m = a.mul() b = cls(num2,num2) n = b.mul() c = cls(m,n) ret = c.add() return ret ret = Number.pingfanghe(2,3) print(ret)
常用內建函式
-
內建函式:在類中,特定時機自動回觸發的函式。
-
設定、獲取、銷燬屬性時自動觸發的方法:
class Person: def __str__(self): return '姓名:{}'.format(self.name) def __init__(self, name): self.name = name def __del__(self): print('物件即將銷燬') # 當訪問不存在的屬性時會自動觸發該方法 def __getattr__(self, item): if item == 'age': return 18 else: return '你猜' # 設定屬性時會自動觸發該方法 def __setattr__(self, key, value): # print(key, value) self.__dict__[key] = value # 銷燬物件的指定屬性時會自動觸發 def __delattr__(self, item): print(item, '屬性即將銷燬') xiaoming = Person('小明') # print(xiaoming.age) # print(xiaoming.weight) xiaoming.age = 20 # 存放了所有的物件屬性 # print(xiaoming.__dict__) # print(xiaoming.age) del xiaoming.age
-
-
將物件當做字典操作,特定時機自動觸發的函式
class Person: # 將物件當做字典操作,新增或設定屬性時自動觸發 def __setitem__(self, key, value): print(key, value) self.__dict__[key] = value # 將物件當做字典操作,獲取屬性時自動觸發 def __getitem__(self, item): # print(item) return self.__dict__.get(item) # 將物件當作字典操作,銷燬屬性時自動觸發 def __delitem__(self, key): print(key, '即將銷燬') del self.__dict__[key] xiaoming = Person() xiaoming['name'] = '小明' # print(xiaoming.name) print(xiaoming['name']) del xiaoming['name']
-
將物件當做函式呼叫
class Person: # 將物件當做函式呼叫時,會自動觸發該方法 def __call__(self, *args, **kwargs): # print('__call__', args) return sum(args) xiaoming = Person() # 如果想這樣呼叫,必須重寫__call__方法 ret = xiaoming(1, 2, 3) print(ret)
-
判斷一個物件是否可以呼叫,是否擁有某屬性,是否是函式
def test(): pass # 判斷一個物件能否被呼叫 print(callable(xiaoming)) print(callable(test)) # 判斷一個物件是否擁有__call__屬性 print(hasattr(test, '__call__')) print(hasattr(xiaoming, '__call__')) # 判斷一個物件是否是函式 from inspect import isfunction print(isfunction(test)) print(isfunction(xiaoming))
練習
-
第一題
-
設計一個學生類
-
屬性:姓名、學號、年齡、成績
-
-
設計一個班級類
-
屬性:班級代號,所有學生
-
-
要求:實現向班級中新增學生、刪除學生、檢視學生、按照指定條件排序
#學生類 class Student : def __init__(self,name,number,age,grade): self.name = name self.number = number self.age =age self.grade = grade def __str__(self): return 'name:{},number:{},age:{},grade:{}'.format(self.name,self.number,self.age,self.grade) #班級類 class Class : def __init__(self,title): self.title =title self.student_list = [] self.student_dict = {} def add_stu(self,stu): self.student_list.append(stu) self.student_dict[stu.number] = stu #學生排序 def sort_stu(self,key=None,reverse =False ): self.student_list.sort(key=key , reverse=reverse) #查詢學生 def get_stu(self,number): return self.student_dict.get(number) #刪除學生 def del_stu(self,number): #從字典中彈出並刪除 s = self.student_dict.pop(number) #從列表刪除 self.student_list.remove(s) def show_stu(self): for stu in self.student_list: print(stu) from random import randint #建立一個班級 banji = Class('python-1805') #按照成績 banji.sort_stu(key=lambda banji: banji.grade,reverse=True) for i in range(10): name = 'stu' + str(i+1) number = 100 + i age = randint(20,30) grade = randint(0,100) #建立學生物件 stu = Student(name,number,age,grade) #將學生新增到班級的列表中 banji.add_stu(stu) banji.show_stu()
-
-
第二題
-
將歌詞解析封裝成類,要求:提供一個方法(根據時間返回歌詞)
-
提示:封裝兩個類:歌詞類、歌詞管理類
#歌詞類 class Lrc: def __init__(self,sec,lrc): self.sec = sec self.lrc = lrc def __str__(self): return "{}:{}".format(self.sec,self.lrc) #歌詞管理類 class LrcManager: def __init__(self,lrc_file): self.lrc_dict = {} self.time_list = [] self.song_dict = {} self.lrc_file =lrc_file self.jiexi = () def jiexi(self): fp = open(self.lrc_file) lrc_list = fp.readlines() #根據時間返回歌詞物件 def get_lrc(self,sec): for t in self.time_list: if t <sec: return self.lrc_dict[t]
-
-