最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python異常處理與反射相關(guān)問(wèn)題總結(jié)

 更新時(shí)間:2021年06月17日 12:00:49   作者:華青水上  
今天給大家?guī)?lái)的是關(guān)于Python的相關(guān)知識(shí),文章圍繞著Python異常處理與反射展開(kāi),文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下

一、異常處理

在程序開(kāi)發(fā)中如果遇到一些 不可預(yù)知的錯(cuò)誤 或 你懶得做一些判斷 時(shí),可以選擇用異常處理來(lái)做。

import requests
 
while True:
    url = input("請(qǐng)輸入要下載網(wǎng)頁(yè)地址:")
    res = requests.get(url=url)
    with open('content.txt', mode='wb') as f:
        f.write(res.content)

上述下載視頻的代碼在正常情況下可以運(yùn)行,但如果遇到網(wǎng)絡(luò)出問(wèn)題,那么此時(shí)程序就會(huì)報(bào)錯(cuò)無(wú)法正常執(zhí)行

try:
    res = requests.get(url=url)
except Exception as e:
    代碼塊,上述代碼出異常待執(zhí)行。
print("結(jié)束")
import requests
 
while True:
    url = input("請(qǐng)輸入要下載網(wǎng)頁(yè)地址:")
    
    try:
        res = requests.get(url=url)
    except Exception as e:
        print("請(qǐng)求失敗,原因:{}".format(str(e)))
        continue
        
    with open('content.txt', mode='wb') as f:
        f.write(res.content)
num1 = input("請(qǐng)輸入數(shù)字:")
num2 = input("請(qǐng)輸入數(shù)字:")
try:
    num1 = int(num1)
    num2 = int(num2)
    result = num1 + num2
    print(result)
except Exception as e:
    print("輸入錯(cuò)誤")

以后常見(jiàn)的應(yīng)用場(chǎng)景:

  • 調(diào)用微信的API實(shí)現(xiàn)微信消息的推送、微信支付等
  • 支付寶支付、視頻播放等
  • 數(shù)據(jù)庫(kù) 或 redis連接和操作
  • 調(diào)用第三方的視頻播放發(fā)的功能,由第三方的程序出問(wèn)題導(dǎo)致的錯(cuò)誤。

異常處理的基本格式:

try:
    # 邏輯代碼
except Exception as e:
    # try中的代碼如果有異常,則此代碼塊中的代碼會(huì)執(zhí)行。
try:
    # 邏輯代碼
except Exception as e:
    # try中的代碼如果有異常,則此代碼塊中的代碼會(huì)執(zhí)行。
finally:
    # try中的代碼無(wú)論是否報(bào)錯(cuò),finally中的代碼都會(huì)執(zhí)行,一般用于釋放資源。
 
print("end")
 
"""
try:
    file_object = open("xxx.log")
    # ....
except Exception as e:
    # 異常處理
finally:
    file_object.close()  # try中沒(méi)異常,最后執(zhí)行finally關(guān)閉文件;try有異常,執(zhí)行except中的邏輯,最后再執(zhí)行finally關(guān)閉文件。
"""

1.1 異常細(xì)分

import requests
 
while True:
    url = input("請(qǐng)輸入要下載網(wǎng)頁(yè)地址:")
    
    try:
        res = requests.get(url=url)
    except Exception as e:
        print("請(qǐng)求失敗,原因:{}".format(str(e)))
        continue
        
    with open('content.txt', mode='wb') as f:
        f.write(res.content)

之前只是簡(jiǎn)單的捕獲了異常,出現(xiàn)異常則統(tǒng)一提示信息即可。如果想要對(duì)異常進(jìn)行更加細(xì)致的異常處理,則可以這樣來(lái)做:

import requests
from requests import exceptions
 
while True:
    url = input("請(qǐng)輸入要下載網(wǎng)頁(yè)地址:")
    try:
        res = requests.get(url=url)
        print(res)    
    except exceptions.MissingSchema as e:
        print("URL架構(gòu)不存在")
    except exceptions.InvalidSchema as e:
        print("URL架構(gòu)錯(cuò)誤")
    except exceptions.InvalidURL as e:
        print("URL地址格式錯(cuò)誤")
    except exceptions.ConnectionError as e:
        print("網(wǎng)絡(luò)連接錯(cuò)誤")
    except Exception as e:
        print("代碼出現(xiàn)錯(cuò)誤", e)
        
# 提示:如果想要寫(xiě)的簡(jiǎn)單一點(diǎn),其實(shí)只寫(xiě)一個(gè)Exception捕獲錯(cuò)誤就可以了

如果想要對(duì)錯(cuò)誤進(jìn)行細(xì)分的處理,例如:發(fā)生Key錯(cuò)誤和發(fā)生Value錯(cuò)誤分開(kāi)處理。

try:
    # 邏輯代碼
    pass
 
except KeyError as e:
    # 小兵,只捕獲try代碼中發(fā)現(xiàn)了鍵不存在的異常,例如:去字典 info_dict["n1"] 中獲取數(shù)據(jù)時(shí),鍵不存在。
    print("KeyError")
 
except ValueError as e:
    # 小兵,只捕獲try代碼中發(fā)現(xiàn)了值相關(guān)錯(cuò)誤,例如:把字符串轉(zhuǎn)整型 int("無(wú)誒器")
    print("ValueError")
 
except Exception as e:
    # 王者,處理上面except捕獲不了的錯(cuò)誤(可以捕獲所有的錯(cuò)誤)。
    print("Exception")

Python中內(nèi)置了很多細(xì)分的錯(cuò)誤,供你選擇。

常見(jiàn)異常:
"""
AttributeError 試圖訪問(wèn)一個(gè)對(duì)象沒(méi)有的樹(shù)形,比如foo.x,但是foo沒(méi)有屬性x
IOError 輸入/輸出異常;基本上是無(wú)法打開(kāi)文件
ImportError 無(wú)法引入模塊或包;基本上是路徑問(wèn)題或名稱錯(cuò)誤
IndentationError 語(yǔ)法錯(cuò)誤(的子類(lèi)) ;代碼沒(méi)有正確對(duì)齊
IndexError 下標(biāo)索引超出序列邊界,比如當(dāng)x只有三個(gè)元素,卻試圖訪問(wèn)n x[5]
KeyError 試圖訪問(wèn)字典里不存在的鍵 inf['xx']
KeyboardInterrupt Ctrl+C被按下
NameError 使用一個(gè)還未被賦予對(duì)象的變量
SyntaxError Python代碼非法,代碼不能編譯(個(gè)人認(rèn)為這是語(yǔ)法錯(cuò)誤,寫(xiě)錯(cuò)了)
TypeError 傳入對(duì)象類(lèi)型與要求的不符合
UnboundLocalError 試圖訪問(wèn)一個(gè)還未被設(shè)置的局部變量,基本上是由于另有一個(gè)同名的全局變量,
導(dǎo)致你以為正在訪問(wèn)它
ValueError 傳入一個(gè)調(diào)用者不期望的值,即使值的類(lèi)型是正確的
"""
更多異常:
"""
ArithmeticError
AssertionError
AttributeError
BaseException
BufferError
BytesWarning
DeprecationWarning
EnvironmentError
EOFError
Exception
FloatingPointError
FutureWarning
GeneratorExit
ImportError
ImportWarning
IndentationError
IndexError
IOError
KeyboardInterrupt
KeyError
LookupError
MemoryError
NameError
NotImplementedError
OSError
OverflowError
PendingDeprecationWarning
ReferenceError
RuntimeError
RuntimeWarning
StandardError
StopIteration
SyntaxError
SyntaxWarning
SystemError
SystemExit
TabError
TypeError
UnboundLocalError
UnicodeDecodeError
UnicodeEncodeError
UnicodeError
UnicodeTranslateError
UnicodeWarning
UserWarning
ValueError
Warning
ZeroDivisionError
"""

1.2 自定義異常&拋出異常

上面都是Python內(nèi)置的異常,只有遇到特定的錯(cuò)誤之后才會(huì)拋出相應(yīng)的異常。

其實(shí),在開(kāi)發(fā)中也可以自定義異常。

class MyException(Exception):
    pass
try:
    pass
except MyException as e:
    print("MyException異常被觸發(fā)了", e)
except Exception as e:
    print("Exception", e)

上述代碼在except中定義了捕獲MyException異常,但他永遠(yuǎn)不會(huì)被觸發(fā)。因?yàn)槟J(rèn)的那些異常都有特定的觸發(fā)條件,例如:索引不存在、鍵不存在會(huì)觸發(fā)IndexError和KeyError異常。

對(duì)于我們自定義的異常,如果想要觸發(fā),則需要使用:raise MyException()類(lèi)實(shí)現(xiàn)。

class MyException(Exception):
    pass
 
 
try:
    # 。。。
    raise MyException()
    # 。。。
except MyException as e:
    print("MyException異常被觸發(fā)了", e)
except Exception as e:
    print("Exception", e)
class MyException(Exception):
    def __init__(self, msg, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.msg = msg
 
 
try:
    raise MyException("xxx失敗了")
except MyException as e:
    print("MyException異常被觸發(fā)了", e.msg)
except Exception as e:
    print("Exception", e)
class MyException(Exception):
    title = "請(qǐng)求錯(cuò)誤"
 
 
try:
    raise MyException()
except MyException as e:
    print("MyException異常被觸發(fā)了", e.title)
except Exception as e:
    print("Exception", e)

案例一:你我合作協(xié)同開(kāi)發(fā),你調(diào)用我寫(xiě)的方法。

我定義了一個(gè)函數(shù)

class EmailValidError(Exception):
    title = "郵箱格式錯(cuò)誤"
 
class ContentRequiredError(Exception):
    title = "文本不能為空錯(cuò)誤"
    
def send_email(email,content):
    if not re.match("\w+@live.com",email):
        raise EmailValidError()
	if len(content) == 0 :
        raise ContentRequiredError()
	# 發(fā)送郵件代碼...
    # ...

你調(diào)用我寫(xiě)的函數(shù)

def execute():
    # 其他代碼
    # ...
    
	try:
        send_email(...)
    except EmailValidError as e:
        pass
    except ContentRequiredError as e:
        pass
    except Exception as e:
        print("發(fā)送失敗")
 
execute()
 
# 提示:如果想要寫(xiě)的簡(jiǎn)單一點(diǎn),其實(shí)只寫(xiě)一個(gè)Exception捕獲錯(cuò)誤就可以了。

案例二:在框架內(nèi)部已經(jīng)定義好,遇到什么樣的錯(cuò)誤都會(huì)觸發(fā)不同的異常。

import requests
from requests import exceptions
 
while True:
    url = input("請(qǐng)輸入要下載網(wǎng)頁(yè)地址:")
    try:
        res = requests.get(url=url)
        print(res)    
    except exceptions.MissingSchema as e:
        print("URL架構(gòu)不存在")
    except exceptions.InvalidSchema as e:
        print("URL架構(gòu)錯(cuò)誤")
    except exceptions.InvalidURL as e:
        print("URL地址格式錯(cuò)誤")
    except exceptions.ConnectionError as e:
        print("網(wǎng)絡(luò)連接錯(cuò)誤")
    except Exception as e:
        print("代碼出現(xiàn)錯(cuò)誤", e)
        
# 提示:如果想要寫(xiě)的簡(jiǎn)單一點(diǎn),其實(shí)只寫(xiě)一個(gè)Exception捕獲錯(cuò)誤就可以了。

案例三:按照規(guī)定去觸發(fā)指定的異常,每種異常都具備被特殊的含義。

1.4 特殊的finally

try:
    # 邏輯代碼
except Exception as e:
    # try中的代碼如果有異常,則此代碼塊中的代碼會(huì)執(zhí)行。
finally:
    # try中的代碼無(wú)論是否報(bào)錯(cuò),finally中的代碼都會(huì)執(zhí)行,一般用于釋放資源。
 
print("end")

當(dāng)在函數(shù)或方法中定義異常處理的代碼時(shí),要特別注意finally和return。

def func():
    try:
        return 123
    except Exception as e:
        pass
    finally:
        print(666)
        
func()

在try或except中即使定義了return,也會(huì)執(zhí)行最后的finally塊中的代碼。

二、反射

反射,提供了一種更加靈活的方式讓你可以實(shí)現(xiàn)去 對(duì)象 中操作成員(以字符串的形式去 對(duì)象 中進(jìn)行成員的操作)。

class Person(object):
    
    def __init__(self,name,wx):
        self.name = name
        self.wx = wx
	
    def show(self):
        message = "姓名{},微信:{}".format(self.name,self.wx)
        
        
user_object = Person("華青水上","hqss666")
 
 
# 對(duì)象.成員 的格式去獲取數(shù)據(jù)
user_object.name
user_object.wx
user_object.show()
 
# 對(duì)象.成員 的格式無(wú)設(shè)置數(shù)據(jù)
user_object.name = "華青水上"
user = Person("華青水上","hqss666")
 
# getattr 獲取成員
getattr(user,"name") # user.name
getattr(user,"wx")   # user.wx
 
 
method = getattr(user,"show") # user.show
method()
# 或
getattr(user,"show")()
 
# setattr 設(shè)置成員
setattr(user, "name", "華青水上") # user.name = "華青水上"

Python中提供了4個(gè)內(nèi)置函數(shù)來(lái)支持反射:

getattr,去對(duì)象中獲取成員

v1 = getattr(對(duì)象,"成員名稱")
v2 = getattr(對(duì)象,"成員名稱", 不存在時(shí)的默認(rèn)值)

setattr,去對(duì)象中設(shè)置成員

setattr(對(duì)象,"成員名稱",值)

hasattr,對(duì)象中是否包含成員

v1 = hasattr(對(duì)象,"成員名稱") # True/False

delattr,刪除對(duì)象中的成員

delattr(對(duì)象,"成員名稱")

以后如果再遇到 對(duì)象.成員 這種編寫(xiě)方式時(shí),均可以基于反射來(lái)實(shí)現(xiàn)。

class Account(object):
 
    def login(self):
        pass
 
    def register(self):
        pass
 
    def index(self):
        pass
 
    
def run(self):
    name = input("請(qǐng)輸入要執(zhí)行的方法名稱:") # index register login xx run ..
    
    account_object = Account()
    method = getattr(account_object, name,None) # index = getattr(account_object,"index")
    
    if not method:
        print("輸入錯(cuò)誤")
        return 
    method()

2.1 一些皆對(duì)象

在Python中有這么句話:一切皆對(duì)象。 每個(gè)對(duì)象的內(nèi)部都有自己維護(hù)的成員。

對(duì)象是對(duì)象

class Person(object):
    
    def __init__(self,name,wx):
        self.name = name
        self.wx = wx
	
    def show(self):
        message = "姓名{},微信:{}".format(self.name,self.wx)
        
        
user_object = Person("華青水上","hqss666")
user_object.name

類(lèi)是對(duì)象

class Person(object):
    title = "武沛齊"
 
Person.title
# Person類(lèi)也是一個(gè)對(duì)象(平時(shí)不這么稱呼)

模塊是對(duì)象

import re
 
re.match
# re模塊也是一個(gè)對(duì)象(平時(shí)不這么稱呼)。

由于反射支持以字符串的形式去對(duì)象中操作成員【等價(jià)于 對(duì)象.成員 】,所以,基于反射也可以對(duì)類(lèi)、模塊中的成員進(jìn)行操作。

簡(jiǎn)單粗暴:只要看到 xx.oo 都可以用反射實(shí)現(xiàn)。

class Person(object):
    title = "華青水上"
 
v1 = Person.title
print(v1)
v2 = getattr(Person,"title")
print(v2)
import re
 
v1 = re.match("\w+","dfjksdufjksd")
print(v1)
 
func = getattr(re,"match")
v2 = func("\w+","dfjksdufjksd")
print(v2)

2.2 import_module + 反射

# 導(dǎo)入模塊
from importlib import import_module
 
m = import_module("random")
 
v1 = m.randint(1,100)

在Python中如果想要導(dǎo)入一個(gè)模塊,可以通過(guò)import語(yǔ)法導(dǎo)入;企業(yè)也可以通過(guò)字符串的形式導(dǎo)入。

示例一:

# 導(dǎo)入模塊
import random
 
v1 = random.randint(1,100)

示例二:

# 導(dǎo)入模塊exceptions
from requests import exceptions as m
# 導(dǎo)入模塊exceptions
from importlib import import_module
m = import_module("requests.exceptions")

示例三:

# 導(dǎo)入模塊exceptions,獲取exceptions中的InvalidURL類(lèi)。
from requests.exceptions import InvalidURL
# 錯(cuò)誤方式
from importlib import import_module
m = import_module("requests.exceptions.InvalidURL") # 報(bào)錯(cuò),import_module只能導(dǎo)入到模塊級(jí)別
# 導(dǎo)入模塊
from importlib import import_module
m = import_module("requests.exceptions")
# 去模塊中獲取類(lèi)
cls = m.InvalidURL

在很多項(xiàng)目的源碼中都會(huì)有 import_modulegetattr 配合實(shí)現(xiàn)根據(jù)字符串的形式導(dǎo)入模塊并獲取成員,例如:

from importlib import import_module
 
path = "openpyxl.utils.exceptions.InvalidFileException"
 
module_path,class_name = path.rsplit(".",maxsplit=1) # "openpyxl.utils.exceptions"   "InvalidFileException"
 
module_object = import_module(module_path)
 
cls = getattr(module_object,class_name)
 
print(cls)

我們?cè)陂_(kāi)發(fā)中也可以基于這個(gè)來(lái)進(jìn)行開(kāi)發(fā),提高代碼的可擴(kuò)展性。

至此Python進(jìn)階中面向?qū)ο笾惓L幚砼c反射總結(jié)完畢,如有不當(dāng)之處,歡迎指正!

到此這篇關(guān)于Python異常處理與反射相關(guān)問(wèn)題總結(jié)的文章就介紹到這了,更多相關(guān)Python異常處理與反射內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

茶陵县| 公主岭市| 齐齐哈尔市| 延长县| 五河县| 陇西县| 阳春市| 若羌县| 高青县| 白玉县| 周宁县| 仁怀市| 绵阳市| 东方市| 绿春县| 贵阳市| 得荣县| 公主岭市| 温宿县| 宜君县| 潼南县| 南溪县| 个旧市| 通城县| 克东县| 勃利县| 都昌县| 平利县| 梁河县| 洛南县| 平定县| 茶陵县| 南川市| 类乌齐县| 娱乐| 射洪县| 临夏市| 贺兰县| 涡阳县| 思南县| 宁乡县|