01.recode
1.類方法和靜態(tài)方法
對(duì)象方法:
a.直接聲明在類中
b.自帶self參數(shù)
c.使用對(duì)象調(diào)用
類方法:
a.聲明@classmethod后面
b.自帶cls參數(shù)
c.使用類調(diào)用
靜態(tài)方法:
a.聲明@staticmethod后面
b.沒有自帶的參數(shù)
c.使用類調(diào)用
2.私有化
加__
3.getter和setter
a.屬性名加_
b.@property后面聲明函數(shù),函數(shù)名屬性名,沒有其他參數(shù),需要返回值
c.對(duì)象.屬性(不帶_)
a.屬性名加_
b.@getter名.setter后面聲明函數(shù),函數(shù)名屬性名,有一個(gè)參數(shù),不需要返回值
c.對(duì)象.屬性(不帶_) = 值
4.繼承
class 子類(父類):
內(nèi)的內(nèi)容
繼承就是讓子類直接擁有父類的屬性和方法
5.添加方法和屬性
class A:
def __init__(self):
self.a = 0
self.b = ''
class B(A):
def __init__(self):
super().__init__()
self.c = 10
b = B()
02.多繼承
1.多繼承
多繼承: 讓一個(gè)類同時(shí)繼承多個(gè)類
注意:實(shí)際開發(fā)的時(shí)候,一般不使用多繼承
class Animal:
num = 61
def __init__(self, name='名字', age=0, color=''):
self.name = name
self.age = age
self.color = color
def show_info(self):
print('=====')
# print('名字:%s 年齡:%d 顏色:%s' % (self.name, self.age, self.color))
class Fly:
info = '飛'
def __init__(self, distance=0, speed=0):
self.distance = distance
self.speed = speed
@staticmethod
def show():
print('會(huì)飛!')
# 讓Birds同時(shí)繼承Animal和Fly
class Birds(Fly, Animal):
pass
bird1 = Birds()
# 對(duì)象屬性只能繼承第一個(gè)類的對(duì)象屬性
print(bird1.speed)
# 兩個(gè)類的字段都能繼承
print(Birds.num, Birds.info)
# 兩個(gè)類的方法都能繼承
Birds.show()
bird1.show_info()
0
61 飛
會(huì)飛!
=====
2.多態(tài)
類的特點(diǎn):封裝、繼承、多態(tài)
封裝:可以對(duì)多條數(shù)據(jù)(屬性)和多個(gè)功能(方法)進(jìn)行封裝
繼承:可以讓一個(gè)類擁有另外一個(gè)類的屬性和方法
多態(tài):有繼承就有多態(tài)(一個(gè)事物的多種形態(tài))
03.運(yùn)算符重載
1.別的語言的函數(shù)和函數(shù)的重載
C++/java聲明函數(shù)的語法:
返回值類型 函數(shù)名(參數(shù)類型1 參數(shù)名1, 參數(shù)類型2 參數(shù)名2){
函數(shù)體
}
int func1(){
}
void func1(int a){
}
void func1(char a){
}
int func1(int a, int b){
}
上面這4個(gè)函數(shù)是不同的函數(shù)(可以同時(shí)存在)
python中的函數(shù)不支持重載
def func1():
pass
def func1(a):
pass
def func1(a, b)
pass
最終只保留最后這一個(gè)func1,前面的會(huì)被覆蓋
2.運(yùn)算符重載
python中使用運(yùn)算的時(shí)候,實(shí)質(zhì)是在調(diào)用相應(yīng)的魔法方法。(python中每個(gè)運(yùn)算符都對(duì)應(yīng)一個(gè)魔法方法)
運(yùn)算符重載:在不同的類中實(shí)現(xiàn)同一個(gè)運(yùn)算符對(duì)應(yīng)的魔法方法,來讓類的對(duì)象支持相應(yīng)的運(yùn)算
class Student(object):
def __init__(self, name='', score=0, age=0):
self.name = name
self.score = score
self.age = age
# + 重載
"""
數(shù)據(jù)1 + 數(shù)據(jù)2 -- 數(shù)據(jù)1會(huì)傳給self, 數(shù)據(jù)2會(huì)傳給other
"""
def __add__(self, other):
# self + other
return self.score + other.score
# - 運(yùn)算
def __sub__(self, other):
# self - other
return self.age - other.age
# 注意:>和<一般情況下只需要重載一個(gè),另外一個(gè)自動(dòng)支持
# < 運(yùn)算
def __lt__(self, other):
return self.score < other.score
# > 運(yùn)算
def __gt__(self, other):
return self.age > other.age
def __repr__(self):
return '<'+(str(self.__dict__)[1:-1])+'>'
stu1 = Student('小花', 90, 16)
stu2 = Student('小明', 80, 18)
stu3 = Student('小紅', 87, 23)
stu4 = Student('小??', 30, 15)
print(stu1 + stu2)
print(stu1 - stu2)
all_students = [stu1, stu2, stu3, stu4]
all_students.sort()
print(all_students)
print(max(all_students))
170
-2
[<'name': '小??', 'score': 30, 'age': 15>, <'name': '小明', 'score': 80, 'age': 18>, <'name': '小紅', 'score': 87, 'age': 23>, <'name': '小花', 'score': 90, 'age': 16>]
<'name': '小紅', 'score': 87, 'age': 23>
04.內(nèi)存管理機(jī)制
1.堆和棧
內(nèi)存區(qū)域中分堆區(qū)間和棧區(qū)間;棧區(qū)間的內(nèi)存的開辟和釋放是自動(dòng)的,堆區(qū)間的內(nèi)存是手動(dòng)開辟手動(dòng)釋放的;
內(nèi)存管理管理的是堆區(qū)間的內(nèi)存;
2.數(shù)據(jù)的存儲(chǔ)
a.python中所有的數(shù)據(jù)都是對(duì)象,都是保存在堆中的
b.python中所有的變量存儲(chǔ)的都是存在堆中的數(shù)據(jù)的地址。存了對(duì)象的地址的變量又叫對(duì)象的引用
c.默認(rèn)情況下創(chuàng)建對(duì)象就會(huì)在堆中去開辟空間存儲(chǔ)數(shù)據(jù),并且將地址返回值;
如果對(duì)象是數(shù)字,字符串會(huì)做緩存,而且使用的是會(huì)先去緩存中看之前有沒有存過,如果有就直接返回之前的數(shù)據(jù)的地址,沒有才開辟新的空間存儲(chǔ)數(shù)據(jù)
3.數(shù)據(jù)的銷毀
python中通過'垃圾回收機(jī)制'來管理內(nèi)存的釋放
原理:看一個(gè)對(duì)象是否銷毀,就看這個(gè)的對(duì)象的引用計(jì)數(shù)是否為0。為0就銷毀,不為0就不銷毀
引用計(jì)數(shù):對(duì)象的引用個(gè)數(shù)
注意:垃圾回收其實(shí)就是回收引用計(jì)數(shù)是0的對(duì)象,但是系統(tǒng)不會(huì)時(shí)時(shí)刻刻的檢測對(duì)象的引用計(jì)數(shù)是否是0。
而是隔一段時(shí)間檢測一次,如果檢測到垃圾就回收
from sys import getrefcount
getrefcount(對(duì)象) - 獲取指定對(duì)象的引用計(jì)數(shù)
"""
1.增加引用計(jì)數(shù): 使用變量存對(duì)象的地址
"""
list1 = [1] # 對(duì)象[1]的引用計(jì)數(shù)是1
print(getrefcount(list1))
list2 = list1 # 對(duì)象[1]的引用計(jì)數(shù)是2
print(getrefcount(list1))
list3 = [list1, 100] # 對(duì)象[1]的引用計(jì)數(shù)是3
print(getrefcount(list1))
"""
2.減少引用計(jì)數(shù)
a. 刪除引用
b. 讓當(dāng)前對(duì)象的引用成為別的對(duì)象的引用
"""
print(id(list3[1]))
del list3[0]
print(getrefcount(list1))
list2 = 100
print(id(list2))
print(getrefcount(list1))
list3 = 100
print(id(list3))
print(getrefcount(100))
2
3
4
1555749472
3
1555749472
2
1555749472
9
05.游戲最小系統(tǒng)
import pygame
# 1.游戲初始化
pygame.init()
# 2.創(chuàng)建游戲窗口
"""
set_mode(窗口大小) - 窗口大小是一個(gè)元祖,有兩個(gè)元素:width, height
set_mode((寬度, 高度))
寬度和高度的單位是像素
"""
window = pygame.display.set_mode((400, 600))
# 將窗口填充成指定的顏色
"""
fill(顏色) - fill((r,g,b))
計(jì)算機(jī)顏色:計(jì)算機(jī)三原色 - 紅,綠,藍(lán)(rgb)
顏色值就是由三個(gè)數(shù)字組成,分別代表紅,綠,藍(lán),數(shù)字范圍是:0-255
python中的顏色是一個(gè)元祖,元祖中有是三個(gè)顏色,分別是r,g, b
(255, 255, 255) - 白色
(0, 0, 0) - 黑色
(255, 0, 0) - 紅色
(0, 255, 0) - 綠
"""
window.fill((255, 255, 255))
# 將窗口展示到顯示設(shè)備上
pygame.display.flip()
# 3.創(chuàng)建游戲循環(huán)
while True:
# 4.檢測事件
for event in pygame.event.get():
# ===區(qū)分不同的事件,做出不一樣的反應(yīng)===
# 判斷關(guān)閉按鈕點(diǎn)擊事件是否發(fā)生
if event.type == pygame.QUIT:
exit()
06.在窗口上顯示圖片
import pygame
pygame.init()
window = pygame.display.set_mode((400, 600))
window.fill((255, 255, 255))
=========顯示圖片===========
1.加載圖片
pygame.image.load(圖片地址) - 加載指定路徑下的圖片,返回一個(gè)圖片對(duì)象
image_obj = pygame.image.load('files/luffy.jpg')
window.blit(image_obj, (0, 0))
2.渲染圖片
blit(渲染對(duì)象, 位置)
渲染對(duì)象 - 圖片對(duì)象(顯示什么)
位置 - 元祖,(x, y)
3.獲取圖片的大小
圖片對(duì)象.get_size() - 獲取圖片大小,返回值是一個(gè)元祖:(width, height)
image_w, image_h = image_obj.get_size()
# window.blit(image_obj, ((400-image_w)/2, (600-image_h)/2))
4.圖片縮放和旋轉(zhuǎn)
a.縮放
pygame.transform.scale(圖片對(duì)象, 大小) - 將指定的圖片縮放在指定的大小, 返回新的圖片對(duì)象
new_image = pygame.transform.scale(image_obj, (50, 150))
window.blit(new_image, (0, 110))
b.旋轉(zhuǎn)縮放
pygame.transform.rotozoom(圖片對(duì)象, 旋轉(zhuǎn)角度, 縮放比例)
new_image2 = pygame.transform.rotozoom(image_obj, 0, 0.5)
window.blit(new_image2, (0, 270))
new_image3 = pygame.transform.rotozoom(image_obj, 45, 1.5)
window.blit(new_image3, (0, 330))
pygame.display.flip()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()

07.在窗口上顯示文字
import pygame
pygame.init()
window = pygame.display.set_mode((400, 600))
window.fill((255, 255, 255))
=======顯示文字=========
1.創(chuàng)建字體對(duì)象(選筆)
a.系統(tǒng)字體
pygame.font.SysFont(字體名, 字體大小, 是否加粗=False,是否傾斜=False) - 返回字體對(duì)象
b.自定義字體
pygame.font.Font(字體文件路徑, 字體大小)
# font = pygame.font.SysFont('Times', 50, italic=True)
font = pygame.font.Font('files/aa.ttf', 40)
2.根據(jù)字體創(chuàng)建文字對(duì)象
render(文字內(nèi)容, 是否平滑, 文字顏色)
text = font.render('hello pygame 你好!', True, (255, 0, 0))
3.將文字渲染到窗口上
window.blit(text, (100, 100))
pygame.display.flip()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()

08.顯示圖形
import pygame
from color import Color
import math
# 游戲最小系統(tǒng)
pygame.init()
window = pygame.display.set_mode((400, 600))
window.fill((255, 255, 255))
======顯示圖形=========
1.畫直線
line(畫在哪兒, 線的顏色, 起點(diǎn), 終點(diǎn), 線寬=1)
pygame.draw.line(window, Color.green, (0, 0), (100, 100), 10)
lines(畫在哪兒, 線的顏色, 是否閉合, 點(diǎn)列表, 線寬=1)
依次連接點(diǎn)列表中所有的點(diǎn)(是否閉合決定是否連接起點(diǎn)和終點(diǎn))
points = [(10, 10), (100, 70), (100, 170), (40, 230), (40, 320)]
pygame.draw.lines(window, Color.red, True, points, 5)
2.畫圓
circle(畫在哪兒, 顏色, 圓心坐標(biāo), 半徑, 線寬=0)
注意:線寬為0的時(shí)候畫實(shí)心圓
pygame.draw.circle(window, Color.yellow, (100, 100), 80, 3)
3.畫弧線
arc(畫在哪兒,顏色,矩形(Rect),起始弧度,終止弧度,線寬=1)
矩形 - (x, y, width, height); x,y是矩形坐上角的坐標(biāo),width,height是矩形的寬高
pygame.draw.arc(window, Color.blue, (150, 300, 50, 100), 0, math.pi, 10)
pygame.display.flip()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()

09.事件和動(dòng)畫
import pygame
from color import Color
pygame.init()
window = pygame.display.set_mode((400, 600))
window.fill((255, 255, 255))
# 在這兒寫的代碼是靜態(tài)的(界面上的內(nèi)容)
x = 100
y = 100
width = 100
height = 80
pygame.draw.rect(window, Color.green, (x, y, width, height))
pygame.display.flip()
while True:
y += 3
# width -= 2
window.fill(Color.white) # 覆蓋原來的狀態(tài)
pygame.draw.rect(window, Color.rand_color(), (x, y, width, height))
pygame.display.update() # 重新顯示
# 有事件產(chǎn)生的時(shí)候才會(huì)進(jìn)入for循環(huán)
for event in pygame.event.get():
# 1.type屬性
"""
不同的type值對(duì)應(yīng)不同類型的事件
QUIT - 關(guān)閉按鈕被點(diǎn)擊事件
a.鼠標(biāo)相關(guān)事件 - 按的位置
MOUSEMOTION - 鼠標(biāo)移動(dòng)
MOUSEBUTTONDOWN - 鼠標(biāo)按下
MOUSEBUTTOUP - 鼠標(biāo)彈起
event.pos - 獲取鼠標(biāo)事件產(chǎn)生的位置
b.鍵盤事件 - 按的是哪個(gè)鍵
KEYDOWN - 按鍵按下
KEYUP - 按鍵彈起
event.key - 被按的鍵對(duì)應(yīng)的字符的編碼值
"""
if event.type == pygame.QUIT:
exit()
elif event.type == pygame.MOUSEMOTION:
# print('鼠標(biāo)移動(dòng)', event.pos)
# pygame.draw.circle(window, Color.rand_color(), event.pos, 30)
# pygame.display.flip()
pass
elif event.type == pygame.MOUSEBUTTONDOWN:
# 鼠標(biāo)按下要做什么就寫在這兒
print('鼠標(biāo)按下', event.pos)
pygame.draw.circle(window, Color.rand_color(), event.pos, 30)
pygame.display.flip()
elif event.type == pygame.MOUSEBUTTONUP:
print('鼠標(biāo)彈起!', event.pos)
elif event.type == pygame.KEYDOWN:
print('按鍵按下')
print(event.key, chr(event.key))
elif event.type == pygame.KEYUP:
print('按鍵彈起')
print(event.key, chr(event.key))
鼠標(biāo)按下 (111, 160)
鼠標(biāo)彈起! (111, 160)
鼠標(biāo)按下 (120, 191)
鼠標(biāo)彈起! (165, 260)
鼠標(biāo)按下 (183, 229)
鼠標(biāo)彈起! (189, 262)
按鍵按下
119 w
按鍵彈起
119 w
按鍵按下
10.產(chǎn)生隨機(jī)顏色
from random import randint
class Color:
white = (255, 255, 255)
black = (0, 0, 0)
red = (255, 0, 0)
yellow = (255, 255, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
def __init__(self, r, g, b):
self.r = r
self.g = g
self.b = b
@staticmethod
def rand_color():
return randint(0, 255), randint(0, 255), randint(0, 255)