Python基礎教程(第十三章 資料庫支持)

来源:http://www.cnblogs.com/Marlowes/archive/2016/05/28/5537223.html
-Advertisement-
Play Games

本文內容全部出自《Python基礎教程》第二版,在此分享自己的學習之路。 lxx___歡迎轉載:http://www.cnblogs.com/Marlowes/p/5537223.htmllxx___ Created on Marlowes 使用簡單的純文本文件只能實現有限的功能。沒錯,使用它們可以 ...


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

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

 

                                Created on Marlowes

 

使用簡單的純文本文件只能實現有限的功能。沒錯,使用它們可以做很多事情,但有時需要額外的功能。你可能想要自動序列化,這時可以選擇shelve模塊(見第十章)和pickle(與shelve模塊關係密切)。但有時,可能需要比這更強大的特性。例如,可能想自動地支持數據併發訪問——想讓幾個用戶同時對基於磁碟的數據進行讀寫而不造成任何文件損壞這類的問題。或者希望同時使用多個數據欄位或屬性進行複雜的搜索,而不是只通過shelve做簡單的單鍵查找。解決的方案有很多,但是如果要處理的數據量巨大而同時還希望其他程式員能輕易理解的話,選擇相對來說更標準化的資料庫(database)可能是個好主意。

本章會對Python的Database API進行討論,這是一種連接SQL資料庫的標準化方法;同時也會展示如何用API執行一些基本的SQL命令。最後一節會對其他可選的資料庫技術進行討論。

我不打算把這章寫成關係型資料庫或SQL語言的教程。多數資料庫的文檔(比如PostgreSQL、MySQL,以及本章用到的SQLite資料庫)都應該能提供相關的基礎知識。如果以前沒用過關係型資料庫,也可以訪問http://www.sqlcourse.com,或者乾脆網上搜一下相關主題,或查看由Clare Churcher著的Beginning SQL Queries(Apress,2008年出版)。

當然,本章使用的簡單資料庫(SQLite)並不是唯一的選擇。還有一些流行的商業資料庫(比如Oracle或Microsoft SQL Server)以及很多穩定且被廣泛使用的開源資料庫可供選擇(比如MySQL、PostgreSQL和Firebird)。第二十六章中使用了PostgreSQL,並且介紹了一些MySQL和SQLite的使用指導。關於其他Python包支持的資料庫,請訪問http://www.python.org/topics/database/,或者訪問Vaults of Parnassus的資料庫分類(http://www.vex.net/parnassus)。

關係型(SQL)資料庫不是唯一的資料庫類別。還有不少類似於ZODB(http://wiki.zope.org/ZODB)的對象資料庫、類似Metakit(http://www.equi4.com/metakit/python.html)基於表的精簡資料庫,和類似於BSD DB(http://docs.python.org/lib/module-bsddb.html)的更簡單的鍵-值資料庫。

本章著重介紹低級資料庫的交互,你會發現幾個高級庫可以幫助完成一些複雜的工作(例如,參見http://www.sqlalchemy.org或者http://www.sqlobject.org,或者在網路上搜索Python的對象-關係映射)。

 

13.1 Python資料庫API

支持SQL標準的可用資料庫有很多,其中多數在Python中都有對應的客戶端模塊(有些資料庫甚至有多個模塊)。所有資料庫的大多數基本功能都是相同的,所以寫一個程式來使用其中的某個資料庫是很容易的事情,而且“理論上”該程式也應該能在別的資料庫上運行。在提供相同功能(基本相同)的不同模塊之間進行切換時的問題通常是它們的介面(API)不同。為瞭解決Python中各種資料庫模塊間的相容問題,現在已經通過了一個標準的DB API。目前的API版本(2.0)定義在PEP249中的Python Database API Specification v2.0中。(http://python.org/peps/pep-0249.html)。

本節將對基本概念做一綜述。並且不會提到API的可選部分,因為它們不見得對所有資料庫都適用。可以在PEP中找到更多的信息,或者可以訪問官方的Python維基百科中的資料庫編程指南(http://wiki.python.org/moin/DatabaseProgramming)。如果對API的細節不感興趣,可以跳過本節。

 

13.1.1 全局變數

任何支持2.0版本DB API的資料庫模塊都必須定義3個描述模塊特性的全局變數。這樣做的原因是API設計得很靈活,以支持不同的基礎機制、避免過多包裝,可如果想讓程式同時應用於幾個資料庫,那可是件麻煩事了,因為需要考慮到各種可能出現的狀況。多數情況下,比較現實的做法是檢查這些變數,看看給定的資料庫模塊是否能被程式接受。如果不能,就顯示合適的錯誤信息然後退出,例如拋出一些異常。3種全局變數如表13-1所示。

表13-1 Python DB API的模塊特性

apilevel                      所使用的Python DB API版本

threadsafety                       模塊的線程安全等級

paramstyle                    在SQL查詢中使用的參數風格

API級別(apilevel)是個字元串常量,提供正在使用的API版本號。對DBAPI 2.0版本來說,其值可能是'1.0'也可能是'2.0'。如果這個變數不存在,那麼模塊就不適用於2.0版本,根據API應該假定當前使用的是DB API 1.0。在程式中提供對其他可能值的支持沒有壞處,誰知道呢,說不定什麼時候DBAPI的3.0版本就出來了。

線程安全性等級(threadsafety)是個取值範圍為0~3的整數。0表示線程完全不共用模塊,而3表示模塊是完全線程安全的。1表示線程本身可以共用模塊,但不對連接共用(參見13.1.3節)。如果不使用多個線程(多數情況下可能不會這樣做),那麼完全不用擔心這個變數。

參數風格(paramstyle)表示在執行多次類似查詢的時候,參數是如何被拼接到SQL查詢中的。值'format'表示標準的字元串格式化(使用基本的格式代碼),可以在參數中進行拼接的地方插入%s。而值'pyformat'表示擴展的格式代碼,用於字典拼接中,比如%(foo)。除了Python風格之外,還有第三種接合方式:'qmark'的意思是使用問號,而'numeric'表示使用:1或者:2格式的欄位(數字表示參數的序號),而'named'表示:foobar這樣的欄位,其中foobar為參數名。如果參數風格看起來有些讓人迷惑,別擔心。對於基礎程式來說,不會用到這些參數,如果需要瞭解特定的資料庫介面如何處理參數,在相關的文檔中會進行解釋。

 

13.1.2 異常

為了能儘可能準確地處理錯誤,API中定義了一些異常類。它們被定義在一種層次結構中,所以可能通過一個except塊捕捉多種異常。(當然要是你覺得一切都能運行良好,或者根本不在乎程式因為某些事情出錯這類不太可能發生的時間而突然停止運行,那麼完全可以忽略這些異常)

異常的層次如表13-2所示。在給定的資料庫模塊中異常應該是全局可用的。關於這些異常的深度描述,請參見API規範(也就是前面提到的PEP)。

表13-2 在DB API中使用的異常

異常          超類          描述

StandardError                                 所有異常的泛型基類

Warning               StandardError            在非致命錯誤發生時引發

Error               StandardError             所有錯誤條件的泛型超類

InterfaceError              Error              關於介面而非資料庫的錯誤

DatabaseError              Error              與資料庫相關的錯誤的基類

DataError           DatabaseError        與資料庫相關的問題,比如值超出範圍

OperationalError         DatabaseError               資料庫內部操作錯誤

IntegrityError          DatabaseError        關係完整性受到影響,比如鍵檢查失敗

InternalError            DatabaseError          資料庫內部錯誤,比如非法游標

ProgrammingError          DatabaseError          用戶編程錯誤,比如未找到表

NotSupportedError          DatabaseError          請求不支持的特性,比如回滾

 

13.1.3 連接和游標

為了使用基礎資料庫系統,首先必須連接到它。這個時候需要使用具有恰當名稱的connect函數,該函數有多個參數,而具體使用哪個參數取決於資料庫。API定義了表13-3中的參數作為準則,推薦將這些參數作為關鍵字參數使用,並按表中給定的順序傳遞它們。參數類型都應為字元串。

表13-3 connect函數的常用參數

參數名          描述          是否可選

dsn           數據源名稱,給出該參數表示資料庫依賴          否

user                  用戶名                  是

password                 用戶密碼                 是

host                  主機名                  是

database                  資料庫名                  是

13.2.1節以及第二十六章會介紹使用connect函數的具體的例子。

connect函數返回連接對象。這個對象表示目前和資料庫的會話。連接對象支持的方法如表13-4所示。

13-4 連接對象方法

close()                    關閉連接之後,連接對象和它的游標均不可用

commit()                    如果支持的話就提交掛事務,否則不做任何事

rollback()                           回滾掛起的事務(可能不可用)

cursor()                               返回連接的游標對象

rollback方法可能不可用,因為不是所有的資料庫都支持事務(事務是一系列動作)。如果可用,那麼它就可以“撤銷”所有未提交的事務。

commit方法總是可用的,但是如果資料庫不支持事務,它就沒有任何作用。如果關閉了連接但還有未提交的事務,它們會隱式地回滾——但是只有在資料庫支持回滾的時候才可以。所以如果不想完全依靠隱式回滾,就應該每次在關閉連接前進行提交。如果提交了,那麼就用不著擔心關閉連接的問題,它會在進行垃圾收集時自動關閉。當然如果希望更安全一些,就調用close方法,也不會敲很多次鍵盤。

cursor方法將我們引入另外一個主題:游標對象。通過游標執行SQL查詢並檢查結果。游標比連接支持更多的方法,而且可能在程式中更好用。表13-5給出了游標方法的概述,表13-6則是特性的概述。

表13-5 游標對象方法

callproc(name[, params])                    使用給定的名稱和參數(可選)調用已命名的資料庫程式

close()                                          關閉游標之後,游標不可用

execute(oper[, params])                                執行SQL操作,可能使用參數

executemany(oper, pseq)                            對序列中的每個參數執行SQL操作

fetchone()                            把查詢的結果集中的下一行保存為序列,或者None

fetchmany([size])                          獲取查詢結果集中的多行,預設尺寸為arraysize

fetchall()                                    將所有(剩餘)的行作為序列的序列

nextset()                                      跳至下一個可用的結果集(可選)

setinputsizes(sizes)                                  為參數預先定義記憶體區域

setoutputsize(size[, col])                            為獲取的大數據值設定緩衝區尺寸

表13-6 游標對象特性

description                                    結果列描述的序列,只讀

rowcount                                        結果中的行數,只讀

arraysize                                fetchmany中返回的行數,預設為1

其中一些方法會在下麵詳細介紹,而有些(比如setinputsizes和setoutputsizes)則不會提到。更多細節請查閱PEP。

 

13.1.4 類型

資料庫對插入到具有某種類型的列中的值有不同的要求,是為了能正確地與基礎SQL資料庫進行交互操作,DB API定義了用於特殊類型和值的構造函數以及常量(單例模式)。例如,如果想要在資料庫中增加日期,它應該用相應的資料庫連接模塊的Date構造函數來建立。這樣資料庫連接模塊就可以在幕後執行一些必要的轉換操作。所有模塊都要求實現表13-7中列出的構造函數和特殊值。一些模塊可能不是完全按照要求去做,例如sqlite3模塊(接下來會討論)並不會輸出表13-7中的特殊值(通過ROWIP輸出STRING)。

表13-7 DB API構造函數和特殊值

Date(year, month, day)                            創建保存日期值的對象

Time(hour, minute, second)                          創建保存時間值的對象

Timestamp(y, mon, d, h, min, s)                       創建保存時間戳值的對象

DateFromTicks(ticks)                         創建保存自新紀元以來秒數的對象

TimeFromTicks(ticks)                         創建保存來自秒數的時間值的對象

TimestampTicks(ticks)                         創建保存來自秒數的時間戳的對象

Binay(string)                              創建保存二進位字元串值的對象

STRING                              描述基於字元串的列類型(比如CHAR)

BINARY                               描述二進位列(比如LONG或RAW)

NUMBER                                         描述數字列

DATETIME                                      描述日期/時間列

ROWID                                          描述行ID列

 

13.2 SQLite和PySQLite

之前提到過,可用的SQL資料庫引擎有很多,而且都有相應的Python模塊。多數資料庫引擎都作為伺服器程式運行,連安裝都需要管理員許可權。為了降低練習Python DB API的門檻,這裡選擇了小型的資料庫引擎SQLite,它並不需要作為獨立的伺服器運行,並且不基於集中式資料庫存儲機制,而是直接作用於本地文件。

在最近的Python版本中(從2.5開始),SQLite的優勢在於它的一個包裝(PySQLite)已經被包括在標準庫內。除非是從源碼開始編譯Python,可能資料庫本身也已經包括在內。讀者也可以嘗試13.2.1節介紹的程式段。如果它們可以工作,那麼就不用單獨安裝PySQLite和SQLite了。

註:如果讀者沒有使用PySQLite的標準庫版本,那麼可能還需要修改import語句,請參考相關文檔獲取更多信息。

獲取PySQLite

如果讀者正在使用舊版Python,那麼需要在使用SQLite資料庫前安裝PySQLite,可以從官方網站下載。對於帶有包管理系統的Linux系統,可能直接從包管理器章獲得PYSQLite和SQLite。

針對PYSQLite的Windows二進位版本實際上包含了資料庫引擎(也就是SQLite),所以只要下載對應Python版本的PYSQLite安裝程式,運行就可以了。

如果使用的不是Windows,而操作系統也沒有可以找到PYSQLite和SQLite的包管理器的話,那麼就需要PYSQLite和SQLite的源代碼包,然後自己進行編譯。

如果使用的Python版本較新,那麼應該已經包含PySQLite。接下來需要的可能就是資料庫本身SQLite了(同樣,它可能也包含在內了)。可以從SQLite的網站http://sqlite.org下載源代碼(確保得到的是已經完成自動代碼生成的包),按照README文件中的指導進行編譯即可。在之後編譯PYSQLite時,需要確保編譯過程可以訪問SQLite的庫文件和include文件。如果已經在某些標準位置安裝了SQLite,那麼可能SQLite發佈版的安裝腳本可以自己找到它,在這種情況下只需執行下麵的命令:

python setup.py build
python setup.py install

可以只用後一個命令,讓編譯自動進行。如果出現大量錯誤信息,可能是安裝腳本找不到所需文件。確保你知道庫文件和include文件安裝到了哪裡,將它們顯式地提供給安裝腳本。假設我在/home/mlh/sqlite/current目錄中原地編譯SQLite,那麼頭文件和庫文件應該可以在/home/mlh/sqlite/current/src和/home/mlh/sqlite/current/build/lib中找到。為了讓安裝程式能使用這些路徑,需要編輯安裝腳本setup.py。在這個文件中可以設定變數include_dirs和library_dirs:

include_dirs = ['/home/mlh/sqlite/current/src']
include_dirs = ['/home/mlh/sqlite/current/build/lib']

在重新綁定變數之後,剛纔說過的安裝過程應該可以正常進行了。

 

13.2.1 入門

可以將SQLite作為名為sqlite3的模塊導入(如果使用的是標準庫中的模塊)。之後就可以創建一個到資料庫文件的連接——如果文件不存在就會被創建——通過提供一個文件名(可以是文件的絕對或者相對路徑):

>>> import sqlite3
>>> conn =  sqlite3.connect("somedatabase.db")

之後就能獲得連接的游標:

>>> curs = conn.cursor()

這個游標可以用來執行SQL查詢。完成查詢並且做出某些更改後確保已經進行了提交,這樣才可以將這些修改真正地保存到文件中:

>>> conn.commit()

可以(而且是應該)在每次修改資料庫後都進行提交,而不是僅僅在準備關閉時才提交,準備關閉資料庫時,使用close方法:

>>> conn.close()

 

13.2.2 資料庫應用程式示例

我會建立一個小型營養成分資料庫作為示常式序,這個程式基於USDA的營養數據實驗室提供的數據(http://www.ars.usda.gov/nutrientdata)。在他們的主頁上點擊USDA National Nutrient Database for Standard Reference鏈接,就能看到很多以普通文本形式(ASCII)保存的數據文件,這就是需要的內容。點擊Download鏈接,下載標題"Abbreviated"下方的ASCII鏈接所指向的ASCII格式的zip文件。此時應該得到一個zip文件,其中包含ABBREV.txt文本文件和描述該文件內容的PDF文件。

ABBREV.txt文件中的數據每行都有一個數據記錄,欄位以脫字元(^)進行分割。數字欄位直接包含數字,而文本欄位包括由波浪號(~)括起來的字元串值,下麵是一個示例行,為了簡短起見刪除了一部分:

~01252~^~CHEESE ... ,PAST PROCESS, ... ^~1 slice,  (3/4 oz)~^0

用line.split("^")可以很容易地將這樣一行文字解析為多個欄位。如果欄位以波浪號開始,就能知道它是個字元串,可以用field.strip("~")獲取它的內容。對於其他的(數字)欄位來講可以使用float(field),除非欄位是空的。下麵一節中的程式將演示把ASCII文件中的數據移入SQL資料庫,然後對其進行一些有意思的查詢。

註:這個示常式序有意提供一個簡單的例子。有關相對高級的用於Python的資料庫的例子,參見第二十六章。

1.創建和填充表

為了真正地創建資料庫表並且向其中插入數據,寫個完全獨立的一次性程式可能是最簡單的方案。運行一次後就可以忘了它和原始數據源(ABBREV.txt文件),儘管保留它們也是不錯的主意。

代碼清單13-1中的程式創建了叫做food的表和適當的欄位,並且從ABBREV.txt中讀取數據。之後分解析(行分解為多個欄位,並使用應用函數convert每個欄位進行轉換),然後通過調用curs.execute執行SQL的INSERT語句將文本欄位中的值插入到資料庫中。

註:也可以使用curs.executemany,然後提供一個從數據文件中提取的所有行的列表。這樣做在本例中只會帶來輕微的速度提升,但是如果使用通過網路連接的客戶機/伺服器SQL系統,則會大大地提高速度。

import sqlite3


def convert(value):
    if value.startwith("~"):
        return value.strip("~")
    if not value:
        value = 0
    return float(value)

conn = sqlite3.connect("foo.db")
curs = conn.cursor()

curs.execute("""
CREATE TABLE food (
id        TEXT        PRIMARY KEY,
desc      TEXT,
water     FLOAT,
kcal      FLOAT,
protein   FLOAT,
fat       FLOAT,
ash       FLOAT,
carbs     FLOAT,
fiber     FLOAT,
sugar     FLOAT
)
""")

query = "INSERT INTO food VALUES (?,?,?,?,?,?,?,?,?,?)"

for line in open("ABBREV.txt"):
    fields = line.split("^")
    vals = [convert(f) for f in fields[:field_count]]
    curs.execute(query, vals)

conn.commit()
conn.close()
importdata.py

註:在代碼清單13-1中使用了paramstyle的“問號”版本,也就是會使用問號作為欄位標記。如果使用舊版本的PySQLite,那麼久需要使用%字元。

當運行這個程式(將ABBREV.txt放在同一目錄)時,它會創建一個叫做food.db的新文件,它會包含資料庫中的所有數據。

鼓勵讀者們多嘗試修改這個例子,例如使用其他的輸入、加入print語句,等等。

2.搜索和處理結果

使用資料庫很簡單。再說一次,需要創建連接並且獲得該鏈接的游標。使用execute方法執行SQL查詢,用fetchall等方法提取結果。代碼清單13-2展示了一個將SQL SELECT條件查詢作為命令行參數,之後按記錄格式列印出返回行的小程式。可以用下麵的命令嘗試這個程式:

$ python food_query.py "kcal <= 100 AND fiber >= 10 ORDER BY sugar"

運行的時候可能註意到有個問題。第一行,生橘子皮(raw orange peel)看起來不含任何糖分(糖分值為0)。這是因為在數據文件中這個欄位丟失了。可以改進剛纔的導入腳本檢測條件,然後插入None來代替真實的值來表示丟失的數據。可以使用如下條件:

"kcal <= 100 AND fiber >= 10 AND sugar ORDER BY sugar"

請求在任何返回行中包含實際數據的“糖分”欄位。這方法恰好也適用於當前的資料庫,它會忽略糖分為0的行。

註:使用ID搜索特殊的食品項,比如用08323搜索Cocoa Pebble的時候可能會出現問題。原因在於SQLite以一種相當不標準的方式處理它的值。在其內部所有的值實際上都是字元串,一些轉換和檢查在資料庫和Python API間進行。通常它工作得很順利,但有時候也會出錯,例如下麵這種情況:如果提供值08323,它會被解釋為數字8323,再轉換為字元串"8323"——一個不存在的ID。可能期待這裡拋出異常或者其他什麼錯誤信息,而不是這種毫無用處的非預期行為。但如果小心一些,一開始就用字元串"08323"來表示ID,就可以工作正常了。

import sqlite3
import sys

conn = sqlite3.connect("foo.db")
curs = conn.cursor()

query = "SELECT * FROM food WHERE %s" % sys.argv[1]
print query

curs.execute(query)
names = [f[0] for f in curs.description]

for row in curs.fetchall():
    for pair in zip(names, row):
        print "%s: %s" % pair
    print
food_query.py

 

13.3 小結

本章簡要介紹了創建和關係型資料庫交互的Python程式。這段介紹相當簡短,因為掌握了Python和SQL以後,那麼兩者的結合——Python DB API也就容易掌握了。下麵是本章一些概念。

Python DB API:提供了簡單、標準化的資料庫介面,所有資料庫的包裝模塊都應當遵循這個介面,以易於編寫跨資料庫的程式。

連接:連接對象代表的是和SQL資料庫的通信連接。使用cursor方法可以從它那獲得獨立的游標。通過連接對象還可以提交或者回滾事務。在處理完資料庫之後,連接可以被關閉。

游標:用於執行查詢和檢查結果。結果行可以一個一個地獲得,也可以很多個(或全部)一起獲得。

類型和特殊值:DB API標準制定了一組構造函數和特殊值的名字。構造函數處理日期和時間對象,以及二進位數據對象。特殊值用來表示關係型資料庫的類型,比如STRING、NUMBER和DATETIME。

SQLite:小型的嵌入式SQL資料庫,它的Python包裝叫做PYSQLite。它速度快,易於使用,並且不需要建立單獨的伺服器。

 

13.3.1 本章的新函數

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

表13-8 本章的新函數

connect(...)                    連接資料庫,返回連接對象

 

13.3.2 接下來學什麼

堅持不懈資料庫處理是絕大多數程式(如果不是大多數,那就是大型程式系統)的重要部分。下一章會介紹另外一個大型程式系統都會用到的組件,即網路。

 


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

-Advertisement-
Play Games
更多相關文章
  • 元數據,就是C#中封裝的一些類,無法修改.類成員的特性被稱為元數據中的註釋. 1、什麼是特性 (1)屬性與特性的區別 屬性(Property):屬性是面向對象思想里所說的封裝在類裡面的數據欄位,Get,Set方法。 特性(Attribute): 官方解釋:特性是給指定的某一聲明的一則附加的聲明性信息 ...
  • qpython是一個能讓安卓手機運行和編寫python的APP,到網上下載APK安裝或者在GOOGLE PLAY搜索安裝即可。 安裝之後你可以你手機跑自己的python程式。 qpython有兩個大版本的: qpython對應的是python 2.X qpython3對應的是python 3.X 當 ...
  • Session是一個域 作用範圍:當前會話範圍 生命周期:當程式第一次調用request.getSession()創建出客戶端的session對象,30分鐘沒有操作認為超時,這個可以在web.xml中進行配置 調用session.nvalidate()方法銷毀session 伺服器非正常關閉時銷毀s ...
  • 首先參考 http://jingyan.baidu.com/article/456c463b99f4370a583144a8.html 創建一個項目,照著上面教程到最後一步的時候,系統自動生成entity類,dao類,sessionfactory類和對應的配置文件 在下麵新建一個Test1.java ...
  • 在經過了一段時間的開發後,我對Laravel框架的認識又在逐步的加深,對於這個世界占有量NO.1的框架... 我想說,我已經在逐步的感受到他的恐怖之處... 一.建表--Laravel在資料庫建表上有自己獨立內置的結構,可以完全不用藉助原生SQL語句或者SQLyogEnt、Navicat 這樣的建表 ...
  • 使用Eclipse上傳/下載Git項目 前提: + Eclipse已安裝EGit插件 + 已擁有GitLab/GitHub賬號 SSH方式 配置SSH授權 1. 本地生成授權Key Eclipse,選擇菜單: 2. 遠程托管配置本地授權的Public Key 進入GitLab管理首頁, 在 中輸入剛 ...
  • 表達式是PHP中一個重要的概念,可以把表達式理解為“任何有值的東西”。在本教程中涉及到表達式的語法,我們以“expr”來表示表達式。 下麵就是一個表達式: 在上面的例子中,當$x的值大於$y時,該表達式值為TRUE,否則為FALSE。 我們經常通過判斷一個表達式的值(包括具體數值和布爾值)來確定我們 ...
  • 先看列表是如何創建的: 同樣有兩種創建方式,但一般用第一種。 列表和元祖最大的不同就是列表是可以修改的。 老規矩,使用 help(list) ,真的是 help() 大法好呀。 好,來人,上代碼。 Help on class list in module __builtin__: class lis ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...