python面向對象程序編程學習記錄

1. case_1:簡單的類,類方法創建

class Cat:
    
    def __init__(self, new_name):
        self.name=new_name
        print("%s 來了" % self.name)
        
    def __del__(self):
        print("%s 去了" % self.name)
        
#    def __str__(self):
#        return "我是小貓【%s】" % self.name
    
    """
    def eat(self, new_name):
        self.name=new_name
        print(" %s 愛吃魚" %self.name)
        
    def drink(self, new_name):
        self.name=new_name
        print(" %s 愛喝水" %self.name)
    """      
        
#創建貓對象
tom=Cat("Tom")
print(tom)
print(tom)

del tom

輸出:

Tom 來了
Tom 去了
<__main__.Cat object at 0x0000000005FD1588>
<__main__.Cat object at 0x0000000005FD1588>
Tom 去了


2. case_2:小明愛跑步

class Person:
    
    def __init__(self, name, weight):
        self.name = name
        self.weight = weight
        print("我是 %s,我被創建出來了,weight: %.2f" % (self.name,self.weight))
        
    def __str__(self):
        return "我是 %s,大家好" % self.name
        
    def run(self):
        self.weight -= 0.5
        print("now weight:%.2f" % self.weight)
        
    def eat(self):
        self.weight += 1
        print("now weight:%.2f" % self.weight)
        

xiaoming=Person("小明",65)
xiaoming.run()
xiaoming.eat()
print(xiaoming)
輸出:

我是 小明,我被創建出來了,weight: 65.00
now weight:64.50
now weight:65.50
我是 小明,大家好


3. case_3:添加傢俱

class HouseItem:
    """傢俱類"""
    def __init__(self, name, area):
        self.name = name
        self.area = area
        
    def __str__(self):
        return "[%s] 佔地:%.2f" % (self.name, self.area)
        
    
class House:
    """房子類"""
    def __init__(self, house_type, area):
        self.house_type=house_type
        self.area=area
        
        self.free_area=area
        self.item_list=[]
        
    def __str__(self):
        return ("戶型: %s\n總面積: %.2f[剩餘: %.2f]\n傢俱: %s" 
                % (self.house_type, self.area, 
                   self.free_area, self.item_list))
        
    def add_item(self, item):
        print("要添加 %s" % item)
        #1.判斷傢俱的面積
        if item.area > self.free_area:
            print("%s 的面積太大了,無法添加" % item.name)
            return
        
        #2.將傢俱的名稱添加到列表中
        self.item_list.append(item.name)
        
        #3.計算剩餘面積
        self.free_area -= item.area
        
        
        
#1. 創建傢俱
bed=HouseItem("席夢思", 400)
chest=HouseItem("衣櫃", 2)
table=HouseItem("餐桌", 1.5)

print(bed)
print(chest)
print(table)

#2. 創建房子對象
my_house = House("兩室一廳", 60)
my_house.add_item(bed)
my_house.add_item(chest)
my_house.add_item(table)
print(my_house)

輸出:

[席夢思] 佔地:400.00
[衣櫃] 佔地:2.00
[餐桌] 佔地:1.50
要添加 [席夢思] 佔地:400.00
席夢思 的面積太大了,無法添加
要添加 [衣櫃] 佔地:2.00
要添加 [餐桌] 佔地:1.50
戶型: 兩室一廳
總面積: 60.00[剩餘: 56.50]
傢俱: ['衣櫃', '餐桌']

4. case_4:士兵突擊(面對對象封裝案列)

class Gun:
    def __init__(self, model):
        #1. 槍的型號
        self.model = model
        #2. 子彈的數量初始化爲0
        self.bullet_count = 0
        
    def add_bullet(self, count):
        self.bullet_count += count
        
    def shoot(self):
        #1. 判斷子彈的數量
        if self.bullet_count <= 0:
            print("[%s]沒有子彈了..." % self.model)
            return

        #2. 發射子彈,-1
        self.bullet_count -=1
        
        #3. 提示發射信息
        print("[%s]突突突...[%d]" % (self.model, self.bullet_count))
        
        
class Soldier:
    def __init__(self, name):
        #1. 姓名
        self.name = name
        #2. 槍 - 默認新兵沒有槍
        self.gun = None
        
    def fire(self):
        #1. 判斷士兵是否有槍
        if self.gun is None:
            print("[%s] 還沒有槍..." % self.name)
            return
        #2. 高喊口號
        print("衝啊...[%s]" % self.name)
        #3. 讓槍填裝子彈
        if self.gun.bullet_count <= 0:
            self.gun.add_bullet(50)    
        #4. 讓槍發射子彈
        self.gun.shoot()
        
        
#1. 創建槍對象
ak47 = Gun("AK47")

ak47.add_bullet(100)
ak47.shoot()

#2. 創建許三多
xusanduo = Soldier("許三多")
xusanduo.gun = ak47
xusanduo.fire()
print(xusanduo.gun)
輸出:

[AK47]突突突...[99]
衝啊...[許三多]
[AK47]突突突...[98]
<__main__.Gun object at 0x0000000005FC7C18>


5. 私有屬性,私有方法,繼承,重寫,擴展

只要在屬性變量的前面加兩個下劃線,例如:__agr

重寫: 當父類大方法實現滿足不了子類需求時,可以對方法進行重寫

case_5:

class Animal:
    def walk(self):
        print("走---")
        
    def run(self):
        print("跑---")
        
    def eat(self):
        print("吃---")
        
                
class Dog(Animal):
    def bark(self):
        print("汪汪叫")
        
        
class Cat_1(Animal):
    def catch(self):
        print("抓老鼠")
        
        
class XiaoTianQuan(Dog):
    def fly(self):
        print("我會飛")
    # 方法擴展的代碼
    def bark(self):
        #1. 針對子類特有的要求,編寫代碼
        print("流披如我...")
        #2. 使用super(). 調用原本在父類中封裝的方法
        super().bark()
        #3. 增加其他子類的代碼
        print("$%^*$%^*$%^*$%^*")
        
        
    # 方法重寫的代碼    
#    def bark(self):
#        print("流披如我...")

        
        
# 創建一個哮天犬的對象
xtq = XiaoTianQuan()

xtq.fly()
xtq.bark()
xtq.walk()
#xtq.catch()
輸出:

我會飛
流披如我...
汪汪叫
$%^*$%^*$%^*$%^*
走---


6.  case_6:父類的私有屬性和私有方法案列

class A:
    def __init__(self):
        self.num1 = 100
        self.__num2 = 200
        
    def __test(self):
        print("私有方法 %d %d" % (self.num1,self.__num2))
        
    def test(self):
        print("父類的公有方法 %d" % self.__num2)
        self.__test()
        
        
class B(A):
    def demo(self):
        #1. 在子類的對象方法中,不能訪問父類的私有屬性
        #print("訪問父類的私有屬性 %d" % self.__num2)
        #2. 在子類的對象方法中,不能調用父類的私有方法
        #self.__test()
        #3. 訪問父類的公有屬性
        print("子類方法 %d" % self.num1)
        #4. 調用父類的公有方法
        self.test()
        
        
# 創建一個子類對象
b = B()
print(b)

b.demo()
# 在外界訪問父類的公有方法/調用公有方法
#print(b.num1)
#b.test()

# 在外界不能直接訪問對象的私有屬性/調用方法
#print(b.__num2)
#b.__test()
輸出:

<__main__.B object at 0x0000000005323BA8>
子類方法 100
父類的公有方法 200
私有方法 100 200


7. case_7:多繼承案列

class AA:
    def test(self):
        print("AA --- test 方法")
        
    def demo(self):
        print("AA --- demo 方法")
        
        
class BB:
    def test(self):
        print("BB --- test 方法")
        
    def demo(self):
        print("BB --- demo 方法")
        
        
class C(AA, BB):
    """多繼承可以讓子類對象,同時具有多個父類的屬性和方法"""
    pass


# 創建子類對象
c = C()

c.test()
c.demo()

# 確定C類對象調用方法的順序
print(C.__mro__)
輸出:

AA --- test 方法
AA --- demo 方法
(<class '__main__.C'>, <class '__main__.AA'>, <class '__main__.BB'>, <class 'object'>)


8.  case_8:多態案例

class Dog(object):
    def __init__(self, name):
        self.name = name
        
    def game(self):
        print("[%s] 普通的狗狗就普通地玩耍" % self.name)
        
        
class XiaoTianDog(Dog):
    def game(self):
        print("[%s] 不普通的狗狗就不普通地玩耍" % self.name)
        
        
class Person(object):
    def __init__(self, name):
        self.name = name
        
    def game_with_dog(self, dog):
        print("%s 和 %s 快樂的玩耍..." % (self.name, dog.name))
        # 讓狗狗玩耍
        dog.game()
        
        
#1. 創建一個狗對象
#wangcai = Dog("旺財")
wangcai = XiaoTianDog("飛天旺財")
#2. 創建一個小明對象
xiaoming = Person("小明")
#3. 讓小明調用和狗玩耍的方法
xiaoming.game_with_dog(wangcai)
輸出:

小明 和 飛天旺財 快樂的玩耍...
[飛天旺財] 不普通的狗狗就不普通地玩耍



9. case_9:類屬性和類方法案列

class Tool(object):
    # 使用賦值語句,定義類屬性,記錄創建工具對象的總數(不會用於記錄具體對象的特徵)
    count = 0
    
    @classmethod
    def show_tool_count(cls):
        print("工具對象的數量 %d" % cls.count)
    
    def __init__(self, name):
        self.name = name
        #針對類屬性做一個計數+1
        Tool.count += 1
        
        
# 創建工具對象
tool1 = Tool("斧頭")
tool2 = Tool("榔頭")
tool3 = Tool("鐵鍬")

print(tool1.count)
print(tool2.count)
print(tool3.count)
print(Tool.count)
Tool.show_tool_count()
輸出:

3
3
3
3
工具對象的數量 3



10. case_10:靜態方法案列(靜態方法 既不需要訪問實例屬性或者調用實例方法 也不需要訪問類屬性或者調用類方法
class Dog(object):
    # 狗對象計數
    dog_count = 0
    
    @staticmethod
    def run():
        # 不需要訪問實例屬性也不需要訪問類屬性的方法
        print("狗在跑...")
        
    def __init__(self, name):
        self.name = name
        
        
# 通過類名.調用靜態方法 - 不需要創建對象
Dog.run()
輸出:

狗在跑...



11. case_11:方法綜合案例
class  Game(object):
    # 類屬性
    top_score = 66
    
    # 類方法
    @classmethod
    def show_top_score(cls):
        print("歷史最高分:%d" % cls.top_score)
        
    # 靜態方法
    @staticmethod
    def show_help():
        print("遊戲幫助信息")
        
    def __init__(self, name):
        self.name = name
        
    def start_game(self):
        print("%s 請您做好準備,遊戲即將開始" % self.name)
        
        
#1. 查看遊戲幫助
Game.show_help()
#2. 查看歷史高分
Game.show_top_score()
#3. 創建遊戲對象,開始遊戲
game = Game("小明")
game.start_game()
輸出:

遊戲幫助信息
歷史最高分:66
小明 請您做好準備,遊戲即將開始



12.  __new__方法

__new__方法是內置的靜態方法,主要有兩個作用:
1. 在內存空間中爲對象分配空間
2. 返回對象的應用

Python的解釋器獲得對象的引用後,將引用作爲第一個參數傳遞給__init__

case_12:

class MusicPlayer(object):
    """ *args多值的元組參數, **kwargs多值的字典參數"""
    def __new__(cls, *args, **kwargs):
        #1. 創建對象時,new方法會被自動調用
        print("創建對象,分配空間")
        #2. 爲對象分配空間,通過調用父類的new方法
        instance = super().__new__(cls)
        #3. 返回對象的引用
        return instance
    
    def __init__(self):
        print("播放器初始化")
        
        
# 創建播放器對象
player = MusicPlayer()
print(player)

player_another = MusicPlayer()
print(player_another)
輸出: 
創建對象,分配空間
播放器初始化
<__main__.MusicPlayer object at 0x0000000007922F98>
創建對象,分配空間
播放器初始化
<__main__.MusicPlayer object at 0x0000000007905B38>



13. 單例設計模式

目的: 讓類創建的對象,在系統中只有唯一的一個實例
case_13:

class MusicPlayer(object):
    # 定義類屬性記錄單例對象引用
    instance = None
    # 記錄是否執行過初始化方法
    init_flag = False
    
    def __new__(cls, *args, **kwargs):
        #1. 判斷類屬性是否已經被賦值
        if cls.instance is None:
            #2. 調用父類的方法,爲第一個對象分配空間
            cls.instance = super().__new__(cls)
        #3. 返回對象引用
        return cls.instance
    
    def __init__(self):
        #1. 判斷類是否執行過初始化動作
        if MusicPlayer.init_flag:
            return
        #2. 如果沒有執行過,則執行初始化動作
        print("初始化播放器")
        #3. 修改類屬性的標記
        MusicPlayer.init_flag = True
                  
            
# 創建多個對象
player1 = MusicPlayer()
print(player1)

player2 = MusicPlayer()
print(player2)
輸出:

初始化播放器
<__main__.MusicPlayer object at 0x0000000005D0A9E8>
<__main__.MusicPlayer object at 0x0000000005D0A9E8>



14. 異常

在程序開發中,如果對某些代碼的執行不能確定是否正確,可以增加try(嘗試)來捕獲異常

try:下方編寫要嘗試代碼,不能確定是否能夠正常執行的代碼

except:如果不是,下方編寫嘗試失敗的代碼

 

case_14:

try:
    # 不能確定正確執行的代碼
    num = int(input("請輸入一個整數:"))
except:
    # 錯誤的處理代碼
    print("請輸入正確的整數")
    
print("-" * 50)
輸出:

請輸入一個整數:d
請輸入正確的整數
--------------------------------------------------



15. 錯誤類型捕獲

case_15_1:已知錯誤類型進而捕獲

try:
    # 提示用戶輸入一個整數
    num = int(input("請輸入一個整數:"))

    # 使用8除以用戶輸入的整數並且輸出
    result = 8 / num

    print(result)
except(ZeroDivisionError):
    print("除0錯誤")
except ValueError:
    print("請輸入正確的整數")
輸出:

請輸入一個整數:a
請輸入正確的整數


case_15_2:捕獲未知錯誤

如果希望程序無論出現任何錯誤,都不會因爲python解釋器拋出的異常而終止,可以在增加一個except

try:
    # 提示用戶輸入一個整數
    num = int(input("請輸入一個整數:"))

    # 使用8除以用戶輸入的整數並且輸出
    result = 8 / num

    print(result)
except ValueError:
    print("請輸入正確的整數")
except Exception as result:
    print("未知錯誤 %s" % result)
輸出:

請輸入一個整數:0
未知錯誤 division by zero



16. case_16:完整的異常語法

try:
    # 提示用戶輸入一個整數
    num = int(input("請輸入一個整數:"))

    # 使用8除以用戶輸入的整數並且輸出
    result = 8 / num

    print(result)
except ValueError:
    print("請輸入正確的整數")
except Exception as result:
    print("未知錯誤 %s" % result)
else:
    print("嘗試成功纔會出現的代碼")
finally:
    print("無論是否出現錯誤都會執行的代碼")
輸出:

請輸入一個整數:10
0.8
嘗試成功纔會出現的代碼
無論是否出現錯誤都會執行的代碼



17.  異常的傳遞

當函數/方法執行出現異常,會將異常傳遞黑函數/方法的調用一方,如果傳遞到主程序,荏苒沒有異常處理,程序纔會被終止

case_17:

def demo1():
    return int(input("請輸入整數:"))

def demo2():
    return demo1()

#print(demo2())

# 利用異常的傳遞性,在主程序捕獲異常
try:
    print(demo2())
except Exception as result:
    print("未知錯誤 %s" % result)
輸出:

請輸入整數:j
未知錯誤 invalid literal for int() with base 10: 'j'



18. 主動拋出異常(根據應用程序特有的業務需求主動拋出異常)
  1. 創建一個Exception的對象
  2. 使用raise關鍵字拋出一場對象
case_18:
def input_password():
    #1. 提示用戶輸入密碼
    pwd = input("請輸入密碼:")
    #2. 判斷密碼長度 >= 8,返回用戶輸入的密碼
    if len(pwd) >= 8:
        return pwd
    #3. 如果 < 8,主動拋出異常
    print("主動拋出異常")
    # 1> 創建異常對象 - 可以使用錯誤信息字符串作爲參數(描述信息)
    ex = Exception("密碼長度不夠")
    # 2> 主動拋出異常
    raise ex
    
# 提示用戶輸入密碼
try:
    print(input_password())
except Exception as result:
    print(result)
輸出:
請輸入密碼:123
主動拋出異常
密碼長度不夠


19. 模塊
每一個以擴展名py結尾的python原地阿媽文件都是一個模塊(全局變量,函數,類)
case_19:
import test_module_1 as DogModule
import test_module_2 as CatModule
import random

#test_module_1.say_hello()
#test_module_2.say_hello()
DogModule.say_hello()
CatModule.say_hello()

#dog = test_module_1.Dog()
##print(dog)
dog = DogModule.Dog()
print(dog)

#cat = test_module_2.Cat()
#print(cat)
cat = CatModule.Cat()
print(cat)

print(DogModule.__file__)
print(random.__file__)
輸出:
我是 模塊1
我是 模塊2
<test_module_1.Dog object at 0x000000000538A9E8>
<test_module_2.Cat object at 0x0000000005D0AA90>
D:\pythonCode\pythonHeiMa\test_module_1.py
d:\python3.6\lib\random.py


20. 包(package)

包是一個包含多個模塊的特殊目錄(目錄下必須包含init.py),包名的命名方式和變量名一致,小寫字母+_

hm_message爲製作的package



21. 文件基本操作
  1. 打開文件
  2. 讀,寫文件
  3. 關閉文件

操作文件的函數和方法

  1. open 打開文件,並且返回文件操作對象
  2. read 將文件內容讀取到內存
  3. write 將指定的內容寫入文件
  4. close 關閉文件

訪問方式 說明

r 以只讀方式打開文件(默認模式)

w 只寫方式(如果文件存在則會被覆蓋,不存在則創建)

a 以追加的方式打開文件,文件指針放在文件的結尾

r+ 以讀寫方式打開文件(如果文件不存在,拋出異常)

w+ 以讀寫方式打開文件(如果文件存在則會被覆蓋,不存在則創建)

a+ 以讀寫方式打開文件(如果文件存在,文件指針將會放在文件的結尾,不存在則創建)

readline方法:一次讀取一行,方法執行後,會把文件指針移動到下一行,準備再次讀取


case_21_1:
#1. 打開文件
file = open("README", "w")
#2,文件讀寫
file.write("hello")
#3. 文件關閉
file.close()

file = open("README")
text = file.read()
print(text)
file.close()
輸出:
hello

case_21_2:
# 大文件複製
#1. 打開文件
file_read = open("README")
file_write = open("README[附件]", "w")

#2,文件讀寫
while True:
    # 讀取一行內容
    text = file_read.readline()
    
    # 判斷是否讀取到內容
    if not text:
        break
        
    file_write.write(text)
    
#3. 文件關閉
file_read.close()
file_write.close()


22. 文件/目錄的常用管理操作(需要導入os模塊)

文件操作:

  1. os.rename(源文件,目標文件)
  2. os.remove(文件名)

目錄操作:

  1. os.listdir(目錄名)
  2. os.mkdir(目錄名)
  3. os.rmdir(目錄名)
  4. os.getcwd():獲取當前目錄
  5. os.chdir(目錄名):修改工作目錄
  6. os.path.isdir(文件路徑):判斷是否是文件


23. 文本文件的編碼格式

python2.x 默認使用ASCII編碼 python3.x 默認使用UTF-8編碼

ASCII編碼:

  1. 只有256個ASCII字符
  2. 一個ASCII在內存中佔用一個字節的空間

UTF-8編碼格式:

  1. 計算機中使用1~6個字節來表示一個UTF-8字符,涵蓋了地球上幾乎所有地區的文字
  2. 大多數漢字使用3個字節表示
  3. UTF-8是UNICODE編碼的一種編碼格式

python2.x中使用中文方法:

在文件第一行增加以下注釋代碼,解釋器會以UTF-8編碼來處理文件

# *-* coding:utf8 *-*
或者
# coding=utf8

case_23:
# *-* coding:utf8 *-*

# 引號前面的u告訴解釋器這是一個utf8編碼格式的字符串(針對python2的改動)
hello_str = u"hello世界"

print(hello_str)

for c in hello_str:
    print(c)
輸出:
hello世界
h
e
l
l
o
世
界




最後感謝黑馬python面向對象的優秀教學視頻。












發佈了33 篇原創文章 · 獲贊 19 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章