Python基礎教程(第八章 異常)

来源:http://www.cnblogs.com/Marlowes/archive/2016/04/27/5428641.html
-Advertisement-
Play Games

本文內容全部出自《Python基礎教程》第二版,在此分享自己的學習之路。 lxx___歡迎轉載:http://www.cnblogs.com/Marlowes/p/5428641.htmllxx___ Created on Marlowes 在編寫程式的時候,程式員通常需要辨別事件的正常過程和異常( ...


本文內容全部出自《Python基礎教程》第二版,在此分享自己的學習之路。

______歡迎轉載:http://www.cnblogs.com/Marlowes/p/5428641.html______

 

                                Created on Marlowes

 

在編寫程式的時候,程式員通常需要辨別事件的正常過程和異常(非正常)的情況。這類異常事件可能是錯誤(比如試圖除以0),或者是不希望經常發生的事情。為了能夠處理這些異常事件,可以在所有可能發生這類事件的地方都使用條件語句(比如讓程式檢查除法的分母是否為零)。但是,這麼做可能不僅會沒效率和不靈活,而且還會讓程式難以閱讀。你可能會想直接忽略這些異常事件,期望它們永不發生,但Python的異常對象提供了非常強大的替代解決方案。

本章介紹如何創建和引發自定義的異常,以及處理異常的各種方法。

 

8.1 什麼是異常

Python用異常對象(exception object)來表示異常情況。遇到錯誤後,會引發異常。如果異常對象並未被處理或捕捉,程式就會用所謂的回溯(traceback, 一種錯誤信息)終止執行:

>>> 1 / 0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero

如果這些錯誤信息就是異常的全部功能,那麼它也就不必存在了。事實上,每個異常都是一些類(本例中是ZeroDivisionError)的實例,這些實例可以被引發,並且可以用很多種方法進行捕捉,使得程式可以捉住錯誤並且對其進行處理,而不是讓整個程式失效。

 

8.2 按自己的方式出錯

異常可以在某些東西出錯的時候自動引發。在學習如何處理異常之前,先看一下自己如何引發異常,以及創建自己的異常類型。

 

8.2.1 raise語句

為了引發異常,可以使用一個類(應該是Exception的子類)或者實例參數調用raise語句。使用類時,程式會自動創建類的一個實例。下麵是一些簡單的例子,使用了內建的Exception的異常類:

>>> raise Exception
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Exception
>>> raise Exception("hyperdrive overload")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Exception: hyperdrive overload

第一個例子raise Exception引發了一個沒有任何有關錯誤信息的普通異常。後一個例子中,則添加了錯誤信息hyperdrive overload。

內建的異常類有很多。Python庫參考手冊的Built-in Exceptions一節中有關與它們的描述。用互動式解釋器也可以分析它們,這些內建異常都可以在exceptions模塊(和內建的命名空間)中找到。可以使用dir函數列出模塊內容,這部分會在第十章中講到:

>>> import exceptions
>>> dir(exceptions)
['ArithmeticError', 'AssertionError', 'AttributeError', ...]

讀者的解釋器中,這個名單可能要長得多——出於對易讀性的考慮,這裡刪除了大部分名字,所有這些異常都可以用在raise語句中:

>>> raise ArithmeticError
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ArithmeticError

表8-1描述了一些最重要的內建異常類:

表8-1 一些內建異常類

 

Exception            所有異常的基類

AttributeError           特性引用或賦值失敗時引發

IOError             試圖打開不存在文件(包括其他情況)時引發

IndexError                                         在使用序列中不存在的索引時引發

KeyError              在使用映射中不存在的鍵時引發

NameError             在找不到名字(變數)時引發

SyntaxError            在代碼為錯誤形式時引發

TypeError             在內建操作或者函數應用於錯誤類型的對象時引發

ValueError            在內建操作或者函數應用於正確類型的對象,但是該對象使用不合適的值時引發

ZeroDivisionError         在除法或者模除操作的第二個參數為0時引發

 

8.2.2 自定義異常類

儘管內建的異常類已經包括了大部分的情況,而且對於很多要求都已經足夠了,但是有些時候還是需要創建自己的異常類。比如在超光速推進裝置過載(hyperdrive overload)的例子中,如果能有個具體的HyperDriveError類來表示超光速推進裝置的錯誤狀況是不是更自然一些?錯誤信息是足夠了,但是會在8.3節中看到,可以根據異常所在的類,選擇性地處理當前類型的異常。所以如果想要使用特殊的錯誤處理代碼處理超光速推進裝置的錯誤,那麼就需要一個獨立於exceptions模塊的異常類。

那麼如何創建自己的異常類呢?就像其他類一樣,只是要確保從Exception類繼承(不管是間接還是直接,也就是說繼承其他的內建異常類也是可以的)。那麼編寫一個自定義異常類基本上就像下麵這樣:

class SomeCustomException(Exception): pass

還不能做太多事,對吧?(如果你願意,也可以向你的異常類中增加方法)

 

8.3 捕捉異常

前面曾經提到過,關於異常的最有意思的地方就是可以處理它們(通常叫做誘捕或者捕捉異常)。這個功能可以使用try/except語句來實現。假設創建了一個讓用戶輸入兩個數,然後進行相除的程式,像下麵這樣:

x = input("Enter the first number: ")
y = input("Enter the second number: ")
print x / y

程式工作正常,假如用戶輸入0作為第二個數

Enter the first number: 10
Enter the second number: 0
Traceback (most recent call last):
  File "/home/marlowes/MyPython/My_Exception.py", line 6, in <module>
    print x / y
ZeroDivisionError: integer division or modulo by zero

為了捕捉異常並且做出一些錯誤處理(本例中只是輸出一些更友好的錯誤信息),可以這樣重寫程式:

try:
    x = input("Enter the first number: ")
    y = input("Enter the second number: ")
    print x / y
except ZeroDivisionError:
    print "The second number can't be zero!"

看起來用if語句檢查y值會更簡單一些,本例中這樣做的確很好。但是如果需要給程式加入更多除法,那麼就得給每個除法加個if語句。而且使用try/except的話只需要一個錯誤處理器。

註:如果沒有捕捉異常,它就會被“傳播”到調用的函數中。如果在那裡依然沒有捕獲,這些異常就會“浮”到程式的最頂層,也就是說你可以捕捉到在其他人的函數中所引發的異常。有關這方面的更多信息,請參見8.10節。

看,沒參數

如果捕捉到了異常,但是又想重新引發它(也就是說要傳遞異常,不進行處理),那麼可以調用不帶參數的raise(還能在捕捉到異常時顯式地提供具體異常,在8.6節會對此進行解釋)。

舉個例子吧,看看這麼做多麼有用:考慮一下一個能“屏蔽”ZeroDivisionError(除零錯誤)的計算器類。如果這個行為被激活,那麼計算器就列印錯誤信息,而不是讓異常傳播。如果在與用戶交互的過程中使用,那麼這就有用了,但是如果是在程式內部使用,引發異常會更好些。因此“屏蔽”機制就可以關掉了,下麵是這樣一個類的代碼:

class MuffledCalculator():
    
    muffled = False
    
    def calc(self, expr):
        try:
            return eval(expr)
        except ZeroDivisionError:
            if self.muffled:
                print "Division by zero is illegal"
            else:
                raise

註:如果除零行為發生而屏蔽機制被打開,那麼calc方法會(隱式地)返回None。換句話說,如果打開了屏蔽機制,那麼就不應該依賴返回值。

下麵是這個類的用法示例,分別打開和關閉了屏蔽:

>>> calculator = MuffledCalculator()
>>> calculator.calc("10 / 2")
5
>>> calculator.calc("10 / 0")
Traceback (most recent call last):
  File "/home/marlowes/MyPython/My_Exception.py", line 28, in <module>
    calculator.calc("10 / 0")
  File "/home/marlowes/MyPython/My_Exception.py", line 19, in calc
    return eval(expr)
  File "<string>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero
>>> calculator.muffled = True
>>> calculator.calc("10 / 0")
Division by zero is illegal

當計算器沒有打開屏蔽機制時,ZeroDivisionError被捕捉但已傳遞了。

 

8.4 不止一個except子句

如果運行上一節的程式並且在提示符後面輸入非數字類型的值,就會產生另一個異常:

Enter the first number: 10
Enter the second number: "Hello, world!"
Traceback (most recent call last):
  File "/home/marlowes/MyPython/My_Exception.py", line 8, in <module>
    print x / y
TypeError: unsupported operand type(s) for /: 'int' and 'str'

因為except子句只尋找ZeroDivisionError異常,這次的錯誤就溜過了檢查並導致程式終止。為了捕捉這個異常,可以直接在同一個try/except語句後面加上另一個except子句:

try:
    x = input("Enter the first number: ")
    y = input("Enter the second number: ")
    print x / y
except ZeroDivisionError:
    print "The second number can't be zero!"
except TypeError:
    print "That wasn't a number, was it?"

這次用if語句實現可就複雜了。怎麼檢查一個值是否能被用在除法中?方法很多,但是目前最好的方式是直接將值用來除一下看看是否奏效。

還應該註意到,異常處理並不會搞亂原來的代碼,而增加一大堆if語句檢查可能的錯誤情況會讓代碼相當難讀。

 

8.5 用一個塊捕捉兩個異常

如果需要用一個塊捕捉多個類型異常,那麼可以將它們作為元組列出,像下麵這樣:

try:
    x = input("Enter the first number: ")
    y = input("Enter the second number: ")
    print x / y
except (ZeroDivisionError, TypeError, NameError):
    print "Your numbers were bogus..."

上面的代碼中,如果用戶輸入字元串或者其他類型的值,而不是數字,或者第2個數為0,都會列印同樣的錯誤信息。當然,只列印一個錯誤信息並沒有什麼幫助。另外一個方法就是繼續要求輸入數字直到可以進行除法運算為止。8.8節中會介紹如何實現這一功能。

註意,except子句中異常對象外面的圓括弧很重要。忽略它們是一種常見的錯誤,那樣你會得不到想要的結果。關於這方面的解釋,請參見8.6節。

 

8.6 捕捉對象

如果希望在except子句中訪問異常對象本身,可以使用兩個參數(註意,就算要捕捉到多個異常,也只需向except子句提供一個參數——一個元組)。比如,如果想讓程式繼續運行,但是又因為某種原因想記錄下錯誤(比如只是列印給用戶看),這個功能就很有用。下麵的示常式序會列印異常(如果發生的話),但是程式會繼續運行:

try:
    x = input("Enter the first number: ")
    y = input("Enter the second number: ")
    print x / y
except (ZeroDivisionError, TypeError), e:
    print e

(在這個小程式中,except子句再次捕捉了兩種異常,但是因為你可以顯式地捕捉對象本身,所以異常可以列印出來,用戶就能看到發生什麼(8.8節會介紹一個更有用的方法)。——譯者註)

註:在Python3.0中,except子句會被寫作except (ZeroDivisionError, TypeError) as e。

 

8.7 真正的捕捉

就算程式能處理好幾種類型的異常,但是有些異常還會從眼皮地下溜走。比如還用那個除法程式來舉例,在提示符下麵直接按回車,不輸入任何東西,會的到一個類似下麵這樣的錯誤信息(棧跟蹤):

Traceback (most recent call last):
  File "/home/marlowes/MyPython/My_Exception.py", line 33, in <module>
    x = input("Enter the first number: ")
  File "<string>", line 0
    
    ^
SyntaxError: unexpected EOF while parsing

這個異常逃過了try/except語句的檢查,這很正常。程式員無法預測會發生什麼,也不能對其進行準備。在這些情況下,與其用那些並非捕捉這些異常的try/except語句隱藏異常,還不如讓程式立刻崩潰。

但是如果真的想用一段代碼捕捉所有異常,那麼可以在except子句中忽略所有的異常類:

try:
    x = input("Enter the first number: ")
    y = input("Enter the second number: ")
    print x / y
except:
    print "Something wrong happened..."

現在可以做任何事情了:

Enter the first number: "This" is *completely* illegal 123
Something wrong happened...

警告:像這樣捕捉所有異常是危險的,因為它會隱藏所有程式員未想到並且未做好準備處理的錯誤。它同樣會捕捉用戶終止執行的Ctrl+C企圖,以及用sys.exit函數終止程式的企圖,等等。這時使用except Exception, e會更好些,或者對異常對象e進行一些檢查。

 

8.8 萬事大吉

有些情況中,沒有壞事發生時執行一段代碼是很有用的;可以像對條件和迴圈語句那樣,給try/except語句加個else子句:

try:
    print "A simple task"
except:
    print "What? Something went wrong?"
else:
    print "Ah... It went as planned."

運行之後會的到如下輸出:

A simple task
Ah... It went as planned.

使用else子句可以實現在8.5節中提到的迴圈:

while True:
    try:
        x = input("Enter the first number: ")
        y = input("Enter the second number: ")
        value = x / y
        print "x / y is", value
    except:
        print "Invalid input. Please try again."
    else:
        break

這裡的迴圈只有在沒有異常引發的情況下才會退出(由else子句中的break語句退出)。換句話說,只要有錯誤發生,程式會不斷要求重新輸入。下麵是一個例子的運行情況:

Enter the first number: 1
Enter the second number: 0
Invalid input. Please try again.
Enter the first number: "foo"
Enter the second number: "bar"
Invalid input. Please try again.
Enter the first number: baz
Invalid input. Please try again.
Enter the first number: 10
Enter the second number: 2
x / y is 5

之前提到過,可以使用空的except子句來捕捉所有Exception類的異常(也會捕捉其所有子類的異常)。百分之百捕捉到所有的異常是不可能的,因為try/except語句中的代碼可能會出現問題,比如使用舊風格的字元串異常或者自定義的異常類不是Exception類的子類。不過如果需要使用except Exception的話,可以使用8.6節中的技巧在除法程式中列印更加有用的錯誤信息:

while True:
    try:
        x = input("Enter the first number: ")
        y = input("Enter the second number: ")
        value = x / y
        print "x / y is", value
    except Exception, e:
        print "Invalid input:", e
        print "Please try again"
    else:
        break

下麵是示例運行:

Enter the first number: 1
Enter the second number: 0
Invalid input: integer division or modulo by zero
Please try again
Enter the first number: "x"
Enter the second number: "y"
Invalid input: unsupported operand type(s) for /: 'str' and 'str'
Please try again
Enter the first number: quuux
Invalid input: name 'quuux' is not defined
Please try again
Enter the first number: 10
Enter the second number: 2
x / y is 5

 

8.9 最後······

最後,是finally子句。它可以用來在可能的異常後進行清理。它和try子句聯合使用:

x = None
try:
    x = 1 / 0
finally:
    print "Cleaning up..."
    del x

上面的代碼中,finally子句肯定會被執行,不管try子句中是否發生異常(在try子句之前初始化x的原因是如果不這樣做,由於ZeroDivisionError的存在,x就永遠不會被賦值。這樣就會導致在finally子句中使用del刪除它的時候產生異常,而且這個異常是無法捕捉的)。

運行這段代碼,在程式崩潰之前,對於變數x的清理就完成了:

Cleaning up...
  File "/home/marlowes/MyPython/My_Exception.py", line 36, in <module>
    x = 1 / 0
ZeroDivisionError: integer division or modulo by zero

註:在Python2.5之前的版本內,finally子句需要獨立使用,而不能作為try語句的except子句使用。如果都要使用的話,那麼需要兩條語句。但在Python2.5及其之後的版本中,可以盡情地組合這些子句。

 

8.10 異常和函數

異常和函數能很自然地一起工作。如果異常在函數內引發而不被處理,它就會傳播至(浮到)函數調用的地方。如果在那裡也沒有處理異常,它就會繼續傳播,一直到達主程式(全局作用域)。如果那裡沒有異常處理程式,程式會帶著棧跟蹤中止。看個例子:

>>> def faulty():
...     raise Exception("Something is wrong")
... 
>>> def ignore_exception():
...     faulty()
... 
>>> def handle_exception():
...     try:
...         faulty()
...     except:
...         print "Exception handled"
... 
>>> ignore_exception()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in ignore_exception
  File "<stdin>", line 2, in faulty
Exception: Something is wrong
>>> handle_exception()
Exception handled

可以看到,faulty中產生的異常通過faulty和ignore_exception傳播,最終導致了棧跟蹤。同樣地,它也傳播到了handle_exception,但在這個函數中被try/except語句處理。

 

8.11 異常之禪

異常處理並不是很複雜。如果知道某段代碼可能會導致某種異常,而又不希望程式以堆棧跟蹤的形式終止,那麼就根據需要添加try/except或者try/finally語句(或者它們的組合)進行處理。

有些時候,條件語句可以實現和異常處理同樣的功能,但是條件語句可能在自然性和可讀性上差些。而從另一方面來看,某些程式中使用if/else實現會比使用try/except要好。讓我們看幾個例子。

假設有一個字典,我們希望列印出存儲在特定的鍵下麵的值。如果該鍵不存在,那麼什麼也不做。代碼可能像下麵這樣寫:

def describePerson(person):
    print "Description of", person["name"]
    print "Age:", person["age"]
    if "occupation" in person:
        print "Occupation:", person["occupation"]

如果給程式提供包含名字Throatwobbler Mangrove和年齡42(沒有職業)的字典的函數,會得到如下輸出:

Description of Throatwobbler Mangrove
Age: 42

如果添加了職業camper,會的到如下輸出:

Description of Throatwobbler Mangrove
Age: 42
Occupation: camper

代碼非常直觀,但是效率不高(儘管這裡主要關心的是代碼的簡潔性)。程式會兩次查找"occupation"鍵,其中一次用來檢查鍵是否存在(在條件語句中),另外一次獲得值(列印)。另外一個解決方案如下:

def describePerson(person):
    print "Description of", person["name"]
    print "Age:", person["age"]
    try:
        print "Occupation: " + person["occupation"]
    except KeyError: pass

註:這裡在列印職業時使用加號而不是逗號。否則字元串"Occupation:"在異常引發之前就會被輸出。

這個程式直接假定"occupation"鍵存在。如果它的確存在,那麼就會省事一些。直接取出它的值再列印輸出即可——不用額外檢查它是否真的存在。如果該鍵不存在,則會引發KeyError異常,而被except子句捕捉到。

在查看對象是否存在特定特性時,try/except也很有用。假設想要查看某對象是否有write特性,那麼可以使用如下代碼:

try:
    obj.write
except AttributeError:
    print "The object is not writeable"
else:
    print "The object is writeable"

這裡的try子句僅僅訪問特性而不用對它做別的有用的事情。如果AttributeError異常引發,就證明對象沒有這個特性,反之存在該特性。這是實現第七章中介紹的getattr(7.2.8節)方法的替代方法,至於更喜歡哪種方法,完全是個人喜好。其實在內部實現getattr時也是使用這種方法:它試著訪問特性並且捕捉可能引發的AttributeError異常。

註意,這裡所獲得的效率提高並不多(微乎其微),一般來說(除非程式有性能問題)程式開發人員不用過多擔心這類優化問題。在很多情況下,使用try/except語句比使用if/else會更自然一些(更“Python化”),應該養成儘可能使用try/except語句的習慣。

 

8.12 小結

本章的主題如下。

異常對象:異常情況(比如發生錯誤)可以用異常對象表示。它們可以用幾種方法處理,但是如果忽略的話,程式就會中止。

警告:警告類似於異常,但是(一般來說)僅僅列印錯誤信息。

引發異常:可以使用raise語句引發異常。它接受異常類或者異常實例作為參數。還能提供兩個參數(異常和錯誤信息)。如果在except子句中不使用參數調用raise,它就會“重新引發”該子句捕捉到的異常。

自定義異常類:用繼承Exception類的方法可以創建自己的異常類。

捕捉異常:使用try語句的except子句捕捉異常。如果在except子句中不特別指定異常類,那麼所有的異常都會被捕捉。異常可以放在元組中以實現多個異常的指定。如果給except提供兩個參數,第二個參數就會綁定到異常對象上。同樣,在一個try/except語句中能包含多個except子句,用來分別處理不同的異常。

else子句:除了except子句,可以使用else子句。如果主try塊中沒有引發異常,else子句就會被執行。

finally:如果需要確保某些代碼不管是否有異常引發都要執行(比如清理代碼),那麼這些代碼可以放置在finally(註意,在Python2.5以前,在一個try語句中不能同時使用except和finally子句——但是一個子句可以放置在另一個子句中)子句中。

異常和函數:在函數內引發異常時,它就會被傳播到函數調用的地方(對於方法也是一樣)。

 

8.12.1 本章的新函數

本章涉及的新函數如表8-2所示。

表8-2 本章的新函數

warnings,filterwarnings(action, ...)          用於過濾警告

 

8.12.2 接下來學什麼

本章講異常,內容可能有些意外(雙關語),而下一章的內容真的很不可思議,恩,近乎不可思議。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在如今併發的環境下,對大數據量的查詢採用緩存是最好不過的了,本文使用redis搭建集群 (個人喜歡redis,對memcache不感冒) redis是3.0後增加的集群功能,非常強大 集群中應該至少有三個節點,每個節點有一備份節點。這樣算下來至少需要6台伺服器 考慮到有些朋友的電腦配置不是很高,跑多 ...
  • 運行結果: Hello JAVA Hello JAVA true b Hello JAVA false false false false 當創建String類型的變數並賦值時,會先到常量池中尋找是否存在這個常量的字元串,如果有則將引用(即地址)返回,如果沒有則在常量池中開闢空間並賦值沒這個給定的常 ...
  • from json_response import JsonResponse, json_response as json_resp 使用的語句如上,其實並不是沒有安裝,只是需要升級一下 pip install django-json-response --upgrade ...
  • 註:文章原文為Dr. Charles Severance 的 《Python for Informatics》。文中代碼用3.4版改寫,併在本機測試通過。 12.9 辭彙表 BeautifulSoup: 一個用於分析HTML文檔,並從中抓取數據的Python庫。它彌補了大部分在瀏覽器中被忽略的HTM ...
  • HashSet and HashMap "本文github地址" 總體介紹 之所以把 HashSet 和 HashMap 放在一起講解,是因為二者在Java里有著相同的實現,前者僅僅是對後者做了一層包裝,也就是說 HashSet 裡面有一個 HashMap (適配器模式) 。因此本文將重點分析 Ha ...
  • javap定義 測試類 javap命令參數 javap -version javap -p javap -public javap -protected javap -l javap -package javap -v/-p -v javap -c 文章開頭的demo中最終的結果是什麼呢? 這個地方 ...
  • 一早上起來把50包開了,一張橙卡。。。就問還有誰。。。。。。。。。。。本命年啊,我去買紅內褲還不行麽。。。。 實時更新,老哥的號的30包什麼都沒有。。。。不過中午又開了5包,皇帝,好評啊!!! 五、代碼重用與函數編寫 include警告與require的錯誤; 大量的包含實現,可以改ini文件中的: ...
  • 轉載註明出處,個人博客:http://www.cnblogs.com/wdfwolf3/ Django首要的部署平臺是WSGI,它是Python Web伺服器和應用的標準。使用Apache和mod_wsgi部署Django是一個使Django投入到生產環境中成熟的方式,mod_wsgi是一個Apac ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...