1. 程式人生 > >11 異常與模組

11 異常與模組

11.1 異常與其捕獲

"""
異常:  就是直譯器處理不理了的一些錯誤,它會把異常資訊丟擲

Traceback (most recent call last):
  File "D:/day10/13-異常及其捕獲.py", line 6, in <module>
    print(a)
NameError: name 'a' is not defined

"""
# print("程式開始")
# print(a)
# num = 2/0
# # print(num)
# # open("hello.txt", "r")
# print("程式結束")
# print(a)
# open("hello.txt", "r")

try:
    # print(a)
    # open("hello.txt", "r")
    num = 2/0
    # print(123456)
except NameError:
    print("變數名錯誤")
except FileNotFoundError:
    print("檔案找不到")
# except ZeroDivisionError:
#     print("除數不能為0")
except Exception as e:   # Exception是所有異常類的父類
    print("前面所有的except都捕獲不到異常,但是try裡面又確實出現異常,就會被這個except Exception所捕獲")
    print(e)  # e 是一個異常資訊
else:
    # 沒有發生異常的時候執行else裡面的程式碼
    print("else - 這裡的程式碼什麼時候執行")
finally:
    # 有或者沒有異常的時候,都會執行finally裡面的程式碼
    print("finally - 這裡的程式碼什麼時候執行")

11.2 名片管理器-異常版

"""

{"name": '諸葛亮', "age": 40, "sex": "男"}

[{"name": '諸葛亮', "age": 40, "sex": "男"}, {"name": '劉備', "age": 45, "sex": "男"}]


思路:
1、把新增過的資料儲存在一個檔案中(儲存的格式為列表:[{"name": '諸葛亮', "age": 40, "sex": "男"}, {"name": '劉備', "age": 45, "sex": "男"}])
2、每一次執行,先讀取檔案中的名片資料(列表),把資料賦值給info_list,這個步驟稱為載入資料
3、操作完檔案之後,要退出系統之前,要儲存資料(把info_list重新寫入到檔案中)

注意: 實際上,我們修改、刪除、新增資料都是對變數info_list進行操作,而不是檔案
"""
import sys
import os


info_list = []  # 這個列表用來儲存所有的名片,它裡面每一個元素就是每一個小名片(列表)

user_name = "admin"
password = "123456"

file_name = "info.txt"


def load_info():
    """載入資料: 讀取檔案中的名片資料,把資料賦值給info_list"""
    global info_list
    try:
        f = open(file_name, "r", encoding="utf-8")
    except FileNotFoundError:
        f = open(file_name, "w", encoding="utf-8")
        f.write("[]")
        f.close()
        f = open(file_name, "r", encoding="utf-8")

    info_list = eval(f.read())   # 讀取到的資料型別是字串, 讀取到的資料是“[{"name": '諸葛亮', "age": 40, "sex": "男"}]”
    f.close()


def save_info():
    """退出系統之前,要儲存資料(把info_list重新寫入到檔案中)"""
    f = open(file_name, "w", encoding="utf-8")
    f.write(str(info_list))  # write的引數建議是字串,不能是列表
    f.close()


def welcome():
    """
        列印介面 
    """
    print("-" * 30)
    print("--------名片管理器v1.0--------")
    print("----1、新增名片")
    print("----2、刪除名片")
    print("----3、修改名片")
    print("----4、查詢名片")
    print("----5、查詢所有名片")
    print("----6、退出系統")
    print("-" * 30)


def add_info():
    """新增名片功能的函式"""
    name = input("請輸入姓名:")
    age = input("請輸入年齡:")
    sex = input("請輸入性別:")
    dic = {"name": name, "age": age, "sex": sex}
    info_list.append(dic)  # 把name, age, sex整合成一個小列表,追加到大列表info_list中
    print("【INFO】:新增成功!")
    print(info_list)  # 自己測試用,看看有沒有新增成功


def del_info():
    """刪除名片功能的函式"""
    name = input("請輸入要刪除這個名片的姓名:")
    for i in info_list:  # i就是每一個小列表
        if name in i.values():  # 判斷名字在不在小列表中
            # 在,才執行這裡的程式碼,就刪除
            # 在大列表中刪除小列表
            info_list.remove(i)
            print("【INFO】:刪除成功!")
            print(info_list)
            break  # 如果找到第一個成功了,後面不用再找了
    else:
        print("【ERROR】:刪除不成功,查無此人!")


def modify_info():
    name = input("請輸入要修改這個名片的姓名:")
    for i in info_list:  # i就是每一個小列表
        if name in i.values():  # 判斷名字在不在小列表中
            # 在,才執行這裡的程式碼,就修改
            new_name = input("請輸入新的姓名:")
            new_age = input("請輸入新的年齡:")
            new_sex = input("請輸入新的性別:")
            # 如果在列表中修改資料?通過下標來修改:列表名[下標] = 值
            info_list[info_list.index(i)] = {"name": new_name, "age": new_age, "sex": new_sex}
            print("【INFO】:修改成功!")
            print(info_list)
            break  # 如果找到第一個成功了,後面不用再找了
    else:
        print("【ERROR】:刪除不成功,查無此人!")


def search_info():
    name = input("請輸入要查詢的名片的姓名:")
    for i in info_list:  # i就是每一個小列表
        if name in i.values():  # 判斷名字在不在小列表中

            print("【INFO】:這個人的資訊如下:%s" % i)
            break  # 如果找到第一個成功了,後面不用再找了
    else:
        print("【ERROR】:刪除不成功,查無此人!")


def search_all_info():
    uname = input("請輸入管理員賬號:")
    pwd = input("請輸入管理員密碼:")

    if uname == user_name and pwd == password:
        # 展示所有資料
        # [['諸葛亮', '40', '男'], ['劉備', '45', '男']]
        print(info_list)
        # for i in info_list:
        #     # print(i)
        #     for j in i:
        #         print(j, end="\t")
        #     print()

    else:
        print("【ERROR】:使用者名稱或者密碼錯誤")


def sys_exit():
    sign = input("確定要退出系統嗎?(yes or no):")
    # if sign == "yes" or sign == "y":
    # if sign in ["yes", "y", "Y", "YES"]:
    if sign.lower() in ["yes", "y"]:
        print("【INFO】:成功退出系統!")
        sys.exit()


def main():
    # 先判斷目錄下有沒有這個檔案
    # if os.path.exists(file_name):
    #     load_info()
    # else:
    #     # 就證明沒有這個檔案,就應該建立檔案
    #     f = open(file_name, "w", encoding="utf-8")
    #     f.write("[]")
    #     f.close()
    #     load_info()
    load_info()

    while True:

        # 列印介面
        welcome()

        # 讓使用者輸入數字,表示對應的操作
        command = input("請輸入數字1~5表示對應的操作:")

        # 判斷使用者輸入的這個數字command,根據它來執行對應的功能(程式碼)
        if command == "1":
            # 新增名片  就是 往大列表info_list,新增某個人的名片
            add_info()

        elif command == "2":
            # 刪除名片
            # [{"name": '諸葛亮', "age": 40, "sex": "男"}, {"name": '劉備', "age": 45, "sex": "男"}]
            del_info()

        elif command == "3":
            # 修改名片
            #
            modify_info()

        elif command == "4":
            # 查詢名片
            # [['諸葛亮', '40', '男'], ['劉備', '45', '男']]
            search_info()

        elif command == "5":
            # 查詢所有名片
            search_all_info()

        elif command == "6":
            # 退出系統
            # break
            save_info()
            sys_exit()
        else:
            print("【ERROR】:請務必輸入數字1~5")


if __name__ == "__main__":
    main()   # 入口函式

11.3 模組

模組----本質是python檔案
    1、匯入模組和使用格式:
        1、import 模組名        (檔名)
            使用:    模組名.變數名/函式名/類名
            
        2、from 模組名 import 變數名/函式名/類名
            使用: 變數名/函式名/類名
            
        3、from 模組名 import *    # *萬用字元表示 任意的變數名/函式名/類名都匯入進來
            使用: 變數名/函式名/類名

    2、模組中的__all__:
        __all__ = ["a"]   # __all__決定了這個Python檔案中的哪一個資料(變數名/類名/函式名)允許被通過 from module_1 import * 匯入

        __all__的用法
        from module_1 import *    #  __all__只能影響這種匯入方式的匯入結果
        print(a)   # 如果module_1模組中的__all__列表中沒有這個a的話,就不能夠使用到module_1模組中的a

11.4 name

當這個模組自己執行的時候,這個__name__的值是"__main__"
當這個模組被其他檔案匯入而執行的時候,這個__name__的值是"module_1"   (即模組名)
功能:__name__就是用來區分這次跑的程式碼是自己在執行還是被匯入的時候執行的	

11.5 包的使用

"""
1、import 包名.模組名 as 簡寫
    使用: 簡寫.變數名/函式名/類名

2、from 包名.模組名 import 變數名/函式名/類名
    使用:變數名/函式名/類名
    
3、from 包名.模組名 import *   # 表示在這個模組中匯入任意的變數名/函式名/類名 
    使用:變數名/函式名/類名  
    
4、from 包名 import 模組名
    使用: 模組名.變數名/函式名/類名
    
5、from 包名 import *       # 特殊情況:需要這個包中的__init__.py檔案中有__all__這個列表,並且列表中得有這個模組名,列表中出現的模組名才允許被匯入
    使用: 模組名.變數名/函式名/類名

"""

# import module.module_1 as md_1
#
# print(md_1.a)
# md_1.fn1()
#  --------------------------

# from module.module_1 import a
# print(a)
# ---------------------------
# from module.module_1 import *
#
# print(a)
# fn1()
# ---------------------------
# from module import module_1
# print(module_1.a)
# module_1.fn1()
# ---------------------------

# from module import *
# print(module_1.a)

11.6 CS

"""

"""


class Player(object):

    def __init__(self, name):
        self.name = name
        self.hp = 100
        self.gun = None

    def __str__(self):
        return "%s的剩餘血量為%s" % (self.name, self.hp)

    def take_gun(self, obj):
        self.gun = obj
        print("%s拿起了一把%s" % (self.name, obj.name))

    # 拿起槍
    # lao_zhuang.take_gun(gun)

    def biubiubiu(self, sbd):
        self.gun.shoot(sbd)


class Bullet(object):

    def hit(self, sbd):
        sbd.hp -= 20
        print("子彈打中了%s, 剩餘的血量為:%s" % (sbd.name, sbd.hp))


class Gun(object):

    def __init__(self, name):
        self.name = name
        self.bullets = []   # 存放子彈

    def __str__(self):
        return "這是一把%s" % self.name

    def get_bullets(self):
        self.bullets = [Bullet() for _ in range(10)]
        print(self.bullets)

    def shoot(self, sbd):
        bullet = self.bullets.pop()   # self.bullets.pop()刪除一顆子彈,並且返回這個物件,所以bullet就是子彈物件
        bullet.hit(sbd)


class Enemy(object):

    def __init__(self, name):
        self.name = name
        self.hp = 100

    def __str__(self):
        return "%s的剩餘血量為%s" % (self.name, self.hp)

lao_zhuang = Player("老莊")
print(lao_zhuang)
gun = Gun("AK47")
print(gun)
enemy = Enemy("敵人")
print(enemy)
# 拿起槍
lao_zhuang.take_gun(gun)

# print(id(gun))      # 這兩個id一致
# print(id(lao_zhuang.gun))
# 裝子彈
gun.get_bullets()
# lao_zhuang.gun.get_buttles()
# 開槍
lao_zhuang.biubiubiu(enemy)
lao_zhuang.biubiubiu(enemy)
lao_zhuang.biubiubiu(enemy)