日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Python小知识 | 这些技能你不会?(终章)

發(fā)布時間:2024/9/15 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python小知识 | 这些技能你不会?(终章) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

零、寫在前面

寫完今天這一篇,Python小知識這塊就完了,一共四篇,也就是我過了一遍《零壓力學(xué)Python》后記錄下來的一些重要的點,希望對初學(xué)者或者復(fù)習(xí)Python基礎(chǔ)的讀者有所幫助,再多的話我就不說了,一切都在知識里面,加油。

一、面相對象三大特性

(1)封裝

封裝,即隱藏對象的屬性和實現(xiàn)細節(jié),僅對外公開接口,控制在程序中屬性的讀和修改的訪問級別。

封裝在平時用的比較多,在編寫一個大項目的時候,我們會自覺地根據(jù)功能分類,這里類就是一種封裝,再細點,類里的函數(shù)也是封裝,當我們使用的時候,只用類名,函數(shù)名,而不接觸具體的類體和函數(shù)體,這樣的好處是顯而易見的,對自己,項目代碼更加易讀,可維護性更高,同時不怕功能代碼被串改,對別人,合作伙伴不需要知道底層實現(xiàn)的,更容易理解代碼含義(函數(shù),方法取名時自己就要注意了)。

(2)繼承

簡單的說,繼承就是在一個現(xiàn)有類型的基礎(chǔ)上,通過增加新的方法或者重定義已有方法(下面會講到,這種方式叫重寫)的方式,產(chǎn)生一個新的類型。繼承是面向?qū)ο蟮娜齻€基本特征--封裝、繼承、多態(tài)的其中之一,我們在使用Python編寫的每一個類都是在繼承,同JAVA語言中,java.lang.Object類是所有類最根本的基類(或者叫父類、超類),如果我們新定義的一個類沒有明確地指定繼承自哪個基類,那么Python就會默認為它是繼承自O(shè)bject類的。

'''
data?:?2018.12.08
author?:?老表
goal?:?繼承簡單例子
'''


class?allStr():
????'''?父類?'''
????all_words?=?"歡迎關(guān)注簡說Python!"
????other_words?=?"人生苦短,我選Python!"

????def?all_print(self):
????????'''?打印其他的話?'''
????????print(self.other_words)??#?調(diào)用自己的類變量

class?myStr(allStr):
????'''?子類?'''
????def?my_print(self):
????????'''?打印我的話?'''
????????print(allStr.all_words)??#?調(diào)用父類變量

#?初始化類對象
my_str?=?myStr()
#?調(diào)用類方法
my_str.my_print()
#?調(diào)用父類的方法
my_str.all_print()
#?企圖外部直接修改父類變量
my_str.all_words?=?"你好,我是老表,歡迎置頂公眾號:簡說Python!"
#?調(diào)用類方法
my_str.my_print()

'''
result?:?
????歡迎關(guān)注簡說Python!
????人生苦短,我選Python!
????歡迎關(guān)注簡說Python!
'''

看上面的結(jié)果我們可以看出,我們不能直接在外部修改父類變量,在第三篇中有介紹,怎么修改類變量,也就是__init__方法的使用。

(3)多態(tài)

多態(tài)是指一個程序中同名的不同方法共存的情況。這些方法同名的原因是它們的終于功能和目的都同樣,可是因為在完畢同一功能時,可能遇到不同的詳細情況。所以須要定義含不同的詳細內(nèi)容的方法,來代表多種詳細實現(xiàn)形式。
多態(tài)包括:重載和重寫

重載

在一個類中定義了多個同名的方法,它們或有不同的參數(shù)個數(shù)或有不同的參數(shù)類型,則稱為方法的重載(Overloading)

重寫

在子類中定義某方法與其父類有同樣的名稱和參數(shù)和返回值,我們說該方法被重寫 (Overriding)。
兩者易混淆,牢記區(qū)別:有繼承關(guān)系的是重寫,沒有的是重載。

"""
author?:?老表
data?:?2018.12.09
goal?:?多態(tài)實例
"""



class?AllStr:
????"""?父類?"""
????all_words?=?"你好,簡說Python!"
????my_words?=?"歡迎關(guān)注:簡說Python!"

????def?print_str(self):
????????print(self.all_words)


class?MyStr(AllStr):
????"""?子類?"""
????def?print_str(self):
????????"""?重寫父類的方法?"""
????????print(self.my_words)

????def?print_me(self):
????????"""?屬于自己的方法?"""
????????print("人生苦短,快學(xué)Python!")

????def?print_me(self,?your_words):
????????"""?重載自己類里的方法?"""
????????print(your_words)


#?初始化一個對象
my_str?=?MyStr()
#?調(diào)用重寫父類的方法
my_str.print_str()
#?調(diào)用自己特有的方法
#?my_str.print_me()?重載后,之前的方法不可調(diào)用
#?調(diào)用子類自己重載的方法
your_words?=?"我置頂了?簡說Python!"
my_str.print_me(your_words)
'''
result?:?
????歡迎關(guān)注:簡說Python!
????我置頂了?簡說Python!
'''

需要注意的是,在Python里面重載是不被推崇的,或者說沒有,為什么呢?因為對于Python這么優(yōu)雅的語言來說,重載是沒必要的,從重載的定義來看,在一個類中定義了多個同名的方法,它們或有不同的參數(shù)個數(shù)或有不同的參數(shù)類型,Python本身就不限制變量的數(shù)據(jù)類型,這是一點,如果傳人變量個數(shù)不確定,還可以用*args,傳遞多個變量,想多少個就多少個,這是其二,最后,如果兩個函數(shù)的功能確實有很大的不同,那么就沒必要硬取兩個相同的函數(shù)名了,直接取不同的函數(shù)名加以區(qū)分其實是更好的。

二、生命游戲

介紹

生命游戲是英國數(shù)學(xué)家約翰·何頓·康威在1970年發(fā)明的細胞自動機。它包括一個二維矩形世界,這個世界中的每個方格居住著一個活著的或死了的細胞。一個細胞在下一個時刻生死取決于相鄰八個方格中活著的或死了的細胞的數(shù)量。如果相鄰方格活著的細胞數(shù)量過多,這個細胞會因為資源匱乏而在下一個時刻死去;相反,如果周圍活細胞過少,這個細胞會因太孤單而死去。

基本規(guī)律

對于網(wǎng)格中的每個位置,計算有多少個鄰接位置中有活細胞,包括對角鄰接位置,因此一個方塊的周圍最多有八個活細胞(數(shù)值為1的方塊),最少為零,規(guī)則就是,如果這個方塊周圍的活細胞數(shù)等于三,就繁殖,也就是值變?yōu)?,如果這個方塊周圍的活細胞數(shù)少于兩個或者大雨三個,則該方塊中細胞死亡,值變?yōu)?。

(1)Matrix2D類代碼實現(xiàn)

新建一個matrix2d.py文件,把下面代碼封裝到里面,一個專門用于處理二維數(shù)組的類。

"""
二維矩陣類
"""



class?Matrix2D:
????"""?通用的二維矩陣類?"""

????def?__init__(self,?rows,?cols):
????????"""?初始化矩陣row行,col列?"""
????????self.grid?=?[[0]*cols?for?_?in?range(rows)]
????????self.rows?=?rows
????????self.cols?=?cols

????def?get_cell(self,?r,?c):
????????"""?獲取單元格(r,c)的值?"""
????????return?self.grid[r][c]

????def?set_cell(self,?n,?**args):
????????"""?設(shè)置某個位置的值?"""
????????for?r,?c?in?args:
????????????self.grid[r][c]?=?n

????def?inc_cells(self,?**args):
????????"""?將任意的單元格?+1?"""
????????for?r,?c?in?args:
????????????self.grid[r][c]?+=?1

????def?set_all_cells(self,?n=0):
????????"""?將所有單元格值都設(shè)置為?n?"""
????????for?i?in?range(self.rows):
????????????for?j?in?range(self.cols):
????????????????self.grid[i][j]?=?n

(2)主函數(shù)

"""
生命游戲
"""


from?lifemat?import?Matrix2D

rows?=?5
cols?=?5
#?存儲圖符號的二維數(shù)組
life_mat?=?Matrix2D(rows,?cols)
#?存儲具體數(shù)據(jù)的二維數(shù)組
nc_mat?=?Matrix2D(rows,?cols)
#?初始化
life_mat.set_cells(1,?(1,?3),?(2,?1),?(2,?3),?(3,?2),?(3,?3))
#?創(chuàng)建邊界字符串
border_str?=?'?_?'?*?cols


def?get_mat_str(a_mat):
????"""?處理打印字符串?"""
????disp_str?=?''
????for?i?in?range(rows):
????????lst?=?[get_chr(a_mat,?i,?j)?for?j?in?range(cols)]
????????disp_str?+=?''.join(lst)?+?'\n'
????return?disp_str


def?get_chr(a_mat,?r,?c):
????"""?設(shè)置圖符號?"""
????return?'?1?'?if?a_mat.get_cell(r,?c)?>?0?else?'?0?'


def?do_generation():
????"""?打印當前狀態(tài)并生成下個狀態(tài)?"""
????#?打印當前生命矩陣狀態(tài)
????print(border_str?+?'\n'?+?get_mat_str(life_mat))
????#?把數(shù)據(jù)全部置0
????nc_mat.set_all_cells(0)

????#?根據(jù)圖符號矩陣life_mat來給nc_mat賦值

????for?i?in?range(rows):
????????for?j?in?range(cols):
????????????if?life_mat.get_cell(i,?j):
????????????????#?環(huán)繞圖像,使有限的二維數(shù)組變成沒有邊界的生命游戲
????????????????im?=?(i?-?1)?%?rows
????????????????ip?=?(i?+?1)?%?rows???#?當前行號-/+?1
????????????????jm?=?(j?-?1)?%?cols
????????????????jp?=?(j?+?1)?%?cols???#?當前列號-/+?1
????????????????#?設(shè)置數(shù)據(jù)量為?1?,表示有活細胞
????????????????nc_mat.inc_cells((im,?jm),?(im,?j),?(im,?jp),?(i,?jm),
?????????????????????????????????(i,?jp),?(ip,?jm),?(ip,?j),?(ip,?jp))
????#?根據(jù)鄰居數(shù)量矩陣按規(guī)則生成下一代
????for?i?in?range(rows):
????????for?j?in?range(cols):
????????????n?=?nc_mat.get_cell(i,?j)
????????????if?n?<?2?or?n?>?3:??????#?死亡現(xiàn)象
????????????????life_mat.set_cells(0,?(i,?j))
????????????elif?n?==?3:????????????#?繁殖現(xiàn)象
????????????????life_mat.set_cells(1,?(i,?j))

import?time
n?=?100
for?i?in?range(n):
????#?循環(huán)調(diào)用迭代
????do_generation()
????#?設(shè)置時間間隔
????time.sleep(1)

運行效果

生命游戲運行效果


錄了20s有興趣可以慢慢看~

建議自己先把邏輯思路理清,然后把代碼復(fù)現(xiàn)一遍,肯定有很大收獲哦~
《零壓力學(xué)Python》里說,學(xué)習(xí)新編程語言的時候,如果能使用它編寫出生命游戲,就說明掌握了這門語言,編完后,我覺得是有很大道理的,不說所有,能弄懂這個程序,至少可以說明你的基礎(chǔ)過關(guān)了。

三、裝飾器

簡單說明是什么有什么用

簡單的稱為裝飾其他函數(shù)的函數(shù)。
我先說一下我的裝飾器的理解,然后再上一些例子。

裝飾器就是一個函數(shù),和一般函數(shù)一樣,裝飾器可以有返回值,參數(shù),代碼段,這個函數(shù)里面還包含了一個或多個函數(shù),對,函數(shù)的嵌套,同樣里面的函數(shù)和一般函數(shù)也是一樣的,可以擁有一切普通函數(shù)該擁有的,簡單來說,裝飾器就是把函數(shù)當做普通變量來用,哪大家會好奇,裝飾器到底有什么用呢?

書上是這樣說的”裝飾器給函數(shù)名重新賦值,使其指向原始函數(shù)的包裝板,包裝板不僅具備原始函數(shù)的所有功能,還添加了新功能“,這樣一理解,可以這樣轉(zhuǎn)化,裝飾器就是用來豐富函數(shù)功能的,那是嘛時候會起作用呢?

調(diào)試的時候,特別是對于大程序的調(diào)試,我不可能在一個模塊里幾百個函數(shù)一個個調(diào)試,這個時候來個裝飾器就很好了,或者說我想驗證某個東西,但不希望在原始函數(shù)添加,這個時候裝飾器就是一把利器了,下面讓我們隨這幾個例子來更好的學(xué)習(xí)裝飾器吧。

實例學(xué)習(xí)

1.最簡單的例子

def?my_decorator(f):
????"""?裝飾器,將一個函數(shù)作為參數(shù)傳遞進來,進行包裝,然后返回?"""
????def?wrapper():
????????print("I?am?doing?extra?stuff.")
????????f()
????????print("Doing?more?extra?stuff.")
????return?wrapper

def?hello():
????print("簡說Python 你好!")

new_hello?=?my_decorator(hello)
new_hello()
'''
result:
????I?am?doing?extra?stuff.
????簡說Python 你好!
????Doing?more?extra?stuff.
'''

2.中等簡單

def?my_decorator(f):
????"""?裝飾器,將一個函數(shù)作為參數(shù)傳遞進來,進行包裝,然后返回?"""
????def?wrapper():
????????print("I?am?doing?extra?stuff.")
????????f()
????????print("Doing?more?extra?stuff.")
????return?wrapper


'''
說明一下:新語法,@+裝飾器的名稱,相當于
def?hello():
????print("Hi,簡說Python!")
hello?=?my_decorator(hello)
'''

@my_decorator
def?hello():
????print("Hi,簡說Python!")

hello()

'''
result:
????I?am?doing?extra?stuff.
????Hi,簡說Python!
????Doing?more?extra?stuff.
'''

3.復(fù)雜案例

from?time?import?time

def?diagnostics(f):
????def?wrapper(*args,?**kwargs):
????????"""?這個包裝函數(shù)帶參數(shù),
????????*args處理多個參數(shù),
????????**kwargs可以處理具名參數(shù)?"""

????????print("Executed",?f.__name__,?"at",?time())
????????value?=?f(*args,?**kwargs)
????????print("Exited",?f.__name__,?"at",?time())
????????print("Arguments:",args)
????????print("Value?returned:",?value,?"\n")
????????return?value
????return?wrapper


@diagnostics
def?print_nums():
????"""?不帶參數(shù),沒有返回值?"""
????for?i?in?range(4):
????????print(i,?end="\t")


@diagnostics
def?add_nums(a,?b):
????"""?帶參數(shù),有返回值?"""
????return?a+b


#?調(diào)用經(jīng)過裝飾器裝飾過的函數(shù)
print_nums()
print("-"*50)
add_nums(2,?3)
print("-"*50)

'''
result:
????Executed?print_nums?at?1544353643.8159559
????0???1???2???3???Exited?print_nums?at?1544353643.8159559
????Arguments:?()
????Value?returned:?None?

????--------------------------------------------------
????Executed?add_nums?at?1544353643.8159559
????Exited?add_nums?at?1544353643.8159559
????Arguments:?(2,?3)
????Value?returned:?5?

????--------------------------------------------------
'''

以上就是裝飾器的基本講解了,細細品讀,理清其中思緒,就能很好的理解和掌握了,希望對大家有所幫助。

靈活應(yīng)用這些基本操作,讓你的工作學(xué)習(xí)事半功倍。


推薦閱讀:(點擊標題即可跳轉(zhuǎn))



??長按圖片 1 秒即可關(guān)注哦~

總結(jié)

以上是生活随笔為你收集整理的Python小知识 | 这些技能你不会?(终章)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。