我相信事在人為,人定勝天,現在還是在基礎語法上面打轉,還是會提出一些很低級的很基礎的問題,不要著急,波浪式前進、螺旋式上升的過程吧,雖然現在的確是很絕望吧......
今天要做一個練習:編寫猜數字游戲(隨機生成 1-100 的數字,用戶猜測)
1 python的f-strings格式化字符串字面量,對比一下java里面的printf
其實我不是很明白,這是我的個人理解:
py里面print(f"",{}),f表示格式化輸出,{}類似于一種占位符,{變量名稱}
ai解答:
是的,你理解得很正確。
在 Python 中,f
?開頭的字符串(即 f-string)是一種字符串格式化方法,它讓字符串插值變得更簡潔易讀。在?f""
?中,花括號?{}
?用于嵌入表達式或變量,Python 會在運行時將其替換為實際的值。
簡單示例:
python
運行
name = "Alice"
age = 30# 使用 f-string 格式化輸出
print(f"我的名字是 {name},今年 {age} 歲。")
# 輸出:我的名字是 Alice,今年 30 歲。# 可以直接在 {} 中使用表達式
print(f"明年我將是 {age + 1} 歲。")
# 輸出:明年我將是 31 歲。
更靈活的用法:
-
調用函數:
python
運行
def double(x):return x * 2num = 5 print(f"5 的兩倍是 {double(num)}。") # 輸出:5 的兩倍是 10。
-
格式化數字:
python
運行
pi = 3.1415926 print(f"π 約等于 {pi:.2f}。") # 保留兩位小數 # 輸出:π 約等于 3.14。price = 99.9 print(f"價格是 ${price:.2f}。") # 強制保留兩位小數 # 輸出:價格是 $99.90。
-
對齊和填充:
python
運行
?width = 10 print(f"{'左對齊':<{width}}") # 左對齊 print(f"{'右對齊':>{width}}") # 右對齊 print(f"{'居中':^{width}}") # 居中
輸出:
plaintext
左對齊 右對齊居中
-
訪問對象屬性或列表元素:
python
運行
person = {"name": "Bob", "city": "Beijing"} print(f"{person['name']} 住在 {person['city']}。") # 輸出:Bob 住在 Beijing。numbers = [10, 20, 30] print(f"第二個數是 {numbers[1]}。") # 輸出:第二個數是 20。
注意事項:
-
引號沖突:如果字符串中需要使用與?
f""
?相同的引號,需用反斜杠轉義或嵌套不同類型的引號。例如:python
運行
print(f"他說:\"你好!\"") # 使用轉義 print(f'他說:"你好!"') # 嵌套單引號
-
表達式復雜時:雖然可以在?
{}
?中寫復雜表達式,但建議保持簡潔,否則會降低可讀性。例如:python
運行
# 不推薦(太復雜) print(f"結果是 {((x+y)*z)/w:.2f}")# 推薦(先計算,再使用變量) result = ((x+y)*z)/w print(f"結果是 {result:.2f}")
f-string 是 Python 3.6+ 引入的特性,它比傳統的?%
?格式化和?str.format()
?更直觀、高效,是目前最推薦的字符串格式化方式。
在 Python 中,f-strings(格式化字符串字面量)提供了一種簡潔、直觀且高效的方式來嵌入表達式或變量到字符串中。這種設計主要出于以下幾個原因:
1.?語法簡潔性
- Python 的哲學是 "用一種方法,最好只有一種方法來做一件事",但字符串格式化在歷史上有多種方式(
%
?格式化、str.format()
、f-strings)。f-strings 被設計為最直觀的方式。 - 示例對比:
python
運行
# 傳統方式(% 格式化) name = "Alice" print("Hello, %s!" % name)# 現代方式(f-string) print(f"Hello, {name}!")
2.?動態表達式支持
- 在?
{}
?中可以直接使用變量、函數調用、甚至復雜表達式,無需預先計算:python
運行
def get_name():return "Bob"print(f"Hello, {get_name().upper()}!") # 輸出:Hello, BOB!
3.?性能優勢
- f-strings 在運行時直接求值并替換,比?
%
?格式化和?str.format()
?更快。例如:python
運行
# 更快的內聯求值 x = 10 print(f"平方:{x**2}") # 直接計算 x2
4.?可讀性提升
- 變量名直接出現在字符串中,使代碼更易理解:
python
運行
width = 10 height = 5 print(f"面積 = {width} × {height} = {width * height}") # 輸出:面積 = 10 × 5 = 50
5.?與 Java 的?printf
?的對比
Java 的?printf
?是基于 C 語言的格式化風格,使用占位符(如?%s
、%d
),而 Python 的 f-strings 更靈活:
特性 | Python f-strings | Java printf |
---|---|---|
語法 | f"文本 {表達式}" | "文本 %s %d" % (變量, 值) |
動態表達式 | 支持直接嵌入函數調用、計算等 | 需要預先計算所有值 |
變量可見性 | 直接使用變量名,如?{name} | 依賴位置參數(%1$s 、%2$d ) |
類型安全 | 自動處理類型轉換 | 需要顯式指定類型(%s 、%d ) |
性能 | 運行時直接替換,效率高 | 依賴字符串解析,相對較慢 |
6.?Python 的設計哲學
Python 強調代碼的可讀性和簡潔性,f-strings 符合這一哲學:
- 更少的樣板代碼:不需要像 Java 那樣頻繁使用?
+
?拼接字符串。 - 更 Pythonic:與列表推導式、生成器表達式等特性一致,用簡潔的語法解決常見需求。
7.?演進歷史
Python 早期只有?%
?格式化(類似 C 語言),后來引入?str.format()
?提升靈活性,但 f-strings(Python 3.6+)進一步簡化了語法。例如:
python
運行
# 舊方式(Python 2/3 早期)
print("姓名:{},年齡:{}".format("Charlie", 25))# 新方式(f-string)
print(f"姓名:{'Charlie'},年齡:{25}")
總結
Python 的 f-strings 是為了提供一種更直觀、高效且符合語言哲學的字符串格式化方式,相比 Java 的?printf
,它更靈活、更具表達力,且與 Python 的動態特性結合得更好。
2 異常處理和文件讀取練習
寫到這個地方寫不下去了,不知道怎么統計單詞
# 下面是一個關于 Python 異常處理的練習題,你可以嘗試完成它。
# 練習題:文件內容分析器
# 要求:
# 編寫一個 Python 程序,實現以下功能:
# 提示用戶輸入一個文件路徑。
# 嘗試讀取該文件的內容。
# 統計文件中的行數、單詞數(以空格分隔)和字符數(包括空格和換行符)。
# 打印統計結果。
# 需要處理的異常情況:
# 文件不存在。
# 文件沒有讀取權限。
# 文件為空(此時輸出統計結果為全零)。
# 用戶輸入無效路徑(例如包含非法字符)。
# 示例輸出:
# plaintext
# 請輸入文件路徑: test.txt
# 文件統計結果:
# - 行數: 3
# - 單詞數: 12
# - 字符數: 56
#
# 異常處理示例:
# plaintext
# 請輸入文件路徑: /nonexistent/file.txt
# 錯誤:文件不存在!
#
# plaintext
# 請輸入文件路徑: /etc/shadow
# 錯誤:沒有讀取該文件的權限!
#
# 你可以將答案寫在下面,我會為你檢查。location = input("請輸入文件路徑:")
try:f = open(location + ".txt", "w", encoding="utf-8")
except FileNotFoundError:print("找不到文件")
except FileExistsError:print("文件不存在")
except PermissionError:print("沒有讀取權限")
else:f.readlines()f.close()
ai給的修改后的正確代碼:
# 獲取用戶輸入的文件路徑
location = input("請輸入文件路徑:")try:# 嘗試以只讀模式打開文件with open(location, "r", encoding="utf-8") as file:# 讀取全部內容content = file.read()# 統計行數lines = content.count('\n') + 1 if content else 0# 統計單詞數(以空格分隔)words = len(content.split()) if content else 0# 統計字符數(包括空格和換行符)characters = len(content)# 打印統計結果print("文件統計結果:")print(f"- 行數: {lines}")print(f"- 單詞數: {words}")print(f"- 字符數: {characters}")except FileNotFoundError:print("錯誤:文件不存在!")
except PermissionError:print("錯誤:沒有讀取該文件的權限!")
except IsADirectoryError:print("錯誤:輸入的是一個目錄,請提供有效的文件路徑!")
except UnicodeDecodeError:print("錯誤:文件編碼不是UTF-8,請提供UTF-8編碼的文件!")
except Exception as e:print(f"錯誤:發生未知錯誤 - {e}")
?原先代碼存在的問題:
- 使用了寫入模式打開文件:
open(location + ".txt", "w")
?這會創建 / 覆蓋文件 - 異常處理邏輯有些混亂:
FileExistsError
?不應該用于檢查文件是否存在 - 沒有實現統計行數、單詞數和字符數的邏輯
3 python中的with語句
with
?語句是 Python 中用于簡化資源管理的語法結構,它通過上下文管理器(Context Manager)自動處理資源的獲取和釋放,確保無論代碼塊是否正常執行完畢,資源都能被正確清理。這種模式不僅讓代碼更簡潔,還能避免因疏忽導致的資源泄漏(如文件未關閉、網絡連接未釋放等)。
基本語法
python
運行
with expression [as variable]:# 代碼塊
expression
:返回一個上下文管理器對象(如?open()
?返回文件對象)。as variable
(可選):將上下文管理器的返回值賦值給變量。
核心機制:上下文管理器
with
?語句依賴上下文管理器,它是實現了?__enter__()
?和?__exit__()
?方法的對象:
__enter__()
:在進入?with
?代碼塊前調用,返回資源對象(如文件句柄)。__exit__()
:在代碼塊結束后(無論是否異常)自動調用,負責清理資源(如關閉文件)。
典型應用場景
1. 文件操作(最常見)
python
運行
with open('data.txt', 'r') as file:content = file.read()# 文件在代碼塊結束后自動關閉
- 等價于傳統寫法:
python
運行
file = open('data.txt', 'r') try:content = file.read() finally:file.close() # 無論是否異常,finally 確保文件關閉
2. 數據庫連接
python
運行
with sqlite3.connect('example.db') as conn:cursor = conn.cursor()cursor.execute('SELECT * FROM users')# conn.commit() 或 conn.rollback() 自動調用
- 數據庫連接在?
with
?結束時自動提交或回滾事務,并關閉連接。
3. 線程鎖
python
運行
lock = threading.Lock()
with lock: # 等價于 lock.acquire() + lock.release()# 線程安全的代碼...
4. 臨時修改環境
python
運行
with tempfile.TemporaryDirectory() as tmpdir:# 在臨時目錄中操作文件# 代碼塊結束后,tmpdir 自動刪除
自定義上下文管理器
如果你需要管理自定義資源,可以通過以下兩種方式創建上下文管理器:
方式 1:類實現
python
運行
class MyResource:def __enter__(self):print("獲取資源")return self # 返回資源對象def __exit__(self, exc_type, exc_val, exc_tb):print("釋放資源")# 異常處理邏輯(如果需要)with MyResource() as resource:# 使用 resourcepass # 輸出:獲取資源 → 釋放資源
方式 2:裝飾器 + 生成器(更簡潔)
python
運行
from contextlib import contextmanager@contextmanager
def my_context_manager():# __enter__ 邏輯resource = "初始化資源"try:yield resource # 返回資源給 with 語句finally:# __exit__ 邏輯print("清理資源")with my_context_manager() as res:print(res) # 輸出:初始化資源
with
?語句的優勢
- 自動資源管理:避免手動調用?
close()
、release()
?等方法。 - 異常安全:即使代碼塊中拋出異常,資源也會被正確釋放。
- 代碼簡潔:減少樣板代碼(如?
try-finally
)。
常見內置上下文管理器
open()
:文件操作threading.Lock()
:線程鎖tempfile.TemporaryFile()
:臨時文件contextlib.suppress()
:抑制特定異常unittest.mock.patch()
:測試中的臨時補丁
注意事項
-
變量作用域:
with
?中定義的變量在代碼塊外仍可用,但資源可能已關閉。python
運行
with open('test.txt') as f:data = f.read() print(data) # 正常訪問,但 f.closed 為 True
-
嵌套?
with
?語句:支持多層資源管理。python
運行
with open('input.txt') as infile, open('output.txt', 'w') as outfile:outfile.write(infile.read())
-
異常處理:
__exit__()
?方法可捕獲并處理異常(通過?exc_type
?參數判斷)。
總結
with
?語句通過上下文管理器實現了資源的自動獲取和釋放,是 Python 中優雅且安全的編程實踐。常見于文件操作、數據庫連接、網絡會話等需要顯式關閉資源的場景,能有效避免資源泄漏,提升代碼可靠性。
4?python的三元表達式
Python 的三元表達式(Ternary Expression),也稱為條件表達式(Conditional Expression),是一種簡潔的語法結構,允許你在一行代碼中根據條件選擇不同的值。
它提供了一種比傳統的if-else
語句更緊湊的方式來表達條件邏輯。
基本語法
python
運行
value_if_true if condition else value_if_false
執行邏輯:
- 如果
condition
為True
,表達式返回value_if_true
。 - 如果
condition
為False
,表達式返回value_if_false
。
簡單示例
示例 1:比較兩個數的大小
python
運行
a = 10
b = 20max_value = a if a > b else b
print(max_value) # 輸出:20
示例 2:判斷奇偶性
python
運行
num = 7
result = "偶數" if num % 2 == 0 else "奇數"
print(result) # 輸出:奇數
與傳統if-else
的對比
傳統寫法:
python
運行
if num % 2 == 0:result = "偶數"
else:result = "奇數"
三元表達式:
python
運行
result = "偶數" if num % 2 == 0 else "奇數"
優勢:
- 代碼更簡潔,減少行數。
- 適合在賦值語句中直接使用,無需額外的代碼塊。
進階用法
1. 嵌套三元表達式
可以在三元表達式中嵌套另一個三元表達式,但過度嵌套會降低代碼可讀性。
python
運行
x = 15
result = "大正數" if x > 10 else ("小正數" if x > 0 else "非正數")
print(result) # 輸出:大正數
2. 與函數調用結合
python
運行
def get_name():return "Alice"def get_default():return "Guest"name = get_name() if user_logged_in else get_default()
3. 在列表推導式中使用
python
運行
numbers = [1, -2, 3, -4, 5]
abs_values = [num if num >= 0 else -num for num in numbers]
print(abs_values) # 輸出:[1, 2, 3, 4, 5]
注意事項
-
避免復雜條件:如果條件或表達式過于復雜,建議使用傳統的
if-else
語句,以保持代碼可讀性。 -
空值處理:
python
運行
# 如果 x 為 None,使用默認值 0 value = x if x is not None else 0
-
執行順序:三元表達式是從左到右求值的,先判斷
condition
,再根據結果選擇返回值。
歷史背景
Python 直到2.5 版本才引入三元表達式語法。在此之前,常見的替代方案是:
python
運行
# Python 2.4及之前的寫法
value = (value_if_false, value_if_true)[condition]
這種寫法利用了布爾值可以作為列表索引(True
為 1,False
為 0)的特性,但可讀性較差。
總結
三元表達式是 Python 中一種簡潔的條件賦值語法,適用于簡單的條件判斷場景。它能讓代碼更緊湊,但應避免過度使用導致代碼難以理解。當邏輯較為復雜時,建議優先使用傳統的if-else
語句。
lines = content.count('\n') + 1 if content else 0
#怎么理解這個三元表達式
這行代碼是用于統計文本內容中的行數,它巧妙地處理了空文件和非空文件兩種情況。我來詳細解釋一下:
代碼拆解
python
運行
lines = content.count('\n') + 1 if content else 0
這行代碼使用了 Python 的三元表達式(也稱為條件表達式),等價于:
python
運行
if content: # 如果 content 不為空字符串lines = content.count('\n') + 1
else: # 如果 content 是空字符串(文件為空)lines = 0
核心邏輯分析
1.?content.count('\n')
count()
?是字符串方法,用于統計子字符串在原字符串中出現的次數。content.count('\n')
?計算文本中換行符的數量。
2. 為什么要?+ 1
?
- 換行符的位置:在文本中,換行符?
\n
?位于每行的末尾(除了最后一行)。
例如,一個包含 3 行的文件:plaintext
Line 1\n Line 2\n Line 3
這里有?2 個換行符,但實際上有?3 行。因此,行數 = 換行符數量 + 1。
3. 特殊情況:空文件
- 如果文件為空,
content
?是空字符串(''
)。''.count('\n')
?返回?0
,但空文件的行數應為?0
,而不是?0 + 1 = 1
。- 因此,當?
content
?為空時,直接返回?0
。
示例驗證
例 1:3 行文本
python
運行
content = "Line 1\nLine 2\nLine 3"
print(content.count('\n')) # 輸出 2
print(content.count('\n') + 1) # 輸出 3(正確的行數)
例 2:1 行文本(無換行符)
python
運行
content = "Only one line"
print(content.count('\n')) # 輸出 0
print(content.count('\n') + 1) # 輸出 1(正確的行數)
例 3:空文件
python
運行
content = ""
print(content.count('\n')) # 輸出 0
print(0 if not content else content.count('\n') + 1) # 輸出 0(正確的行數)
為什么需要這個邏輯?
在處理文件時,行數的統計不能簡單地依賴換行符數量:
- 最后一行無換行符:大多數文本編輯器會在文件末尾自動添加換行符,但有些不會。因此,最后一行可能沒有?
\n
,需要通過?+ 1
?補償。 - 空文件:空文件不包含任何字符,包括換行符,因此行數應為?
0
。
總結
這行代碼通過以下步驟準確統計行數:
- 計算換行符數量。
- 對于非空文件,行數 = 換行符數量 + 1。
- 對于空文件,直接返回?
0
。
這種方法既簡潔又健壯,能夠處理各種邊界情況,是統計文本行數的經典實現。
5 猜數游戲
我寫的真的是shit吧!!!!!我真的服了。。。
import randomprint("我們來玩猜數吧!")
ans = random.randint(1,1000)#生成隨機數
num = int(input("請輸入1-1000中的一個數"))
while True:if num > ans:print("猜大了")continueelif num < ans:print("猜小了")continueelse:print("答對了")break
修改第一版:
import randomprint("我們來玩猜數吧!")
ans = random.randint(1, 1000) # 生成隨機數
num = int(input("請輸入1-1000中的一個數:"))while True:if num > ans:print("猜大了")num = int(input("請繼續輸入1-1000中的一個數:"))elif num < ans:print("猜小了")num = int(input("請繼續輸入1-1000中的一個數:"))else:print("答對了")break # 正確結束循環的語句
修改第二版,降低重復率:
import randomprint("我們來玩猜數吧!")
ans = random.randint(1, 1000) # 生成隨機數while True:num = int(input("請輸入1-1000中的一個數:"))if num > ans:print("猜大了")elif num < ans:print("猜小了")else:print("答對了")break # 正確結束循環的語句
這個題目太簡單了基礎的不行,但是我第一次寫還是漏洞百出。。。好了好了,就這樣。以后可以做一點擴展。
核心就是 “生成隨機數→用戶輸入→比較判斷→循環反饋” 的流程。不過,如果想讓這個小游戲更有趣或更有挑戰性,可以從幾個方向擴展,讓它稍微復雜一點,比如:
1. 增加猜測次數限制
比如限定最多猜 10 次,超時則失敗,增加緊張感:
python
運行
import randomprint("猜數游戲(最多10次機會)")
ans = random.randint(1, 100)
max_attempts = 10
attempts = 0while attempts < max_attempts:num = int(input(f"請輸入1-100中的數(還剩{max_attempts - attempts}次):"))attempts += 1if num > ans:print("猜大了")elif num < ans:print("猜小了")else:print(f"恭喜!用了{attempts}次就猜對了!")break
else: # 循環正常結束(未觸發break)時執行print(f"次數用完啦!正確答案是{ans}")
2. 記錄歷史猜測記錄
顯示用戶之前猜過的數字,幫助分析規律:
python
運行
import randomprint("帶歷史記錄的猜數游戲")
ans = random.randint(1, 50)
history = []while True:num = int(input("請輸入1-50中的數:"))history.append(num)if num > ans:print(f"猜大了,你之前猜過:{history}")elif num < ans:print(f"猜小了,你之前猜過:{history}")else:print(f"猜對了!你的猜測記錄:{history},共猜了{len(history)}次")break
3. 動態調整難度
根據用戶的猜測速度調整數字范圍,比如第一次猜 1-100,猜對后下次擴大到 1-200,增加可玩性:
python
運行
import randommin_num, max_num = 1, 100
rounds = 1print(f"第1輪:猜1-{max_num}之間的數")
ans = random.randint(min_num, max_num)while True:num = int(input(f"請輸入{min_num}-{max_num}中的數:"))if num > ans:print("猜大了")elif num < ans:print("猜小了")else:rounds += 1min_num, max_num = 1, max_num + 100 # 每輪范圍+100print(f"恭喜過關!進入第{rounds}輪,范圍擴大到1-{max_num}")ans = random.randint(min_num, max_num)
這些擴展雖然不復雜,但能讓簡單的邏輯變得更豐富,也能練習循環、條件判斷、列表等基礎語法的綜合運用。如果想更深入,還可以加入難度選擇(簡單 / 中等 / 困難)、計分系統等,甚至用 GUI 庫(如 tkinter)做個可視化界面~