言成言成啊 | Kit Chen's Blog

Python基础

发布于2025-03-16 22:05:23,更新于2025-03-18 22:08:35,标签:python  文章会持续修订,转载请注明来源地址:https://meethigher.top/blog

本文示例代码meethigher/python-learn: python基础语法学习demo

一、Python 安装

对于 Python 版本的管理,直接安装可能会导致版本不兼容或管理上的麻烦,特别是当你需要在多个项目中使用不同的 Python 版本时。为此,推荐使用 pyenv 这样的版本管理工具,它可以帮助你管理多个 Python 版本,并且能方便地在不同版本之间切换。

1.1 安装 pyenv

直接访问 pyenv,按照说明,下载安装即可。

1.2 安装 Python 版本

安装好 pyenv 后,你可以通过以下命令查看支持的 Python 版本:

1
pyenv install --list

选择你需要的版本并安装:

1
pyenv install 3.11.9

安装完成后,你可以设置全局默认版本:

1
pyenv global 3.11.9

使用 pyenv versions 可以查看当前安装的所有 Python 版本,并通过 pyenv local <version> 来为某个项目设置局部版本。

1.3 pip 使用

pip(Python Package Installer)是 Python 官方推荐的包管理工具,用于安装、更新、卸载第三方库。

操作命令
检查 pip 版本pip --version
安装最新库pip install 包名
安装指定版本pip install 包名==版本号
查看已安装的库pip list
查看库信息pip show 包名
更新库pip install --upgrade 包名
卸载库pip uninstall 包名
导出依赖库pip freeze > requirements.txt
安装多个库pip install -r requirements.txt
更换国内镜像源pip install -i 镜像地址 包名

二、Python 基础语法

2.1 变量与数据类型

2.1.1 基本数据类型

在Python中,常见的基本数据类型包括:

  1. 整数类型 (int)
  2. 浮点数类型 (float)
  3. 字符串类型 (str)
    • 用于表示文本数据,如 "Hello", 'Python'
  4. 布尔类型 (bool)
    • 用于表示真假值,只有两个取值:TrueFalse
  5. 列表类型 (list)
    • 用于存储多个元素的有序集合,元素可以是不同类型,如 [1, 2.5, "hello"]
  6. 元组类型 (tuple)
    • 与列表相似,但不可变,如 (1, 2.5, "hello")
  7. 集合类型 (set)
    • 用于存储不重复的元素的集合,如 {1, 2, 3}
  8. 字典类型 (dict)
    • 用于存储键值对(key-value pairs)的集合,如 {"name": "Alice", "age": 25}
  9. None 类型
    • 表示“无值”或“空值”,常用于初始化变量或作为函数的返回值,如 None

这些是Python中最常用的基本数据类型。

以下是一些常见的用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
x = 10  # 整数
y = 3.14 # 浮点数
name = "Alice" # 字符串
is_active = True # 布尔值

# 加减乘除
# 加法
print(1 + 1)
# 减法
print(1 - 1)
# 乘法
print(2 * 6)
# 浮点除法
print(18 / 5)
print(17 / 5)
# 地板除法:向下取整。与 Java 的 / 相同
print(18 // 5)
print(17 // 5)

需要注意 Python 中浮点除法 / 和向下取整除法 // 之间的区别

2.1.2 数据类型常用操作

字符串操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 切片
s = "Hello, World!"
print(s[0:5]) # 输出 "Hello"
print(s[7:]) # 输出 "World!"

# 拼接
s1 = "Hello"
s2 = "World"
s3 = s1 + " " + s2
print(s3) # 输出 "Hello World"

# 格式化方法
name = "Alice"
age = 25
# 旧式格式化
print("My name is %s, and I am %d years old." % (name, age))
# 新式格式化
print("My name is {}, and I am {} years old.".format(name, age))
# f-string 格式化
print(f"My name is {name}, and I am {age} years old.")

列表操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 增
my_list = [1, 2, 3]
my_list.append(4) # 在列表末尾添加元素
print(my_list) # 输出 [1, 2, 3, 4]
my_list.insert(1, 5) # 在指定位置插入元素
print(my_list) # 输出 [1, 5, 2, 3, 4]

# 删
my_list.pop() # 删除列表末尾元素
print(my_list) # 输出 [1, 5, 2, 3]
my_list.remove(5) # 删除指定元素
print(my_list) # 输出 [1, 2, 3]

# 改
my_list[1] = 10 # 修改指定位置元素
print(my_list) # 输出 [1, 10, 3]

# 查
print(my_list.index(10)) # 查找元素位置,输出 1

# 排序
my_list = [3, 1, 2]
my_list.sort() # 升序排序
print(my_list) # 输出 [1, 2, 3]
my_list.sort(reverse=True) # 降序排序
print(my_list) # 输出 [3, 2, 1]

字典操作

1
2
3
4
5
6
7
8
9
10
11
12
13
# 键值对操作
my_dict = {'name': 'Alice', 'age': 25}
# 增/改
my_dict['city'] = 'New York' # 添加新的键值对
my_dict['age'] = 26 # 修改已有键的值
print(my_dict) # 输出 {'name': 'Alice', 'age': 26, 'city': 'New York'}

# 删
del my_dict['city'] # 删除指定键值对
print(my_dict) # 输出 {'name': 'Alice', 'age': 26}

# 查
print(my_dict.get('name')) # 获取指定键的值,输出 'Alice'

2.2 条件语句

Python 使用 ifelifelse 来控制程序的流程。elif 用于多重条件判断。

1
2
3
4
5
6
7
age = 18
if age < 18:
print("未成年")
elif age == 18:
print("刚成年")
else:
print("成人")

2.3 循环语句

Python 支持 forwhile 循环。建议不要直接使用常量值进行循环,而是使用变量来控制循环次数。

1
2
3
4
5
6
7
8
9
10
11
12
# 定义循环次数的变量
num_iterations = 5

# for 循环
for i in range(num_iterations):
print(i)

# while 循环
i = 0
while i < num_iterations:
print(i)
i += 1

2.4 print 函数

print() 用于输出信息到控制台,常用于调试和查看程序的运行结果。它可以接受多个参数,并以空格分隔输出。

1
2
3
4
5
6
7
8
9
10
11
12
# 输出单个字符串
print("Hello, Python!")

# 输出多个参数
x = 10
y = 3.14
print("x =", x, "y =", y)

# 格式化输出
name = "Alice"
age = 25
print(f"My name is {name}, and I am {age} years old.")

print-f 使用方式说明
f-string(格式化字符串字面值)是 Python 3.6 及以上版本引入的一种字符串格式化方法。在字符串前加上 fF 前缀,然后在字符串中使用大括号 {} 来包含表达式,Python 会在运行时将这些表达式求值并替换到字符串中。这种方式简洁直观,提高了代码的可读性和可维护性。例如上述示例中,{name}{age} 会被变量 nameage 的实际值替换。

三、函数

3.1 定义函数

使用 def 关键字定义函数,函数可以接受参数并返回结果。

1
2
3
4
def add(a, b=5):
# 这里定义了一个函数 add,接收两个参数 a 和 b
# b=5 是默认参数的写法,意思是如果调用函数时没有提供 b 的值,b 会默认为 5
return a + b

函数调用

1
2
print(add(10))  # 调用时只传递了 a,b 使用默认值 5 -> 10 + 5 = 15
print(add(10, 20)) # 调用时传递了 b,b 为 20 -> 10 + 20 = 30

3.2 函数参数详解

3.2.1 可变参数(args 和 *kwargs)

*args 是一个元组,**kwargs 是一个字典

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# *args 用于接收任意数量的位置参数
def sum_numbers(*args):
total = 0
for num in args:
total += num
return total

print(sum_numbers(1, 2, 3)) # 输出 6

# **kwargs 用于接收任意数量的关键字参数
def print_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")

print_info(name="Alice", age=25, city="New York")

3.2.2 参数解包

1
2
3
4
5
6
7
8
def add(a, b):
return a + b

numbers = [1, 2]
print(add(*numbers)) # 参数解包,输出 3

info = {'a': 1, 'b': 2}
print(add(**info)) # 关键字参数解包,输出 3

3.3 装饰器

装饰器本质上是一个高阶函数,它可以在不修改原函数代码的情况下,动态地添加功能。这点就类似于 Java 中的动态代理。

1
2
3
4
5
6
7
8
9
10
11
12
def decorator(func):
def wrapper():
print("调用函数前执行")
func()
print("调用函数后执行")
return wrapper

@decorator # 等价于 say_hello = decorator(say_hello)
def say_hello():
print("Hello, world!")

say_hello()

四、面向对象

4.1 类和对象

Python 是一门面向对象的编程语言。类是对象的模板,对象是类的实例。

1
2
3
4
5
6
7
8
9
class Dog:
def __init__(self, name, age):
# __init__ 是构造函数,用于初始化类实例
# self 表示实例本身,name 和 age 是对象的属性
self.name = name
self.age = age

def bark(self):
print(f"{self.name} is barking!")

创建对象并调用方法

1
2
dog1 = Dog("Buddy", 3)
dog1.bark() # 输出 "Buddy is barking!"

4.2 类的继承机制

像 Java、C# 只支持单继承,他们虽然不支持多继承,但是通过实现多接口来间接弥补了多继承的缺陷。

像 C++、Python 既支持单继承,也支持多继承。

4.2.1 单继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Animal:
def __init__(self, name):
self.name = name

def eat(self):
print(f"{self.name} is eating.")

class Cat(Animal):
def meow(self):
print(f"{self.name} is meowing.")

cat = Cat("Tom")
cat.eat() # 继承自 Animal 类的方法
cat.meow() # 自身的方法

4.2.2 多继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Flyable:
def fly(self):
print("Flying...")

class Swimmable:
def swim(self):
print("Swimming...")

class Duck(Flyable, Swimmable):
def quack(self):
print("Quack!")

duck = Duck()
duck.fly()
duck.swim()
duck.quack()

4.2.3 方法重写实现多态性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Shape:
def area(self):
pass

class Circle(Shape):
def __init__(self, radius):
self.radius = radius

def area(self):
return 3.14 * self.radius ** 2

class Rectangle(Shape):
def __init__(self, length, width):
self.length = length
self.width = width

def area(self):
return self.length * self.width

shapes = [Circle(5), Rectangle(3, 4)]
for shape in shapes:
print(shape.area())

4.3 魔法方法和属性

4.3.1 魔法方法

魔法方法是 Python 中的一种特殊方法,魔法方法的名称必须以双下划线开头和结尾。例如,__init____add____len__

这些方法通常在特定的上下文中自动调用,用户不需要直接调用它们。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Book:
def __init__(self, title, author):
self.title = title
self.author = author

def __str__(self):
return f"Book: {self.title} by {self.author}"

def __repr__(self):
return f"Book('{self.title}', '{self.author}')"

def __add__(self, other):
return f"self={self.title}, other={other.title}"

def __len__(self):
return len(self.title)


book = Book("Python Crash Course", "Eric Matthes")
print(book) # 调用 __str__ 方法
print(repr(book)) # 调用 __repr__ 方法
print(len(book)) # 调用 __len__ 方法

a = Book("a", "a")
b = Book("b", "b")
print(a + b) # 调用 a+b 实际上,是触发了 a.__add__(b) 的方法

4.3.2 类属性和实例属性的区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Car:
# 类属性
wheels = 4

def __init__(self, brand):
# 实例属性
self.brand = brand

car1 = Car("Toyota")
car2 = Car("Honda")

print(car1.wheels) # 访问类属性
print(car1.brand) # 访问实例属性

Car.wheels = 6 # 修改类属性
print(car2.wheels) # 所有实例的类属性都被修改

五、线程与协程

5.1 线程

Python 提供了 threading 模块来处理多线程。每个线程都是一个独立的执行流,在多核 CPU 上可以并行运行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import threading

def print_numbers():
for i in range(5):
print(i)

# 创建两个线程
thread1 = threading.Thread(target=print_numbers)
thread2 = threading.Thread(target=print_numbers)

# 启动线程
thread1.start()
thread2.start()

# 等待线程完成
thread1.join()
thread2.join()

print("thread1 and thread2 Done")

5.2 协程

协程是通过 asyncio 模块实现的轻量级线程。它比线程更节省资源,适用于 I/O 密集型任务。

asyncawait 是 Python 3.5 引入的关键字,用于简化异步编程。

1
2
3
4
5
6
7
8
9
import asyncio

async def my_coroutine():
print("Start")
await asyncio.sleep(1) # 模拟 I/O 操作
print("End")

# 创建事件循环并运行协程
asyncio.run(my_coroutine())

解释

  • async def 用于定义一个异步函数,也叫作 协程(coroutine)。协程函数与普通的函数不同,它是可暂停的、可恢复的。定义协程函数时,必须在函数前加上 async 关键字。
  • await 用来等待一个异步操作的结果,它只能在 async 函数内部使用。当 Python 执行到 await 时,它会暂停当前的协程,直到 await 后面的异步操作完成后,才会继续执行。

六、其他语法

6.1 列表解析

列表解析是 Python 的一项强大特性,可以通过简洁的语法生成列表。

1
2
3
4
5
6
7
8
9
10
11
12
# 基本的列表解析
squares = [x**2 for x in range(5)] # 生成 0 到 4 的平方数列表
print(squares) # 输出 [0, 1, 4, 9, 16]

# 带条件的列表解析
even_squares = [x**2 for x in range(10) if x % 2 == 0] # 只生成偶数的平方
print(even_squares) # 输出 [0, 4, 16, 36, 64]

# 嵌套列表解析
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [item for row in matrix for item in row] # 将二维列表展平为一维
print(flattened) # 输出 [1, 2, 3, 4, 5, 6, 7, 8, 9]

6.2 生成器

生成器(Generator) 是一种用于创建迭代器的工具,它允许你在迭代数据时按需生成值,而不是一次性生成所有数据并存储在内存中,从而更节省内存并提高效率。

生成器的核心特性是惰性求值,它会在每次需要下一个元素时才计算并返回该元素。生成器是通过一个特殊的函数创建的,该函数使用 yield 关键字来逐步返回值,而不是像普通函数那样一次性返回结果。每次调用 yield 时,函数会暂停执行并返回一个值,直到下一次请求时才恢复执行。

1
2
3
4
5
def count_up_to(max):
count = 1
while count <= max:
yield count # yield 返回一个值,并且暂停函数执行,直到下一次调用时继续
count += 1

使用生成器

1
2
3
gen = count_up_to(5)
for num in gen:
print(num) # 输出 1, 2, 3, 4, 5,每次调用时返回一个值

6.3 异常处理

Python 提供了强大的异常处理机制,通过 tryexceptelsefinally 可以进行错误捕获与处理。

1
2
3
4
5
6
7
8
try:
x = 10 / 0 # 这里会抛出 ZeroDivisionError 异常,因为除数是 0
except ZeroDivisionError as e:
print("除数不能为零")
else:
print("没有异常发生")
finally:
print("无论如何都会执行")

6.4 文件操作

with 是 Python 中的一个上下文管理器(context manager)语法,用于简化资源的管理,尤其是在处理需要显式打开和关闭的资源时(如文件、数据库连接、网络套接字等)。

读取文件

1
2
3
4
5
6
7
8
# 读文件
with open('python-learn.md', 'r', encoding='utf-8') as f:
content = f.read() # 一次性读取整个文件内容
print(content)

# 写文件
with open('output.sh', 'w', encoding='utf-8') as f:
f.write("Hello, Python!") # 将文本写入文件

七、框架使用

7.1 flask

安装框架

1
pip install flask

参照 reqres.in 实现 api

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
from flask import Flask, request, jsonify

app = Flask(__name__)

database = {
"users": [
{
"avatar": "https://reqres.in/img/faces/1-image.jpg",
"email": "george.bluth@reqres.in",
"first_name": "George",
"id": 1,
"last_name": "Bluth"
},
{
"avatar": "https://reqres.in/img/faces/2-image.jpg",
"email": "janet.weaver@reqres.in",
"first_name": "Janet",
"id": 2,
"last_name": "Weaver"
},
{
"avatar": "https://reqres.in/img/faces/3-image.jpg",
"email": "emma.wong@reqres.in",
"first_name": "Emma",
"id": 3,
"last_name": "Wong"
},
{
"avatar": "https://reqres.in/img/faces/4-image.jpg",
"email": "eve.holt@reqres.in",
"first_name": "Eve",
"id": 4,
"last_name": "Holt"
},
{
"avatar": "https://reqres.in/img/faces/5-image.jpg",
"email": "charles.morris@reqres.in",
"first_name": "Charles",
"id": 5,
"last_name": "Morris"
},
{
"avatar": "https://reqres.in/img/faces/6-image.jpg",
"email": "tracey.ramos@reqres.in",
"first_name": "Tracey",
"id": 6,
"last_name": "Ramos"
},
{
"avatar": "https://reqres.in/img/faces/7-image.jpg",
"email": "michael.lawson@reqres.in",
"first_name": "Michael",
"id": 7,
"last_name": "Lawson"
},
{
"avatar": "https://reqres.in/img/faces/8-image.jpg",
"email": "lindsay.ferguson@reqres.in",
"first_name": "Lindsay",
"id": 8,
"last_name": "Ferguson"
},
{
"avatar": "https://reqres.in/img/faces/9-image.jpg",
"email": "tobias.funke@reqres.in",
"first_name": "Tobias",
"id": 9,
"last_name": "Funke"
},
{
"avatar": "https://reqres.in/img/faces/10-image.jpg",
"email": "byron.fields@reqres.in",
"first_name": "Byron",
"id": 10,
"last_name": "Fields"
},
{
"avatar": "https://reqres.in/img/faces/11-image.jpg",
"email": "george.edwards@reqres.in",
"first_name": "George",
"id": 11,
"last_name": "Edwards"
},
{
"avatar": "https://reqres.in/img/faces/12-image.jpg",
"email": "rachel.howell@reqres.in",
"first_name": "Rachel",
"id": 12,
"last_name": "Howell"
}
]
}


@app.route('/api/users', methods=['GET'])
def get_users():
try:
page = int(request.args.get('page', 1))
per_page = int(request.args.get('per_page', 6))
except Exception:
return jsonify({"error": "Invalid page or per_page parameter"}), 400

total = len(database['users'])

# 计算正确的起始和结束索引
start_idx = (page - 1) * per_page
end_idx = min(start_idx + per_page, total)

return jsonify({
"page": page,
"per_page": per_page,
"total": total,
# 1 if total % per_page else 0
# 等价于
# if total % per_page:
# result = 1
# else:
# result = 0
"total_pages": (total // per_page) + (1 if total % per_page else 0),
# 前开后闭
"data": database['users'][start_idx:end_idx]
})


@app.route('/api/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
user = next((u for u in database['users'] if u['id'] == user_id), None)
if user:
return jsonify({"data": user})
return jsonify({"error": "User not found"}), 404


@app.route('/api/users', methods=['POST'])
def create_user():
data = request.json
new_id = max(user['id'] for user in database['users']) + 1
new_user = {
"id": new_id,
"email": data.get("email"),
"first_name": data.get("first_name"),
"last_name": data.get("last_name"),
"avatar": "https://reqres.in/img/faces/{}-image.jpg".format(new_id)
}
database['users'].append(new_user)
return jsonify(new_user), 201


@app.route('/api/users/<int:user_id>', methods=['PUT'])
def update_user(user_id):
data = request.json
user = next((u for u in database['users'] if u['id'] == user_id), None)
if user:
user.update(data)
return jsonify(user)
return jsonify({"error": "User not found"}), 404


@app.route('/api/users/<int:user_id>', methods=['DELETE'])
def delete_user(user_id):
global database
database['users'] = [u for u in database['users'] if u['id'] != user_id]
return '', 204


if __name__ == '__main__':
app.run(debug=True)

7.2 transformers

7.3 torch

八、程序打包

打包工具如 pyinstaller 可以将 Python 程序打包成独立的可执行文件,方便分发和使用。

8.1 基本打包

首先,确保你已经安装了 pyinstaller,如果没有安装,可以使用以下命令进行安装:

1
pip install pyinstaller

如果你有一个简单的 Python 脚本,例如 your_script.py,可以使用以下命令将其打包成一个独立的可执行文件:

1
pyinstaller --clean --onefile --icon=test.ico --name=hh.exe your_script.py

执行上述命令后,pyinstaller 会在 dist 目录下生成一个与脚本同名的可执行文件。

如果你希望将依赖项分离出来,以减小可执行文件的大小,可以使用以下命令:

1
pyinstaller --clean --onedir --icon=test.ico --name=hh.exe your_script.py

--onedir 选项会将程序和依赖项打包到一个目录中,而不是一个单独的文件。这样,可执行文件会变小,但需要将整个目录一起分发。

在初次打包时,pyinstaller 会自动生成 .spec 扩展名的配置文件,可以通过手动编辑 .spec 文件来定制打包行为。

8.2 处理依赖多个自定义 Python 脚本的情况

假设你的 Python 主函数依赖了几个自己写的 Python 脚本,目录结构如下:

1
2
3
4
5
6
7
8
9
10
project/.

Example09.py

└─sub09
├─clazz
│ │ Sub09Class.py

└─func
Sub09Func.py

其中,Example09.py 是主程序,Sub09Func.pySub09Class.py 是自定义的模块。

Example09.py 示例代码:

1
2
3
4
5
6
7
8
9
10
# 引入其他模块写的函数
from sub09.func.Sub09Func import print_info
# 引入其他模块定义的类
from sub09.clazz.Sub09Class import Animal

animal = Animal("HK")

content = animal.speek()

print_info(speek=content)

Sub09Func.py 示例代码:

1
2
3
def print_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")

Sub09Class.py 示例代码:

1
2
3
4
5
6
class Animal:
def __init__(self, name):
self.name = name

def speek(self):
return f"My name is {self.name}"

要将这些脚本打包成一个程序入口,可以在项目根目录下执行以下命令:

1
pyinstaller --onefile Example09.py

pyinstaller 会自动检测依赖关系,并将其包含到打包结果中。打包完成后,在 dist 目录下会生成一个 main 可执行文件,运行该文件即可启动整个程序。

有一点注意,当你第一次导入某个模块时,Python 会编译该模块并生成 .pyc 文件。

发布:2025-03-16 22:05:23
修改:2025-03-18 22:08:35
链接:https://meethigher.top/blog/2025/python-learn/
标签:python 
付款码 打赏 分享
Shift+Ctrl+1 可控制工具栏