Python學(xué)習(xí)筆記-第5天: 面向?qū)ο?2) 、模塊、包

第五天 函數(shù)和面向?qū)ο?2)

今天主要學(xué)習(xí)面向?qū)ο蟮娜筇卣鳎悍庋b、繼承、多態(tài)以及簡單的設(shè)計(jì)模式和模塊化。學(xué)習(xí)項(xiàng)目及練習(xí)源碼地址:GitHub源碼

面向?qū)ο蟮娜筇卣?/h2>

object類

object類是所有類的父類,因此所有的類都有object類的屬性和方法。類定義中沒有指定父類,則默認(rèn)父類是object類。

封裝

隱藏對象的屬性和實(shí)現(xiàn)細(xì)節(jié),外提供必要的方法。相當(dāng)于將“細(xì)節(jié)封裝起來”,只對外暴露“相關(guān)調(diào)用方法”。通過Python的“私有屬性、私有方法”的方式,來實(shí)現(xiàn)“封裝”。Python沒有嚴(yán)格的語法級別的“訪問控制符”,更多的是依靠程序員自覺實(shí)現(xiàn)。

繼承

繼承可以讓子類具有父類的特性,提高了代碼的重用性。
從設(shè)計(jì)上是一種增量進(jìn)化,原有父類設(shè)計(jì)不變的情況下,可以增加新的功能,或者改進(jìn)已有的算法(重寫也叫重載父類的方法)。

  • 語法

    class 子類類名(父類 1[,父類 2,...]):
    
        類體
    
  • 定義子類時(shí),必須在其構(gòu)造函數(shù)中調(diào)用父類的構(gòu)造函數(shù)。

  • 子類繼承了父類除構(gòu)造方法之外的所有成員(包括屬性和方法)。

  • 子類可以重新定義父類中的方法,這樣就會覆蓋父類的方法,也稱為“重寫“

  • 子類中可以通過super關(guān)鍵字調(diào)用父類的方法

  • 可以使用類方法mro()或類屬性mro獲取其層次

  • 內(nèi)置函數(shù)dir(),可以方便的看到指定對象所有的屬性和方法

  • 對象方法:__str__()用于返回一個(gè)對于“對象的描述”,對應(yīng)于內(nèi)置函數(shù)str(),內(nèi)置函數(shù)print()就是調(diào)用對象的這個(gè)方法的返回值。

  • 看語法,Python是支持多重繼承的

    class Parent:
            def __init__(self,name):
                self.name = name
                print("call parent init.")
            def say_name(self):
                print('My Name Is:',self.name)
    class Children(Parent):
        def __init__(self,name,age):
            self.age = age
            Parent.__init__(self,name) # 此處不可以用super().__init__代替
        def say_age(self):
            print("I am a children,my age is:",self.age)
        def say_name(self):
            print("I am a children,my name is:",self.name)
    p = Parent("父親")
    c = Children("孩子",18)
    p.say_name()
    c.say_name()
    c.say_age()
    print(p)
    print(c)
    print(type(p))
    print(type(c))
    print(Children.mro())
    '''
    輸出結(jié)果如下:
    call parent init.
    call parent init.
    My Name Is: 父親
    I am a children,my name is: 孩子
    I am a children,my age is: 18
    <__main__.Parent object at 0x10bf69ed0>
    <__main__.Children object at 0x10bfcb1d0>
    <class '__main__.Parent'>
    <class '__main__.Children'>
    [<class '__main__.Children'>, <class '__main__.Parent'>, <class 'object'>]
    '''
    

多態(tài)

多態(tài)(polymorphism)是指同一個(gè)方法調(diào)用由于對象不同可能會產(chǎn)生不同的行為。

  • 多態(tài)是方法的多態(tài),屬性沒有多態(tài)

  • 多態(tài)的存在有 2 個(gè)必要條件:繼承、方法重寫。

    class Car:
        def __init__(self):
            print('make a car')
        def honk(self):
            print('喇叭滴滴滴')
    class BWM(car):
        def __init__(self):
            print('make a BWM car')
            Car.__init__(self)
        def honk(self):
            print('寶馬來了請閃開')
    class BYD(Car):
        def __init__(self):
            print('make a BYD car')
            Car.__init__(self)
        def honk(self):
            print('BYD正在向你靠近')
    def honk(car):
        if isinstance(car,Car):
            car.honk()
        else:
            print("沒車別嗶嗶嗶")
    bwm = BWM()
    byd = BYD()
    honk(bwm)
    honk(byd)
    honk(None)
    

簡單的設(shè)計(jì)模式

什么是設(shè)計(jì)模式?

前人總結(jié)的一系列解決各種場景問題的套路。

工廠模式

顧名思義:所謂工廠模式就是一個(gè)對象根據(jù)調(diào)用參數(shù)的不同,可以生產(chǎn)許多不同的對象。

class StarFactory:
    def __init__(self):
        print("歡迎使用明星工廠")
    def createStar(self,name):
        if name == 'man':
            return ManStar()
        elif name == "womam":
            return WomanStar()
class ManStar:
    def __init__(self):
        print("我是一名超級男明星")
class WomanStar:
    def __init__(self):
        print("我是一名超級女明星")

單列模式

單例模式(Singleton Pattern)的核心作用是確保一個(gè)類只有一個(gè)實(shí)例,并且提供一個(gè)訪問該實(shí)例的全局訪問點(diǎn)。單例模式只生成一個(gè)實(shí)例對象,減少了對系統(tǒng)資源的開銷。當(dāng)一個(gè)對象的產(chǎn)生需要比較多的資源,如讀取配置文件、產(chǎn)生其他依賴對象時(shí),可以產(chǎn)生一個(gè)“單例對象”,然后永久駐留內(nèi)存中,從而極大的降低開銷。

  • 使用new方法

  • 類實(shí)例對象在Python的模塊時(shí)是天然的單例模式

    class Singleton:
        __obj = None
        __hasInited = False
        def __init__(self,name):
            print("try init....")
            self.name = name
            if Singleton.__hasInited == False:
                Singleton.__hasInited = True
    
        def __new__(cls, *args, **kwargs):
            if cls.__obj == None:
                cls.__obj = object.__new__(cls)
            return cls.__obj
        def say_name(self):
            print(self.name)
    a = Singleton("a")
    b = Singleton("b")
    print(a)
    print(b)
    a.say_name()
    b.say_name()
    '''
    try init....
    try init....
    <__main__.Singleton object at 0x10882dad0>
    <__main__.Singleton object at 0x10882dad0>
    b 這里不是a,說明第二次改變了第一次對象的值,是一個(gè)坑
    b 
    '''
    
    

模塊和包

使用模塊化編程便于將一個(gè)任務(wù)分解成多個(gè)模塊,實(shí)現(xiàn)團(tuán)隊(duì)協(xié)同開發(fā),完成大規(guī)模程序。實(shí)現(xiàn)代碼復(fù)用和可維護(hù)性。

模塊

  • 一個(gè)模塊對應(yīng)python源文件,一般后綴名是:.py

  • 標(biāo)準(zhǔn)庫模塊

    Python 標(biāo)準(zhǔn)庫提供了操作系統(tǒng)功能、網(wǎng)絡(luò)通信、文本處理、文件處理、數(shù)學(xué)運(yùn)算等基 本的功能。比如:random(隨機(jī)數(shù))、math(數(shù)學(xué)運(yùn)算)、time(時(shí)間處理)、file(文件處理)、os(和操作系統(tǒng)交互)、sys(和解釋器交互)等。

  • 第三方模塊

  • 用戶自動(dòng)模塊

導(dǎo)入模塊

測試模塊

測試代碼

  • import語句

    import 模塊名 # 導(dǎo)入一個(gè)模塊
    import 模塊 1,模塊 2...  # 導(dǎo)入多個(gè)模塊
    import 模塊名 as 模塊別名 # 導(dǎo)入模塊并使用新名字
    

    import加載的模塊分為四個(gè)通用類別:

    1. 使用 python 編寫的代碼(.py文件);
    2. 已被編譯為共享庫的C、C++擴(kuò)展;
    3. 包好一組模塊的包
    4. 使用C編寫并鏈接到python解釋器的內(nèi)置模塊;
  • from...import

    from...import 導(dǎo)入的是模塊中的一個(gè)函數(shù)/一個(gè)類。

  • 動(dòng)態(tài)導(dǎo)入:內(nèi)置函數(shù)__import__()可以實(shí)現(xiàn)動(dòng)態(tài)導(dǎo)入模塊

  • 使用importlib模塊實(shí)現(xiàn)動(dòng)態(tài)導(dǎo)入

  • 每個(gè)模塊都有一個(gè)名稱,通過特殊變量name可以獲取模塊的名稱

    一般情況下name輸出模塊名字,對應(yīng)源文件名。僅有一個(gè)例外,就是當(dāng)一個(gè)模塊被作為程序入口時(shí)(主程序、交互式提示符下),它的name的值為“__main__”。我們可以根據(jù)這個(gè)特 點(diǎn),將模塊源代碼文件中的測試代碼進(jìn)行獨(dú)立的處理。

  • 當(dāng)導(dǎo)入一個(gè)模塊時(shí),模塊中的代碼都會被執(zhí)行。如果再次導(dǎo)入這個(gè)模塊,不會再次執(zhí)行。

    import math
    print(math.__name__)
    
    

當(dāng)需要把多個(gè)模塊放在一起時(shí),需要就需要用到包了

  • Python中的包就是一個(gè)必須有init.py的目錄

    1. 作為包的標(biāo)識,不能刪除。
    2. 用來實(shí)現(xiàn)模糊導(dǎo)入
    3. 導(dǎo)入包實(shí)質(zhì)是執(zhí)行init.py文件,可以在init.py文件中做這個(gè)包的初始化、以及需要統(tǒng)一執(zhí)行代碼、批量導(dǎo)入。
  • 導(dǎo)入包

    import 包名.模塊名
    import 包名.子包名.模塊名
    from 包名.模塊名 import 函數(shù),類,變量
    
  • 包下面可以包含“模塊(module)”,也可以再包含“子包(subpackage)”

  • 如果是子包內(nèi)的引用,可以按相對位置引入子模塊

    from .. import 模塊文件名 # 導(dǎo)入上層目錄中的模塊文件
    from . import 模塊文件名 # 導(dǎo)入本層目錄的模塊文件
    
  • sys.path和模塊搜索路徑

    當(dāng)導(dǎo)入某個(gè)模塊文件時(shí),Python解釋器一般按照如下路徑尋找模塊文件(按照順序?qū)ふ?,找到即停不繼續(xù)往下尋找):

    1. 內(nèi)置模塊

    2. 當(dāng)前目錄

    3. 程序的主目錄

    4. pythonpath目錄(如果已經(jīng)設(shè)置了pythonpath環(huán)境變量)

    5. 標(biāo)準(zhǔn)鏈接庫目錄

    6. 第三方庫目錄(site-packages目錄)

    7. .pth 文件的內(nèi)容(如果存在的話)

      在工程目錄建立這樣一個(gè)文件,一行代表一個(gè)目錄

    8. sys.path.append()臨時(shí)添加的目錄

安裝第三方庫

pip install 模塊名稱

Python的文件操作

文本文件和二進(jìn)制文件

  • 文本文件

    文本文件存儲的是普通“字符”文本,python默認(rèn)為unicode字符集(兩個(gè)字節(jié)表示一個(gè)字符,最多可以表示:65536個(gè))

  • 二進(jìn)制文件

    二進(jìn)制文件把數(shù)據(jù)內(nèi)容用“字節(jié)”進(jìn)行存儲

文件操作相關(guān)模塊概述

Python標(biāo)準(zhǔn)庫中提供了如下常用文件操作的庫:

名稱 說明
io 模塊 文件流的輸入和輸出操作 input output
os 模塊 基本操作系統(tǒng)功能,包括文件操作
glob 模塊 查找符合特定規(guī)則的文件路徑名
fnmatch 模塊 使用模式來匹配文件路徑名
fileinput 模塊 處理多個(gè)輸入文件
filecmp 模塊 用于文件的比較
cvs 模塊 用于 csv 文件處理
pickle 和 cPickle 用于序列化和反序列化
xml 包 用于 XML 數(shù)據(jù)處理
bz2、gzip、zipfile、zlib、tarfile 用于處理壓縮和解壓縮文件(分別對應(yīng)不同的算法)

常用文件操作函數(shù)

  • open()

    open(文件名[,打開方式,[encoding="字符編碼"]])
    

    打開方式有如下幾種:

    模式 描述
    r 讀 read 模式
    w f = open(r"filepath","w")。寫 write模式。如果文件不存在則創(chuàng)建;如果文件存在,則重寫新內(nèi)容;
    a 追加 append 模式。如果文件不存在則創(chuàng)建;如果文件存在,則在文件末尾追加內(nèi)容
    b 二進(jìn)制 binary 模式(可與其他模式組合使用)
    + 讀、寫模式(可與其他模式組合使用)
  • close()

    打開的文件對象必須顯式調(diào)用 close()方法 關(guān)閉文件對象。當(dāng)調(diào)用 close()方法時(shí),首先會把緩沖區(qū)數(shù)據(jù)寫入文件(也可以直接調(diào)用 flush() 方法),再關(guān)閉文件,釋放文件對象。為了確保打開的文件對象正常關(guān)閉,一般結(jié)合異常機(jī)制的finally或者with關(guān)鍵字實(shí)現(xiàn)無論何種情況都能關(guān)閉打開的文件對象。

  • write(txt)

    把字符串txt寫入到文件中

  • writelines(txtList):

    把字符串列表寫入文件中,不添加換行符

  • with

    with關(guān)鍵字(上下文管理器)可以自動(dòng)管理上下文資源,不論什么原因跳出with塊,都能確保文件正確的關(guān)閉,并且可以在代碼塊執(zhí)行完畢后自動(dòng)還原進(jìn)入該代碼塊時(shí)的現(xiàn)場。

  • read(size)

    從文件中讀取 size 個(gè)字符,并作為結(jié)果返回。如果沒有 size 參數(shù),則讀取整個(gè)文件。讀取到文件末尾,會返回空字符串。

  • readline()

    讀取一行內(nèi)容作為結(jié)果返回。讀取到文件末尾,會返回空字符串。

  • readlines()

  • 文件讀寫操作練習(xí):測試代碼

os和os.path模塊

os模塊可以幫助我們直接對操作系統(tǒng)進(jìn)行操作。我們可以直接調(diào)用操作系統(tǒng)的可執(zhí)行文件、命令,直接操作文件、目錄等等

  • os.system

    os.system 可以幫助我們直接調(diào)用系統(tǒng)的命令

    import os
    os.system("ping www.google.com")
    
  • os.startfile

    直接運(yùn)行可執(zhí)行文件

異常和錯(cuò)誤處理

python中,引進(jìn)了很多用來描述和處理異常的類,稱為異常類。異常類定義中包含了該類異常的信息和對異常進(jìn)行處理的方法。


錯(cuò)誤類型

如何定位異常

當(dāng)發(fā)生異常時(shí),Python解釋器會報(bào)相關(guān)的錯(cuò)誤信息,并會在控制臺打印出相關(guān)錯(cuò)誤信息。只需按照從上到下的順序即可追溯(Trackback)錯(cuò)誤發(fā)生的過程,最終定位引起錯(cuò)誤的那一行代碼。

異常處理語句

  • try...except

    try:
        a = 1/0
    except ZeroDivisionError:
        print("不能除零")
    except BaseException as e: # 允許多個(gè)錯(cuò)誤捕獲,更好的控制你的程序
        print(e)
    
  • else

      try:
          a = 1/1
      except ZeroDivisionError:
          print("不能除零")
      except BaseException as e: # 允許多個(gè)錯(cuò)誤捕獲,更好的控制你的程序
      else:
          print(a) # try里面的沒有錯(cuò)誤時(shí)執(zhí)行
      finally:
          print("無論如何都要執(zhí)行")# 通常用于釋放系統(tǒng)資源
    
  • finally

return語句和異常處理問題

在try....except語句中最好不要用return語句,將它放在try之外。

常見異常匯總

異常名稱 說明
ArithmeticError 所有數(shù)值計(jì)算錯(cuò)誤的基類
AssertionError 斷言語句失敗
AttributeError 對象沒有這個(gè)屬性
BaseException 所有異常的基類
DeprecationWarning 關(guān)于被棄用的特征的警告
EnvironmentError 操作系統(tǒng)錯(cuò)誤的基類
EOFError 沒有內(nèi)建輸入,到達(dá) EOF 標(biāo)記
Exception 常規(guī)錯(cuò)誤的基類
FloatingPointError 浮點(diǎn)計(jì)算錯(cuò)誤
FutureWarning 關(guān)于構(gòu)造將來語義會有改變的警告
GeneratorExit 生成器(generator)發(fā)生異常來通知退出
ImportError 導(dǎo)入模塊/對象失敗
IndentationError 縮進(jìn)錯(cuò)誤
IndexError 序列中沒有此索引(index)
IOError 輸入/輸出操作失敗
KeyboardInterrupt 用戶中斷執(zhí)行(通常是輸入^C)
KeyError 映射中沒有這個(gè)鍵
LookupError 無效數(shù)據(jù)查詢的基類
MemoryError 內(nèi)存溢出錯(cuò)誤(對于 Python 解釋器不是致命的)
NameError 未聲明/初始化對象 (沒有屬性)
NotImplementedError 尚未實(shí)現(xiàn)的方法
OSError 操作系統(tǒng)錯(cuò)誤
OverflowError 數(shù)值運(yùn)算超出最大限制
OverflowWarning 舊的關(guān)于自動(dòng)提升為長整型(long)的警告
PendingDeprecationWarning 關(guān)于特性將會被廢棄的警告
ReferenceError 弱引用(Weak reference)試圖訪問已經(jīng)垃圾回收了的對象
RuntimeError 一般的運(yùn)行時(shí)錯(cuò)誤
RuntimeWarning 可疑的運(yùn)行時(shí)行為(runtime behavior)的警告
StandardError 所有的內(nèi)建標(biāo)準(zhǔn)異常的基類
StopIteration 迭代器沒有更多的值
SyntaxError Python 語法錯(cuò)誤
SyntaxWarning 可疑的語法的警告
SystemError 一般的解釋器系統(tǒng)錯(cuò)誤
SystemExit 解釋器請求退出
TabError Tab 和空格混用
TypeError 對類型無效的操作
UnboundLocalError 訪問未初始化的本地變量
UnicodeDecodeError Unicode 解碼時(shí)的錯(cuò)誤
UnicodeEncodeError Unicode 編碼時(shí)錯(cuò)誤
UnicodeError Unicode 相關(guān)的錯(cuò)誤
UnicodeTranslateError Unicode 轉(zhuǎn)換時(shí)錯(cuò)誤
UserWarning 用戶代碼生成的警告
ValueError 傳入無效的參數(shù)
Warning 警告的基類
WindowsError 系統(tǒng)調(diào)用失敗
ZeroDivisionError 除(或取模)零 (所有數(shù)據(jù)類型)

自定義異常類

程序開發(fā)中,有時(shí)候我們也需要自己定義異常類。自定義異常類一般都是運(yùn)行時(shí)異常,通常繼承Exception或其子類即可。命名一般以 Error、Exception為后綴。

  • 自定義異常由 raise 語句主動(dòng)拋出
  • 練習(xí)自定異常源碼

小結(jié)

到目前為止,Python語言的真實(shí)基礎(chǔ)算是告一個(gè)段落。離登堂入室還有半步飛仙的距離了。接下來做的就是實(shí)戰(zhàn)+實(shí)戰(zhàn)+實(shí)戰(zhàn),將所學(xué)的知識融會貫通。之后還有關(guān)于Python高階的學(xué)習(xí),比如并發(fā),異步程序,網(wǎng)絡(luò)編程等等。

GUI實(shí)戰(zhàn)

話說Python搞后臺服務(wù)的較多,但是跨平臺的GUI開發(fā)其實(shí)也不弱,通過幾個(gè)GUI的練習(xí),鞏固一下前面所學(xué)的知識。

常用的GUI庫

  • Tkinter

    tkinter(Tk interface)是Python的標(biāo)準(zhǔn)GUI庫,支持跨
    平臺的GUI程序開發(fā)。

  • PyQT

    PyQt是一個(gè)創(chuàng)建GUI應(yīng)用程序的工具包。它是Python編程語言和Qt庫的成功融合。Qt庫是目前最強(qiáng)大的庫之一。在線指南

  • wxPython

    wxPython是Python語言的一套優(yōu)秀的GUI圖形庫,允許Python程序員很方便的創(chuàng)建完整的、功能健全的GUI用戶界面。 wxPython是作為優(yōu)秀的跨平臺GUI庫wxWidgets的Python封裝和Python模塊的方式提供給用戶的。

    就如同Python和wxWidgets一樣,wxPython也是一款開源軟件,并且具有非常優(yōu)秀的跨平臺能力,能夠支持運(yùn)行在32 [1] /64位windows、絕大多數(shù)的Unix或類Unix系統(tǒng)、Macintosh OS X下。

Tkinter編寫一個(gè)GUI程序

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 寫在前面的話 代碼中的# > 表示的是輸出結(jié)果 輸入 使用input()函數(shù) 用法 注意input函數(shù)輸出的均是字...
    FlyingLittlePG閱讀 3,228評論 0 9
  • 初識面向?qū)ο?楔子 你現(xiàn)在是一家游戲公司的開發(fā)人員,現(xiàn)在需要你開發(fā)一款叫做<人狗大戰(zhàn)>的游戲,你就思考呀,人狗作戰(zhàn)...
    go以恒閱讀 1,001評論 0 6
  • 一、Python簡介和環(huán)境搭建以及pip的安裝 4課時(shí)實(shí)驗(yàn)課主要內(nèi)容 【Python簡介】: Python 是一個(gè)...
    _小老虎_閱讀 6,339評論 0 10
  • 抽象類 什么是抽象類 與java一樣,python也有抽象類的概念但是同樣需要借助模塊實(shí)現(xiàn),抽象類是一個(gè)特殊的...
    go以恒閱讀 727評論 0 3
  • property、魔法屬性和魔法方法、多重繼承和多繼承 1.5 property 學(xué)習(xí)目標(biāo) 1. 能夠說出什么要...
    Cestine閱讀 857評論 0 1

友情鏈接更多精彩內(nèi)容