學習python第十六天, 一周總結
這一周主要學習內容如下
- 函式
- 函式的呼叫
- 函式的引數問題
- 使用模塊
- 遞回函式
- 面對物件編程
- 繼承問題,父類、子類
- 關聯問題,普通關聯、強關聯
- 依賴關系
- 多型
復習的目的只是整合一周學習的只是具體還是要參照每一天所寫的筆記和代碼
函式
簡單來說函式就是將各種作用的代碼打包起來,然后形成函式,之后在需要使用時就可以直接調過來使用,就不需要重新再寫一遍直接用即可
函式都意義大概就是避免代碼的冗雜,減少代碼的重復性,還有就是如果需要對代碼進行更改時就要一個一個更改,而有了函式直接更改函式即可
格式為:
def 函式名(引數):
? return 回傳值
這里的引數可以理解為數學里函式的自變數,也可以沒有引數,而回傳值可以理解為數學函式里的因變數
,回傳值的種類很多,字串,數字,布林值,等等等等,
函式是一個很重要,很常用的知識點,以后也會經常使用到,所以多多的練習必不可少
引數
對于不同的函式我們需要匯入不同的引數,引數各種各樣,還有一些引數不確定引數的個數,最簡單的例子就是求不確定個數的數字和,或乘積,還有不同引數的型別
于是就有了以下方法
# 當不確定引數個數時
def __init__(self, *args):
# 當引數為字典且不確定字典個數時
def __init__(self, **kwargs):
# 當需要確定引數型別時,在引數后面加上冒號加上引數型別
def __init__(self, name: str, age: int, score: dict, parent: list):
模塊的使用
模塊的使用 其實與使用python的第三方庫差不多,都是先匯入再使用,不同的地方就是現在我們只學到了在同一個環境下的模塊使用,
遞回函式
遞回函式其實就是在一個函式中自己呼叫自己,有點類似于while回圈,需要找到一個停止呼叫的鑰匙
def fac(num):
if num == 0:
return 1
return num * fac(num - 1)
在回傳值那里繼續呼叫自己,造成一個回圈,在回圈的程序中引數變小
當引數變為1時我們就停止遞回if num == 0:
return 1
面對物件
面向物件編程
指令式編程---->面向程序(函式)編程----->程式比較簡單的時候沒有任何毛病
編程范式(程式設計的方法論):面向物件編程/函式式編程
物件: 物件是可以接收訊息的物體,面向物件編程就是通過給物件發訊息達到解決問題的目標
物件 = 資料 + 函式(方法)----->物件將資料和操作資料的函式從邏輯上變成一個整體,
類(型別): 將一大類物件共同的特正抽取出來之后得到的一個抽象概念
簡單地說,類是物件的藍圖(模板),有了類才能創建出這種類的物件
面向物件編程:
- 定義類---->使用駝峰命名法,每個單詞首字母大寫
~資料抽象: 找到物件相關的靜態特征(屬性)---->找名詞
~行為抽象: 找到和物件相關的動態特征(方法)----->找動詞 - 造物件
- 發訊息
- 口訣
一切皆為物件
物件都有屬性和行為
每個物件都是獨一無二的
物件一定屬于某個類
簡化面對物件編程的基本步驟如下:
- 定義類(資料抽象,行為抽象)
- 創建物件(創建物件----->構造器語法----->類名)
- 給物件發訊息(呼叫物件的方法)
我自己總結下來就是,找到一種種類,從這種類里邊抽象出一個物件,當然也可以先抽象出一個物件再將其歸到一個類里,
抽象出這個類的屬性,有什么特殊的地方,比如什么顏色,頭上有犄角還是身后有尾巴,或者是其他的特點,這些是屬性
抽象出這個類的行為,這個種類的物種能夠做什么事情,有什么用,就是它的行為,
將這個類抽象出來之后,創建一個這個種類里面的一個個體,比如學生類,創建出小明這個學生,牛類,你家門口的那頭奶牛大花,物件需要是一個具體的東西,可以不存在,但是要具體,讓人一下子就能想象出它的樣子,創建出物件,根據類的要求傳入引數,也就是屬性,屬于這個類且這個物件也有的屬性
最后給物件發訊息,讓它執行它的行為
這就是一個面對物件編程的程序,值得注意的是這里的物件可不是你的男朋友或者女朋友,如果單身狗就當我沒說
靜態方法,動態方法
我們在類里面寫的函式,通常稱之為方法,它們基本上都是發給物件的訊息,
但是有的時候,我們的訊息并不想發給物件,而是希望發給這個類(類本身也是一個物件),
這個時候,我們可以使用靜態方法或類方法,將我們要發的訊息傳給類
繼承
對已有的類進行擴展開展創建出新的類,這個程序叫做繼承
提供繼承學習的類叫做父類,得到繼承資訊的類叫做子類
子類直接從父類繼承公共的屬性和行為,再添加自己特有的屬性和行為
子類一般強于父類,父類有的子類可直接拿來用,而父類卻不能使用子類的行為
- 兩個類之間有哪些可能的關系???
~ is-a關系:繼承 —> 從一個類派生出另一個類
a student is a person.
a teacher is a person.
~ has-a關系:關聯 —> 把一個類的物件作為另外一個類的物件的屬性
a person has an identity card.
a car has an engine.
- (普通)關聯
- 強關聯:整體和部分的關聯,聚合和合成
~ use-a關系:依賴 —> 一個類的物件作為另外一個類的方法的引數或回傳值
a person use a vehicle.
簡單的關系如下:
class Vehicle:
"""交通工具"""
pass
class Horse(Vehicle):
"""馬"""
pass
class Motobike(Vehicle):
"""摩托車"""
def __init__(self):
self.engine = Engine()
class Engine:
"""引擎"""
pass
class Follower:
"""徒弟"""
def __init__(self, name):
self.name = name
def do_work(self):
pass
class MrTang:
"""唐僧"""
def __init__(self):
self.followers = [Follower('孫悟空'), Follower('豬悟能'), Follower('沙悟凈')]
def drive(self, vehicle):
"""駕駛"""
pass
馬和摩托車都是交通工具,所以他們可以使用交通工具的屬性
引擎是摩托車的一部分所以他們屬于關聯關系
唐僧可以騎馬,使用與被使用關系屬于依賴
面向物件編程的四大支柱:
-
~ 抽象(abstraction):提取共性(定義類就是一個抽象程序,需要做資料抽象和行為抽象),
-
封裝(encapsulation):把資料和操作資料的函式從邏輯上組裝成一個整體(物件),
—> 隱藏實作細節,暴露簡單的呼叫介面, - 繼承(inheritance):擴展已有的類創建新類,實作對已有類的代碼復用,
-
多型(polymorphism):給不同的物件發出同樣的訊息,不同的物件執行了不同的行為,
—> 方法重寫:子類對父類已有的方法,重新給出自己的實作版本
重寫
子類對父類已有的方法,重新給出自己的實作版本,這個程序叫做方法重寫(override),
在重寫方法的程序中,不同的子類可以對父類的同一個方法給出不同的實作版本,那么該方法在運行時就會表現出多型行為,
面對物件編程練習
-
寫一個撲克游戲,洗牌,把牌發到四個玩家手上
-
-
牌
- 屬性: 花色、點數
- 行為: 顯示
-
-
撲克
- 屬性: 保存牌的串列
- 行為: 發牌、 洗牌
-
-
玩家
- 屬性: 名字,保存玩家手牌的串列
- 行為: 摸牌、整理、出牌
整理需要用到一種特殊的方法------魔術方法
魔術方法
魔術(魔法)方法 —> 以雙下劃線開頭和結尾的方法 —> 有特殊用途和意義的方法
- init —> 初始化方法,在呼叫構造器語法創建物件的時候會被自動呼叫
~ (initialize -> 初始化)
- str —> 獲得物件的字串表示,在呼叫 print函式直接輸出物件時會被自動呼叫
- repr —> 獲得物件的字串表示,把物件放到容器中,用 print直接輸出容器時會自動呼叫
~ (representation -> 表述)
- lt —> 對應小于號運算子,自動比大小
~ (less than -> '<'運算子)
class Card:
def __init__(self, suite, face):
"""
牌的屬性,花色和點數
"""
self.suite = suite
self.face = face
def __str__(self):
"""展示字符"""
return self.show()
def __repr__(self):
"""展示字符"""
return self.show()
def __lt__(self, other):
"""自動比較大小的方法"""
face1, face2 = self.face, other.face
return face1 < face2
def show(self):
"""將花色和點數合稱牌"""
suites = {'S': '?', 'H': '?', 'C': '?', 'D': '?'}
faces = ['', 'A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'k']
return f'{suites[self.suite]}{faces[self.face]}'
def main():
"""程式入口"""
card1 = Card('H', 1)
card2 = Card('S', 13)
card3 = Card('D', 12)
card4 = Card('C', 9)
print(card1, card2, card3, card4)
cardA = [card1, card2, card3, card4]
print(cardA)
if __name__ == '__main__':
main()
class Poker:
"""
撲克
"""
def __init__(self):
self.cards = [Card(suite, face)
for suite in 'SHCD'
for face in range(1, 14)]
# 生成式語法生成一副撲克
# for suite in 'SHCD':
# for face in range(1, 14):
# card = Card(suite, face)
# self.cards.append(card)
self.counter = 0
def shuffle(self):
# 將撲克順序打亂
self.counter = 0
random.shuffle(self.cards)
def deal(self) -> Card:
"""發牌, 將撲克牌一張一張發"""
card = self.cards[self.counter]
self.counter += 1
return card
def has_more(self) -> bool:
# 牌發完了
return self.counter < len(self.cards)
def main():
poker = Poker()
poker.shuffle()
while poker.has_more():
# 使用回圈發牌,當牌發完了,has_more(self) -> bool就會回傳False,終止回圈
print(poker.deal(), end='')
if __name__ == '__main__':
main()
class Player:
def __init__(self, nickname):
# 玩家昵稱
self.nickname = nickname
self.cards = []
def get_one_card(self, card):
"""摸一張牌"""
self.cards.append(card)
def arrange(self):
"""整理手上的牌"""
self.cards.sort()
def show(self):
"""顯示玩家手上的牌"""
print(self.nickname, end=':')
# 輸出玩家昵稱,再將玩家手上的牌一張張輸出
for card in self.cards:
print(card, end='')
print()
def main():
nicknames = ['呂布', '猴子', '鎧', '程咬金']
players = [Player(nickname) for nickname in nicknames]
poker = Poker()
poker.shuffle()
for _ in range(13):
for player in players:
card = poker.deal()
player.get_one_card(card)
for player in players:
player.show()
if __name__ == '__main__':
main()
練習,使用繼承
給我的感覺使用繼承就好比使用函式一樣
就是為了減少代碼的重復
將多個子類所擁有的屬性寫在父類里(當然前提是父類也同時有這屬性才行)
然后直接從父類里面拿來用就行了
就好比,學生、老師都屬于人這個類,那么學生類和老師類就是人類的子類,他們共有的屬性就寫在父類里,比如吃、玩
class Person:
def __init__(self, name, gander):
self.name = name
self.gander = gander
pass
def eat(self):
"""
吃飯
:return:
"""
print(f'{self.name}正在吃飯')
pass
def play(self, game_name):
"""
玩耍
:param game_name:
:return:
"""
print(f'{self.name}正在玩{game_name}')
pass
class Student(Person):
def __init__(self, name, gender, grade):
self.name = name
self.gender = gender
self.grade = grade
def study(self, course_name):
"""
學習
:param course_name:
:return:
"""
print(f'{self.name}正在學習{course_name}')
class Teacher(Person):
def __init__(self, name, gender, title):
super().__init__(name, gender)
self.title = title
def teach(self, object_name):
return f'{self.name}教的是{object_name}'
if __name__ == '__main__':
stu = Student('王大錘', '男', '五年級')
stu.study('語文')
stu.eat()
stu.play('王者榮耀')
多型
多型也屬于面對物件編程的范疇,當父類所擁有的行為,子類也擁有但是由于子類的不同所執行的方法也不同,再繼承呼叫這種方法的程序就叫做多型,而這種方法我們在父類里抽象的時候不能將特點具體執行寫出來,只能在子類呼叫時才能具體體現,
示例代碼如下:
我們現在要寫一個發工資的情形,不同的職位,職員發不同的工資
薪資(月薪)結算系統
-
三類員工:
- 部門經理:固定月薪,15000元
- 程式員:計時結算月薪,每小時200元
- 銷售員:底薪+提成,底薪1800元,銷售額5%提成
from abc import abstractmethod
# 匯入這個模塊,使用這個模塊里的方法標記多型型別
class Employee:
def __init__(self, name, post):
self.name = name
self.post = post
@abstractmethod
# 標記多型
def get_salary(self):
pass
class Manager(Employee):
def get_salary(self):
""" 經理的工資發放標準"""
return 15000
class Programmer(Employee):
def __init__(self, name, post):
super().__init__(name, post)
self.work_time = 0
pass
def get_salary(self):
"""程式員的工資發放標準"""
return self.work_time * 200
class Salesman(Employee):
def __init__(self, name, post):
super().__init__(name, post)
self.sale = 0
def get_salary(self):
""" 銷售員的工資發放標準"""
return 1800 + self.sale * 0.05
def main():
temps = [Manager('王大錘', '經理'), Programmer('馬克', '程式員'),
Programmer('喬布斯', '程式員'), Salesman('龔凡', '銷售員'),
Salesman('科科特', '銷售員'), Salesman('巴菲特', '銷售員')]
for temp in temps:
# 遍歷每一個員工
if type(temp) == Programmer:
working_time = float(input(f'請輸入{temp.name}的作業時間'))
temp.work_time = working_time
elif type(temp) == Salesman:
post_money = float(input(f'請輸入{temp.name}的銷售額'))
temp.sale = post_money
print(f'{temp.name}的工資是{temp.get_salary()}')
if __name__ == '__main__':
main()
在使用多型的時候要注意,子類的方法名要和父類的一樣才能使用
無論是函式還是面對物件編程都是比較重要的知識點,需要多多學、看、寫代碼
簡易版 21點游戲
class Card:
def __init__(self, suite, face):
self.suite = suite
self.face = face
def __str__(self):
return self.show()
def __repr__(self):
return self.show()
def __lt__(self, other):
face1, face2 = self.face, other.face
return face1 < face2
def show(self):
suites = {'S': '?', 'H': '?', 'C': '?', 'D': '?'}
faces = ['', 'A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
return f'{suites[self.suite]}{faces[self.face]}'
import random
class Poker:
"""
撲克
"""
def __init__(self):
self.cards = [Card(suite, face)
for suite in 'SHCD'
for face in range(1, 14)]
# for suite in 'SHCD':
# for face in range(1, 14):
# card = Card(suite, face)
# self.cards.append(card)
self.counter = 0
def shuffle(self):
self.counter = 0
random.shuffle(self.cards)
def deal(self) -> Card:
"""發牌"""
card = self.cards[self.counter]
self.counter += 1
return card
def has_more(self) -> bool:
return self.counter < len(self.cards)
class Player:
def __init__(self, nickname):
self.nickname = nickname
self.cards = []
def get_one_card(self, card):
"""摸一張牌"""
self.cards.append(card)
def arrange(self):
self.cards.sort()
def show(self):
"""顯示玩家手上的牌"""
print(self.nickname, end=':')
for card in self.cards:
print(card, end='')
print()
def compare(self):
"""
轉換非數字牌的點數
:return: 點數
"""
X = []
for get_number in self.cards:
m = str(get_number)
x = m[1:]
if x == 'J' or x == 'K' or x == 'Q':
x = 10
elif x == 'A' and sum(X) + 11 <= 21:
x = 11
elif x == 'A' and sum(X) + 11 > 21:
x = 1
else:
x = int(x)
X.append(x)
return X
def BlackJack(self):
"""
形成Black Jack的特殊情況
:return:
"""
if sum(self.compare()) == 21 and len(self.cards) == 2:
print('Black Jack')
def main():
total_money = 1000
while total_money > 0:
bet_money = int(input('清下注:'))
if bet_money > total_money:
print('錢不夠')
continue
player1 = Player('閑家')
player2 = Player('莊家')
poker = Poker()
poker.shuffle()
for _ in range(2):
card1 = poker.deal()
player1.get_one_card(card1)
card2 = poker.deal()
player2.get_one_card(card2)
player1.show()
player2.show()
while True:
h1 = 1
while True:
if sum(player1.compare()) > 21:
h1 = 0
break
h1 = int(input('閑家是否繼續要牌如果要請輸入1,否則輸入0:'))
if h1 == 1:
card = poker.deal()
player1.get_one_card(card)
player1.show()
elif h1 == 0:
break
h2 = 1
while True:
if sum(player2.compare()) > 21:
h2 = 0
break
h2 = int(input('莊家是否繼續要牌如果要請輸入1,否則輸入0:'))
if h2 == 1:
card = poker.deal()
player2.get_one_card(card)
player2.show()
elif h2 == 0:
break
if h1 == 0 and h2 == 0:
break
print(f'閑家{sum(player1.compare())}點, 莊家{sum(player2.compare())}點')
if player1.BlackJack() and player2.BlackJack():
print('平局')
elif player1.BlackJack():
print('Black Jack,閑家勝')
total_money += bet_money * 2
if player2.BlackJack():
print('莊家勝')
total_money -= bet_money
elif sum(player1.compare()) > 21:
print('莊家勝')
total_money -= bet_money
elif sum(player2.compare()) > 21:
print('閑家勝')
total_money += bet_money * 2
elif sum(player2.compare()) > 21:
print('閑家勝')
total_money += bet_money * 2
elif sum(player1.compare()) > sum(player2.compare()):
print('閑家勝')
total_money += bet_money * 2
elif sum(player1.compare()) == sum(player2.compare()):
print('平局')
else:
print('莊家勝')
total_money -= bet_money
print(f'您還有{total_money}元')
if __name__ == '__main__':
main()
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/292501.html
標籤:python
