python 语法篇(一)

news/2025/4/2 7:20:31/

目录

  • 1 正则匹配
    • 注意点1
    • 1.1 正则匹配字符串写法
    • 1.2 创建re函数
      • (1)re.search()--搜索第一个匹配项
      • (2)re.match() - 从字符串开头匹配
      • (3)re.findall() - 返回所有匹配项的列表
      • (4)re.finditer() - 返回匹配项的迭代器(适合大文本)
      • (5)re.sub() - 替换匹配内容
      • (6)re.split() - 按正则表达式分割字符串
  • 2 参数数量/类型/默认值指定
  • 3 引用传递和值传递说明
  • 4 排列组合 itertools
  • 5 内置变量/特殊变量
    • 5.1 内置变量
    • 5.2 类相关的特殊属性
  • 6 try-except-else-finally机制
    • 6.1 基础用法
    • 6.2 else-finally
    • 6.3 向上一级抛出错误
  • 7 Threading - 线程(不是进程,创建进程我用的少)
    • 7.1 讲到线程,就不得不谈线程通信
  • 8 路径操作及路径索引 glob

以下资料参考官网及AI

1 正则匹配

re官网
python 的 re 库能够实现正则匹配功能。

注意点1

注意:在Python中使用正则表达式时要优先使用原始字符串。
(也就是说,字符串不会被python语言解析。而只会被re库里的函数解析)

原因如下:
正则表达式本身用 \ 转义特殊字符(如 \d 表示数字),但Python字符串中的 \ 也是转义符。因此,在普通字符串中写正则表达式时,需用 ‌两个反斜杠‌ 表示一个实际的反斜杠(如 \d)。

原始字符串(前缀 r)会忽略Python字符串的转义规则,直接保留所有字符的字面值。例如,r"\d" 会直接传递给正则引擎 \d,而无需额外转义。

以下为错误案例1:

python">import repattern = "\\"  # 普通字符串:实际传递的是单个 \,但正则引擎会报错(转义不完整)
re.findall(pattern, "a\\b")  # 报错:因为正则收到的是单个 \

正确写法:

python">pattern = "\\\\"  # 普通字符串中,四个反斜杠 → Python转义为两个 \,正则引擎收到两个 \
result = re.findall(pattern, "a\\b")  # 成功匹配到 ["\\"]

使用原始字符串的写法:

python">pattern = r"\\"  # 原始字符串直接保留两个 \,正则引擎收到两个 \
result = re.findall(pattern, "a\\b")  # 成功匹配到 ["\\"]

以下为错误案例2:

python">pattern = "\b"   # 普通字符串中,\b 是退格符,正则引擎无法识别为单词边界
re.findall(pattern, "hello world")  # 匹配失败

正确写法:

python">pattern = r"\b"  # 原始字符串直接传递 \b,正则引擎识别为单词边界
result = re.findall(pattern, "hello world")  # 匹配到单词边界的空字符

1.1 正则匹配字符串写法

pattern = r'xxx'

匹配字符含义案例
[ ]一个字符的集合,这写字符可以单独列出,也可以用范围表示(范围用-分隔)[abc],[a-c]
$[akm$] 将会匹配以下任一字符 ‘a’, ‘k’, ‘m’ 或 ‘$’
^^放在字符类的最开头,集合取反来匹配字符类中未列出的字符。(如果放在字符类其他位置,则无意义)[^5] 将匹配除 ‘5’ 之外的任何字符;[5^] 将匹配 ‘5’ 或 ‘^’
\w匹配任何字母数字字符相当于字符类 [a-zA-Z0-9_]
\d匹配任何十进制数字等价于字符类 [0-9]
\S匹配任何非空白字符等价于字符类 [^ \t\n\r\f\v]
\W匹配任何非字母与数字字符等价于字符类 [^a-zA-Z0-9_]
\s匹配任何空白字符[ \t\n\r\f\v]
\D匹配任何非数字字符等价于字符类 [^0-9]
.匹配除换行符之外的任何字符
*定前一个字符可以匹配零次或更多次,而不是只匹配一次ca*t 将匹配 ‘ct’ ( 0 个 ‘a’ )、‘cat’ ( 1 个 ‘a’ )、 ‘caaat’ ( 3 个 ‘a’ )
+匹配一次或更多次ca+t 可以匹配 ‘cat’ ( 1 个 ‘a’ )或 ‘caaat’ ( 3 个 ‘a’),但不能匹配 ‘ct’
{m,n}其中 m 和 n 是十进制整数,该限定符意味着必须至少重复 m 次,最多重复 n 次。a/{1,3}b 可以匹配 ‘a/b’、‘a//b’ 或者 ‘a///b’ ,但不能匹配中间没有斜杆的 ‘ab’,或者四个斜杆的 ‘ab’
()它们将包含在其中的表达式组合在一起,你可以使用重复限定符重复组的内容(ab)*,匹配ab 0到多次

1.2 创建re函数

(1)re.search()–搜索第一个匹配项

python">import retext = "Python is fun, Python is powerful"
pattern = r"Python"
match = re.search(pattern, text)
if match:print("Found:", match.group())  # 输出: Found: Python

(2)re.match() - 从字符串开头匹配

python">import re
text = "Python is awesome"
pattern = r"Python"
match = re.match(pattern, text)
if match:print("Match found:", match.group())  # 输出: Match found: Python# 若 text = "I love Python",则 match 为 None

(3)re.findall() - 返回所有匹配项的列表

python">import re
text = "apple 12, banana 3, cherry 45"
numbers = re.findall(r'\d+', text)
print(numbers)  # 输出: ['12', '3', '45']

(4)re.finditer() - 返回匹配项的迭代器(适合大文本)

python">import re
text = "a=1, b=2, c=3"
matches = re.finditer(r'\w+=\d+', text)
for match in matches:print(match.group())  # 输出: a=1, b=2, c=3

(5)re.sub() - 替换匹配内容

python">import re
text = "2023-10-05"
new_text = re.sub(r'-', '/', text)
print(new_text)  # 输出: 2023/10/05# 使用函数处理替换内容
def double_number(match):return str(int(match.group()) * 2)text = "Score: 5, Count: 3"
result = re.sub(r'\d+', double_number, text)
print(result)  # 输出: Score: 10, Count: 6

(6)re.split() - 按正则表达式分割字符串

python">import re
text = "one,two;three four"
parts = re.split(r'[,; ]+', text)
print(parts)  # 输出: ['one', 'two', 'three', 'four']

2 参数数量/类型/默认值指定

直接通过一个综合案例说明:

python">from typing import Union, Optional, Anydef generate_user_card(username: str,  # 必选参数(无默认值)age: int = 18,  # 必选但有默认值(可省略)*hobbies: str,  # 不定数量的位置参数(爱好)country: Optional[str] = "未知",  # 可选关键字参数(允许None)**extra_info: Union[str, int, float]  # 不定数量的关键字参数(扩展信息)
) -> dict[str, Any]:"""生成用户信息卡,支持灵活参数输入"""user_data = {"username": username,"age": age,"hobbies": hobbies if hobbies else ("无",),"country": country,"extra": extra_info}return user_data

(1)基础调用:

python">
result1 = generate_user_card("Alice")
print(result1)
# {'username': 'Alice', 'age': 18, 'hobbies': ('无',), 'country': '未知', 'extra': {}}

(2)额外信息传入:

python">result3 = generate_user_card("Charlie",age=30,country=None,  # 明确设置为Noneemail="charlie@example.com",score=95.5
)
print(result3["extra"])
# {'email': 'charlie@example.com', 'score': 95.5}

3 引用传递和值传递说明

在 Python 中,变量传递的本质是 对象引用的传递‌,所有操作都是基于对象的引用(可以理解为“指针”)。

  • 不可变对象‌(int, float, str, tuple 等)
    传递的是对象的引用,但修改时会创建新对象,原始对象不受影响(类似“值传递”的效果)

  • ‌可变对象‌(list, dict, set, 自定义类实例等)
    传递的是对象的引用,修改内容时会影响原始对象(类似“引用传递”的效果)

案例说明1

python">def modify_data(num: int, lst: list, obj: object):num += 10      # 不可变对象:创建新对象lst.append(4)  # 可变对象:修改原对象obj.value = 5  # 可变对象:修改原对象# 初始化数据
original_num = 5
original_list = [1, 2, 3]
class MyClass:def __init__(self):self.value = 0
original_obj = MyClass()# 调用函数
modify_data(original_num, original_list, original_obj)print(original_num)    # 输出 5(未改变)
print(original_list)   # 输出 [1, 2, 3, 4](已改变)
print(original_obj.value)  # 输出 5(已改变)

案例2

python">class DataHolder:def __init__(self, data):self.data = data  # data 是可变/不可变对象的引用# 不可变对象操作
holder1 = DataHolder(10)
temp = holder1.data
temp += 5  # 创建新对象,不影响原数据
print(holder1.data)  # 输出 10# 可变对象操作
holder2 = DataHolder([1, 2])
holder2.data.append(3)  # 直接修改原对象
print(holder2.data)     # 输出 [1, 2, 3]

案例3:修改和赋值的本质区别

python">a = [1, 2]
b = a       # 引用传递(指向同一对象)
b.append(3) # 修改原对象
print(a)    # 输出 [1, 2, 3]c = [4, 5]
d = c
d = [6, 7]  # 创建新对象(重新绑定引用)
d.append(10)
print(c)    # 输出 [4, 5](原对象未变)

注意,这里:
lst = lst + (创建新列表,不影响原对象)
lst.append(4)(原地修改,影响原对象)

案例4:默认参数陷阱

python"># 错误示例:默认参数为可变对象
def buggy_func(data=[]):  # 默认列表会持续保留data.append(1)return data# 正确做法
def safe_func(data=None):data = data if data is not None else []data.append(1)return data

错误案例的进一步测试:

python">def func(data=[]):data.append(1)return datafunc()
data = func()
data.append(10)
func()
print(data) # 输出:[1, 1, 10, 1]

4 排列组合 itertools

tee 生成迭代器副本(副本的修改不影响原始数据)
islice 切片
zip_longest 合并多个迭代器

python">import itertoolsl = [1,2,3,4]
iter1, iter2 = itertools.tee(l, 2)
for x in iter1:
# 
itertools.zip_longest()

5 内置变量/特殊变量

5.1 内置变量

python所有的内置变量:

python">dir(__builtins__)

__name__
如果当前运行的python文件为主文件,则该文件:
__name__ == __main__
如果当前文件被其他文件调用,则该文件:
__name__ == [文件名](不带.py后缀)
参考文章

5.2 类相关的特殊属性

__slots__
限制class可绑定的类的属性。

python">__slots__ = ['属性名1','属性名2','属性名3']

定义的属性仅对当前类实例起作用,对继承的子类是不起作用的。
除非在子类中也定义__slots__,这样,子类实例允许定义的属性就是自身的__slots__加上父类的__slots__。
__init__
类默认构造函数 ,第一个参入参数为self
__lt__
@property装饰器
将方法变成属性调用。
__str__

6 try-except-else-finally机制

6.1 基础用法

python">try:with open('example.txt', 'r') as file:content = file.read()print(content)
except FileNotFoundError:print("文件未找到,请检查文件路径是否正确。")
except PermissionError:print("没有权限读取该文件。")
except Exception as e:# 捕获所有其他类型的异常print(f"发生了一个错误:{e}")

try: 放置可能引发异常的代码。‘
except:如果try中的代码引发异常,会跳转到指定的except 块儿中
as: as e是可选的,允许你将异常实例赋值给变量e,这样就可以在except块中访问到异常信息。
Exception :代表不指定异常类型(反之捕获所有异常)

Python会按照except块的顺序检查,一旦找到匹配的异常类型,就会执行该块中的代码,并且跳过后续的except块。

6.2 else-finally

python">try:# 尝试执行的代码pass
except SomeException:# 处理异常的代码pass
else:# 如果没有异常发生,执行这里的代码pass
finally:# 无论是否发生异常,都执行这里的代码pass

else:如果你想要在没有异常发生时执行一些代码,可以使用else块。它紧跟在所有的except块之后,只有在try块没有引发任何异常时才会执行。
finally:无论是否发生异常,finally块中的代码都会被执行。这通常用于执行一些清理工作,比如关闭文件或释放资源。

6.3 向上一级抛出错误

raise [error]
注意:如果不抛出错误,程序在执行换except后就会退出吗?
当except块内部的操作执行完成后,程序并不会自动退出,除非你在except块中显式地调用了sys.exit()、exit()、os._exit()等函数来终止程序,或者异常没有被捕获并且传播到了程序的顶层(即没有被任何try块捕获)。

7 Threading - 线程(不是进程,创建进程我用的少)

感谢大佬的总结:
https://liaoxuefeng.com/books/python/process-thread/thread/index.html
说实话,之前只用过C thread,没用过python
这里对大佬的 文章列出一些关键点:
(1)启动一个线程就是把一个函数传入并创建Thread实例,然后==调用start()==开始执行。
(2)在Python中,可以使用多线程,但不要指望能有效利用多核

python">

有一些久远的记忆似乎在逐渐复苏

7.1 讲到线程,就不得不谈线程通信

线程的特点就是,共享资源,任务间需要频繁通信。
线程的关键点就是:通信和同步。
要避免的问题:死锁
(1)互斥锁
(2)信号量
(3)条件变量
(4)事件
(5)消息队列
(6)管道

8 路径操作及路径索引 glob

主要利用glob2库

python">from glob2 import globpaths = glob(file_path) # 搜索文件file_path下所有文件,返回list变量# 返回该路径下所有文件

http://www.ppmy.cn/news/1584578.html

相关文章

JAVA实现动态IP黑名单过滤

一些恶意用户(可能是黑客、爬虫、DDoS 攻击者)可能频繁请求服务器资源,导致资源占用过高。因此需要一定的手段实时阻止可疑或恶意的用户,减少攻击风险。 通过 IP 封禁,可以有效拉黑攻击者,防止资源被滥用,保障合法用户…

实战 | 基于 SpringBoot + UniApp 打造国际版打车系统:架构设计与性能优化全解析

✅ 一、引言:国际版打车系统的技术挑战 随着共享出行在全球范围内的快速发展,跨国打车平台如 Uber、Lyft 和 DiDi 等纷纷崛起。开发一套国际版打车系统,不仅要满足国内需求,还需要应对以下技术挑战: 🌍 多…

Altium Designer 24 PCB编辑器[设计]栏找不到[规则]选项而只有[Constraints Manager]选项

Altium Designer 24 PCB编辑器[设计]栏找不到[规则]选项而只有[Constraints Manager]选项 问题描述问题原因解决方法 问题描述 在使用 Altium Designer 24 的PCB编辑器时,发现有的PCB文件的【设计】栏下有【规则】这个选项,有的PCB文件的【设计】栏下没…

蓝桥杯 之 LCA算法

文章目录 习题1483.树节点的第K个祖先拓展:LCA LCA问题,就是最近公共祖先的问题 习题 1483.树节点的第K个祖先 1483.树节点的第K个祖先 普通的做法,当然是一个个往上面搜索,但是这样的话时间复杂度是o(k),那么能不能每次求解的是…

JVM如何判断一个对象可以被回收

在 Java 中,JVM 使用 垃圾回收器 (GC) 来自动管理内存。JVM 判断一个对象是否可以被回收的主要依据是 对象是否可达。具体来说,如果某个对象不再被任何可达的引用所引用,那么这个对象就可以被认为是 垃圾,可以被回收。 判断一个对…

win 远程 ubuntu 服务器 安装图形界面

远程结果:无法使用docker环境使用此方法 注意要写IP和:数字 在 ubuntu 服务器上安装如下: # 安装 sudo apt-get install tightvncserver # 卸载 sudo apt purge tightvncserver sudo apt autoremove#安装缺失的字体包: sudo apt update s…

【自学笔记】PHP语言基础知识点总览-持续更新

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1. PHP 简介2. PHP 环境搭建3. 基本语法变量与常量数据类型运算符 4. 控制结构条件语句循环语句 5. 函数函数定义与调用作用域 6. 数组7. 字符串8. 表单处理9. 会话…

Android HAL 架构详解,底层开发不再难

目录 HAL 基础概念 HAL 是个啥? 为啥要有 HAL? HAL 在系统中的位置 HAL 工作原理 抽象接口:硬件的 “通用语言” 接口的设计思路 核心结构体 版本与兼容性 实例:相机 HAL 接口 模块加载:动态链接的魔法 加载步骤 优化策略 实例:加载音频 HAL 通信机制:HAL…