一娱仔、review
1.寫一個(gè)撲克類鱼鸠, 要求擁有發(fā)牌和洗牌的功能(具體的屬性和其他功能自己根據(jù)實(shí)際情況發(fā)揮)
from enum import Enum, unique
from random import shuffle
@unique
class PokerNum(Enum):
J = 11, 'J', 11
Q = 12, 'Q', 12
K = 13, 'K', 13
A = 1, 'A', 14
TWO = 2, '2', 15
BigJoker = 15, '大王', 17
SmallJoker = 14, '小王', 16
@unique
class PokerColor(Enum):
Club = '?'
Diamond = '?'
Heart = '?'
Spade = '?'
Space = ''
class Poker:
def __init__(self, num: PokerNum, color: PokerColor):
self.num = num
self.color = color
def __repr__(self):
if isinstance(self.num, PokerNum):
return str(self.color.value) + str(self.num.value[1])
return str(self.color.value)+str(self.num)
def __gt__(self, other):
if isinstance(self.num, PokerNum):
a = self.num.value[2]
else:
a = self.num
if isinstance(other.num, PokerNum):
b = other.num.value[2]
else:
b = other.num
return a > b
class Game:
# 斗地主
def __init__(self):
pokers = []
colors = [PokerColor.Club, PokerColor.Diamond, PokerColor.Heart, PokerColor.Spade]
nums = [PokerNum.A, PokerNum.TWO, 3, 4, 5, 6, 7, 8, 9, 10, PokerNum.J, PokerNum.Q, PokerNum.K]
for num in nums:
for color in colors:
p = Poker(num, color)
pokers.append(p)
pokers.extend([Poker(PokerNum.SmallJoker, PokerColor.Space), Poker(PokerNum.BigJoker, PokerColor.Space)])
self.pokers = pokers
self.pokers_iter = iter(self.pokers)
# 洗牌
def shuffling(self):
shuffle(self.pokers)
self.pokers_iter = iter(self.pokers)
# 斗地主發(fā)牌方式
def deal1(self):
ps1 = []
ps2 = []
ps3 = []
for _ in range(17):
ps1.append(next(self.pokers_iter))
ps2.append(next(self.pokers_iter))
ps3.append(next(self.pokers_iter))
ps1.sort(reverse=True)
ps2.sort(reverse=True)
ps3.sort(reverse=True)
return ps1, ps2, ps3, list(self.pokers_iter)
game1 = Game()
game1.shuffling()
p1, p2, p3, di = game1.deal1()
print(p1)
print(p2)
print(p3)
print('底牌:', di)
2悲立、(嘗試)寫一個(gè)類,其功能是:1.解析指定的歌詞文件的內(nèi)容 2.按時(shí)間顯示歌詞
提示:歌詞文件的內(nèi)容一般是按下面的格式進(jìn)行存儲的档冬。
歌詞前面對應(yīng)的是時(shí)間膘茎,在對應(yīng)的時(shí)間點(diǎn)可以顯示對應(yīng)的歌詞
class Lyric:
def __init__(self, time, word):
value = float(time[1:3])*60 + float(time[4:])
self.time = value
self.word = word
def __repr__(self):
return '<'+str(self.time) + ':' + self.word+'>'
def __gt__(self, other):
return self.time > other.time
class LyricAnalysis:
def __init__(self, name):
# 歌名
self.name = name
self.__all_lyrics = []
def get_word(self, time):
# =======解析歌詞文件======
if not self.__all_lyrics:
print('解析歌詞')
with open('files/'+self.name) as f:
while True:
line = f.readline()
if not line:
break
lines = line.split(']')
word = lines[-1]
for t in lines[:-1]:
lyric = Lyric(t, word)
self.__all_lyrics.append(lyric)
# 排序
self.__all_lyrics.sort(reverse=True)
# ==========獲取歌詞==========
for lyric in self.__all_lyrics:
if lyric.time <= time:
return lyric.word
ly = LyricAnalysis('藍(lán)蓮花')
print('===:',ly.get_word(123))
print('===:',ly.get_word(10))
print('===:',ly.get_word(89))
ly2 = LyricAnalysis('一首簡單的歌')
print('!!!:', ly2.get_word(30))
print('!!!:', ly2.get_word(90))
二、多繼承
Python中的類支持多繼承
多繼承的時(shí)候酷誓,子類只能繼承第一個(gè)父類所有的屬性和方法披坏,
后面的父類只能繼承字段和方法,方法名一樣時(shí)盐数,只繼承第一個(gè)父類
class Animal(object):
num = 100
def __init__(self):
self.age = 0
self.gender = '雌'
@classmethod
def func1(cls):
print('動物類的類方法')
def func2(self):
print('動物類中的對象方法')
class Fly(object):
name = '飛行器'
def __init__(self):
self.height = 100
self.time = 5
self.speed = 100
def func2(self):
print('飛行的對象方法')
class Bird(Animal, Fly):
pass
bird1 = Bird()
# 字段都能繼承
print(Bird.num, Bird.name)
Bird.func1()
bird1.func2()
# print(bird1.age, bird1.gender)
# print(bird1.speed, bird1.height, bird1.time)
三棒拂、運(yùn)算符重載
1.運(yùn)算符
Python中所有的類型都是類,所有的數(shù)據(jù)都是對象,
Python中使用任意的運(yùn)算符都是在調(diào)用類中的相應(yīng)方法帚屉,每一個(gè)運(yùn)算符對應(yīng)什么方法是固定的谜诫,
某種數(shù)據(jù)是否支持某個(gè)運(yùn)算符操作就看這個(gè)數(shù)據(jù)類型中是否實(shí)現(xiàn)了對應(yīng)的方法
2、運(yùn)算符重載
——指的是在不同的類中實(shí)現(xiàn)同樣的運(yùn)算符對應(yīng)的函數(shù)
類的對象默認(rèn)情況下只支持:==攻旦、喻旷!=
import copy
class Student:
def __init__(self, name, age, score=0):
self.name = name
self.age = age
self.score = score
def __repr__(self):
return '<%s, id:%s>' % (str(self.__dict__)[1:-1], hex(id(self)))
# a+b -> a.__add__(b)
# self -> 當(dāng)前類的對象,也是+前面的那個(gè)數(shù)據(jù)
# other -> +后面的那個(gè)數(shù)據(jù), 類型根據(jù)運(yùn)算規(guī)則的設(shè)計(jì)可以是任何類型的數(shù)據(jù)
def __add__(self, other):
# return self.age + other.age
return self.score + other.score
# return Student(self.name+other.name, self.age+other.age, self.score + other.score)
# return self.score + other
# a*b -> a.__mul__(b)
def __mul__(self, other):
list = []
for _ in range(other):
list.append(copy.copy(self))
return list
# a<b -> a.__lt__(b)
# 注意: <和>符號只需要重載其中一個(gè)就可以
def __lt__(self, other):
return self.score < other.score
stu1 = Student('小明', 19, 90)
stu2 = Student('小花', 20, 78)
# stu1.__add__(stu2)
print(stu1 + stu2)
# stu1.__add__(100)
# print(stu1 + 100)
print(stu1 * 3)
students = [stu1, stu2, Student('小紅', 12, 100)]
students.sort()
print(students)
print(stu1 < stu2)
print(stu1 > stu2)
四牢屋、拷貝
1且预、直接賦值
將變量中的地址直接賦值給新的變量,賦值后兩個(gè)變量的地址相同
2烙无、淺拷貝
拷貝(不管是淺拷貝還是深拷貝)不同于直接賦值锋谐,會產(chǎn)生新的地址,
字符串截酷、列表涮拗、元祖的切片,對象.copy()迂苛,copy模塊中的copy方法都是淺拷貝
淺拷貝只會拷貝當(dāng)前對象三热,不會對子對象進(jìn)行拷貝
3、深拷貝
copy模塊中的deepcopy方法是深拷貝灾部,不僅會拷貝當(dāng)前對象康铭,還會拷貝子對象惯退,產(chǎn)生新的地址
# 練習(xí):
import copy
a = ['color', 'height', 'background']
b = [a, 'aaa', 'bbb']
c1 = b
c2 = copy.copy(b)
c3 = copy.deepcopy(b)
a[-1] = ['BG']
b.append('ccc')
五赌髓、枚舉值的特點(diǎn):
1)可以通過有意義的屬性名直接顯示數(shù)據(jù)
2)每個(gè)數(shù)據(jù)的值不能修改
3)可以做到不同的數(shù)據(jù)的值唯一
from enum import Enum, unique
@unique
class PokerNum(Enum):
J = 11
Q = 12
K = 13
A = 1
class Color:
RED = (255, 0, 0)
print(PokerNum.J)
print(PokerNum.K.value, PokerNum.J.value > PokerNum.Q.value)
六、內(nèi)存的開辟
內(nèi)存區(qū)間分為棧區(qū)間和堆區(qū)間催跪,棧區(qū)間的內(nèi)存自動開辟和釋放锁蠕,堆區(qū)間的內(nèi)存需要手動開辟和釋放,
但是Python中已經(jīng)將堆區(qū)間的內(nèi)存的開辟和釋放自動化了
當(dāng)給變量賦值的時(shí)候懊蒸,系統(tǒng)會先在堆區(qū)間中自動開辟區(qū)間將數(shù)據(jù)存起來荣倾,然后再將數(shù)據(jù)在堆中的地址存存在
變量中,變量存在棧區(qū)間
注意:數(shù)字和字符串?dāng)?shù)據(jù)在開辟空間的時(shí)候骑丸,會先檢查內(nèi)存中之前是否已經(jīng)有這個(gè)數(shù)據(jù)舌仍,如果有就直接使用之前的
數(shù)據(jù),沒有才開辟新的空間保存數(shù)據(jù)
七通危、內(nèi)存的釋放
棧區(qū)間:全局棧區(qū)間在程序結(jié)束后銷毀铸豁,函數(shù)棧區(qū)間在函數(shù)調(diào)用結(jié)束后銷毀
堆區(qū)間:看一個(gè)對象是否銷毀,就看這個(gè)對象的引用計(jì)數(shù)是否為0菊碟,如果引用為0节芥,這個(gè)對象就會銷毀(垃圾回收)
注意:Python中針對對象的循環(huán)引用已經(jīng)做了處理,程序員不需要寫額外的代碼來解決循環(huán)引用問題