欢迎来到Python编程的世界!本教程旨在为完全没有编程经验的“小白”提供一份全面、易懂且实用的Python学习路径,助您从零基础逐步成长为一名能够独立开发和解决问题的Python开发者。
为何选择Python? Python以其简洁的语法、强大的功能和广泛的应用领域(Web开发、数据科学、人工智能、自动化脚本等)而备受青睐。学习Python,将为您打开通往未来科技世界的大门。
Python是什么? Python是一种高级、解释型、通用且动态的编程语言。它支持多种编程范式,包括面向对象、命令式、函数式和过程式编程。
为什么要学Python?
对于初学者,推荐安装Anaconda发行版。Anaconda是一个集成了Python解释器、conda包管理器以及众多常用科学计算库(如NumPy, Pandas, Matplotlib)的免费开源平台。它能省去许多环境配置的麻烦。
https://www.anaconda.com/products/distributionpython --version 检查Python版本,输入 conda --version 检查conda版本。让我们来编写并运行您的第一个Python程序——“Hello World!”。
# 这是一个简单的Python程序,用于在控制台输出“Hello World!”
print("Hello World!")
如何运行:
hello.py 的文件(确保文件扩展名为 .py)。hello.py 文件所在的目录。python hello.py您将会在命令行看到输出:Hello World!
变量是用来存储数据的容器。在Python中,您无需提前声明变量的类型,Python会根据赋值自动推断。
# 变量赋值
message = "你好,Python!" # 字符串类型
age = 30 # 整数类型
pi = 3.14159 # 浮点数类型
is_active = True # 布尔类型
print(message)
print(age)
print(pi)
print(is_active)
# 您可以使用 type() 函数查看变量的类型
print(type(message))
print(type(age))
print(type(pi))
print(type(is_active))
输出:
你好,Python!
30
3.14159
True
<class 'str'>
<class 'int'>
<class 'float'>
<class 'bool'>
int): 任意大小的整数,如 10, -5, 10000000000。float): 带小数点的数字,如 3.14, -0.5, 2.0。complex),但在日常编程中不常用。str)字符串是由一系列字符组成的。可以使用单引号 ''、双引号 "" 或三引号 ''' ''' / """ """ 定义。
single_quote_str = '这是一个单引号字符串。'
double_quote_str = "这是一个双引号字符串。"
multi_line_str = """这是一个
多行字符串,
可以保留格式。"""
print(single_quote_str)
print(double_quote_str)
print(multi_line_str)
# 字符串拼接
greeting = "Hello"
name = "Alice"
full_greeting = greeting + ", " + name + "!"
print(full_greeting)
# 字符串格式化(推荐f-string,Python 3.6+)
age = 25
formatted_string = f"我的名字是{name},我今年{age}岁。"
print(formatted_string)
bool)布尔值只有两个:True 和 False,常用于逻辑判断。
age 和 Age 是不同的变量)。if, for, while 等)。snake_case)来命名变量和函数。运算符用于对变量和值执行操作。
| 运算符 | 描述 | 示例 | 结果 |
|---|---|---|---|
+ |
加法 | 5 + 2 |
7 |
- |
减法 | 5 - 2 |
3 |
* |
乘法 | 5 * 2 |
10 |
/ |
除法(浮点数) | 5 / 2 |
2.5 |
// |
整除(向下取整) | 5 // 2 |
2 |
% |
取模(取余数) | 5 % 2 |
1 |
** |
幂运算 | 5 ** 2 |
25 |
用于比较两个值,返回布尔值(True 或 False)。
| 运算符 | 描述 | 示例 | 结果 |
|---|---|---|---|
== |
等于 | 5 == 2 |
False |
!= |
不等于 | 5 != 2 |
True |
> |
大于 | 5 > 2 |
True |
< |
小于 | 5 < 2 |
False |
>= |
大于等于 | 5 >= 5 |
True |
<= |
小于等于 | 5 <= 2 |
False |
用于组合条件语句。
| 运算符 | 描述 | 示例 |
|---|---|---|
and |
如果两个条件都为真,则结果为真 | (True and False) 结果为 False |
or |
如果至少一个条件为真,则结果为真 | (True or False) 结果为 True |
not |
取反 | not True 结果为 False |
x = 10
y = 20
z = 10
print(f"x == z: {x == z}")
print(f"x > y: {x > y}")
print(f"x < y and x == z: {x < y and x == z}")
print(f"x > y or x == z: {x > y or x == z}")
print(f"not (x > y): {not (x > y)}")
控制流语句决定了程序执行的顺序。
根据条件执行不同的代码块。
score = 85
if score >= 90:
print("优秀!")
elif score >= 60:
print("及格。")
else:
print("不及格。")
注意缩进! Python使用缩进来表示代码块的归属关系,而不是大括号。这是Python的一大特点,也是初学者容易犯错的地方。通常使用4个空格作为标准缩进。
for 循环: 常用于遍历序列(如列表、字符串、元组、字典)。
# 遍历列表
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)
# 遍历数字序列(使用 range() 函数)
# range(5) 会生成 0, 1, 2, 3, 4
for i in range(5):
print(f"当前数字是:{i}")
# range(start, end)
for i in range(1, 4): # 1, 2, 3
print(i)
# range(start, end, step)
for i in range(0, 10, 2): # 0, 2, 4, 6, 8
print(i)
while 循环: 当条件为真时,重复执行代码块。
count = 0
while count < 5:
print(f"Count is: {count}")
count += 1 # 等同于 count = count + 1
# 示例:猜数字游戏
import random
secret_number = random.randint(1, 10)
guess = 0
while guess != secret_number:
try:
guess = int(input("请猜一个1到10的数字:"))
if guess < secret_number:
print("太小了!")
elif guess > secret_number:
print("太大了!")
except ValueError:
print("请输入一个有效的整数!")
print(f"恭喜你,猜对了!数字是 {secret_number}")
break: 立即终止当前循环。continue: 跳过当前循环的剩余部分,进入下一次循环。pass: 占位符,不做任何事情,常用于构建空的代码块或函数,避免语法错误。
# break 示例
for i in range(10):
if i == 5:
break # 当 i 等于 5 时,循环停止
print(i) # 输出 0, 1, 2, 3, 4
print("-" * 20)
# continue 示例
for i in range(10):
if i % 2 == 0: # 如果 i 是偶数
continue # 跳过本次循环的print,进入下一个i
print(i) # 输出 1, 3, 5, 7, 9
print("-" * 20)
# pass 示例
def my_function():
pass # 以后再实现具体逻辑
if True:
pass # 暂时不知道要写什么,但需要一个代码块
Python提供了几种内置的复合数据类型,用于存储和组织数据。它们是编程中不可或缺的工具。
列表是Python中最常用的数据结构,它是一个有序、可变的元素集合。列表中的元素可以是任何数据类型。
# 创建列表
my_list = [1, 2, 3, "hello", True, 3.14]
print(my_list)
# 索引(从0开始)
print(f"第一个元素: {my_list[0]}") # 1
print(f"最后一个元素: {my_list[-1]}") # 3.14
# 切片 [start:end:step] (end不包含)
print(f"前三个元素: {my_list[0:3]}") # [1, 2, 3]
print(f"从第二个元素到结尾: {my_list[1:]}") # [2, 3, 'hello', True, 3.14]
print(f"复制列表: {my_list[:]}")
# 修改元素
my_list[0] = 100
print(f"修改后的列表: {my_list}")
# 添加元素
my_list.append("new_item") # 在末尾添加
my_list.insert(1, "inserted_item") # 在指定位置插入
print(f"添加元素后: {my_list}")
# 删除元素
my_list.remove("hello") # 按值删除第一个匹配项
del my_list[0] # 按索引删除
popped_item = my_list.pop() # 删除并返回末尾元素
print(f"删除元素后: {my_list}")
print(f"被弹出的元素: {popped_item}")
# 常用方法
num_list = [3, 1, 4, 1, 5, 9, 2]
num_list.sort() # 排序
print(f"排序后: {num_list}")
num_list.reverse() # 反转
print(f"反转后: {num_list}")
print(f"元素 '1' 的数量: {num_list.count(1)}")
print(f"元素 '5' 的索引: {num_list.index(5)}")
元组是有序、不可变的元素集合。一旦创建,元组中的元素就不能被修改、添加或删除。常用于存储不希望被修改的数据。
# 创建元组
my_tuple = (1, 2, "apple", False)
print(my_tuple)
# 访问元素和切片(与列表类似)
print(f"第一个元素: {my_tuple[0]}")
print(f"切片: {my_tuple[1:3]}")
# 尝试修改会报错
# my_tuple[0] = 10 # TypeError: 'tuple' object does not support item assignment
# 元组的解包
x, y, z, flag = my_tuple
print(f"解包结果: x={x}, y={y}, z={z}, flag={flag}")
字典是无序(Python 3.7+版本中字典保持插入顺序)、可变的键值对(key-value pair)集合。每个键(key)必须是唯一的,且不可变(如字符串、数字、元组),值(value)可以是任意类型。
# 创建字典
person = {
"name": "Alice",
"age": 30,
"city": "New York"
}
print(person)
# 访问值
print(f"姓名: {person['name']}")
# 使用 .get() 方法,避免键不存在时报错
print(f"地址: {person.get('address', '未知地址')}")
# 添加/修改键值对
person["email"] = "[email protected]" # 添加新键
person["age"] = 31 # 修改现有键的值
print(f"更新后: {person}")
# 删除键值对
del person["city"] # 按键删除
# popped_value = person.pop("age") # 删除并返回对应的值
print(f"删除城市后: {person}")
# print(f"被弹出的年龄: {popped_value}")
# 遍历字典
print("遍历键:")
for key in person.keys():
print(key)
print("遍历值:")
for value in person.values():
print(value)
print("遍历键值对:")
for key, value in person.items():
print(f"{key}: {value}")
集合是无序、不重复元素的集合。常用于去重和数学上的集合操作(并集、交集、差集)。
# 创建集合
my_set = {1, 2, 3, 2, 1, 4} # 重复元素会自动去重
print(f"去重后的集合: {my_set}") # {1, 2, 3, 4}
# 从列表创建集合
list_with_duplicates = [1, 2, 2, 3, 4, 4, 5]
unique_elements = set(list_with_duplicates)
print(f"列表去重后: {unique_elements}")
# 添加元素
my_set.add(5)
print(f"添加元素后: {my_set}")
# 删除元素
my_set.remove(1) # 如果元素不存在会报错
my_set.discard(10) # 如果元素不存在也不会报错
print(f"删除元素后: {my_set}")
# 集合操作
set_a = {1, 2, 3, 4}
set_b = {3, 4, 5, 6}
print(f"并集 (union): {set_a | set_b}") # {1, 2, 3, 4, 5, 6}
print(f"交集 (intersection): {set_a & set_b}") # {3, 4}
print(f"差集 (difference A-B): {set_a - set_b}") # {1, 2}
print(f"差集 (difference B-A): {set_b - set_a}") # {5, 6}
print(f"对称差集 (symmetric difference): {set_a ^ set_b}") # {1, 2, 5, 6}
函数是一段封装了特定功能的代码块,可以被多次调用,提高代码的重用性。
# 定义一个无参数、无返回值的函数
def greet():
print("Hello, welcome to Python!")
# 调用函数
greet()
# 定义带参数的函数
def greet_person(name):
print(f"Hello, {name}!")
greet_person("Alice")
greet_person("Bob")
# 定义带返回值的函数
def add(a, b):
result = a + b
return result
sum_result = add(10, 20)
print(f"10 + 20 = {sum_result}")
# 默认参数
def say_hello(name="World"):
print(f"Hello, {name}!")
say_hello() # 输出: Hello, World!
say_hello("Charlie") # 输出: Hello, Charlie!
# 可变参数 (*args 和 **kwargs)
# *args 收集位置参数为元组
def sum_all(*args):
total = 0
for num in args:
total += num
return total
print(f"Sum of 1,2,3: {sum_all(1, 2, 3)}") # 输出: 6
# **kwargs 收集关键字参数为字典
def print_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="David", age=25, city="London")
函数内部定义的变量是局部变量,只在函数内部有效。函数外部定义的变量是全局变量,可以在整个程序中访问。
global_var = "我是全局变量"
def my_function():
local_var = "我是局部变量"
print(global_var) # 可以访问全局变量
print(local_var) # 可以访问局部变量
my_function()
print(global_var)
# print(local_var) # 这会报错,因为 local_var 在函数外部不可见
注意: 在函数内部修改全局变量需要使用 global 关键字声明,但通常不推荐直接修改全局变量,因为它会使代码难以理解和维护。
global_count = 0
def increment_global_count():
global global_count # 声明使用全局变量
global_count += 1
increment_global_count()
print(global_count) # 输出: 1
Lambda函数是一种小型、匿名的函数,只能包含一个表达式。常用于需要一个简单函数作为参数的情况。
# 普通函数实现加法
def add_normal(x, y):
return x + y
print(add_normal(1, 2))
# Lambda函数实现加法
add_lambda = lambda x, y: x + y
print(add_lambda(1, 2))
# 结合高阶函数使用 (如 map, filter, sorted)
numbers = [1, 2, 3, 4, 5]
# 使用 map 将每个数字平方
squared_numbers = list(map(lambda x: x**2, numbers))
print(f"平方后的数字: {squared_numbers}") # [1, 4, 9, 16, 25]
# 使用 filter 筛选偶数
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(f"偶数: {even_numbers}") # [2, 4]
模块(Module): 一个 .py 文件就是一个模块,它包含Python代码(函数、类、变量等)。
包(Package): 包含多个模块的目录。包的目录下通常会有一个 __init__.py 文件(Python 3.3+不再强制要求,但仍是惯例)。
# 导入整个模块
import math
print(f"圆周率: {math.pi}")
print(f"16的平方根: {math.sqrt(16)}")
# 从模块中导入特定内容
from random import randint, choice
print(f"1到100的随机整数: {randint(1, 100)}")
print(f"随机选择一个水果: {choice(['apple', 'banana', 'cherry'])}")
# 导入模块并使用别名
import datetime as dt
now = dt.datetime.now()
print(f"当前时间: {now}")
使用 import vs from...import:
import module_name:导入整个模块,使用时需要 module_name.function()。优点是避免命名冲突。from module_name import function_name:只导入模块中的特定函数或变量,可以直接使用 function_name()。优点是代码更简洁,缺点是可能出现命名冲突。from module_name import *,因为它会将模块中所有内容导入当前命名空间,极易造成命名冲突。math:数学函数。random:生成随机数。time:时间相关操作。os:与操作系统交互(如文件路径、环境变量)。sys:与Python解释器交互(如命令行参数、退出程序)。json:处理JSON数据。re:正则表达式操作。Python提供了简单直观的方式来读写文件。
# 写入文件
# 'w' 模式:写入,如果文件不存在则创建,如果文件存在则清空内容再写入
with open("my_file.txt", "w", encoding="utf-8") as f:
f.write("Hello, Python!\n")
f.write("This is a file operation example.\n")
print("文件写入完成。")
# 读取文件
# 'r' 模式:读取
with open("my_file.txt", "r", encoding="utf-8") as f:
content = f.read() # 读取所有内容
print("---文件内容---")
print(content)
print("---文件内容结束---")
# 按行读取
with open("my_file.txt", "r", encoding="utf-8") as f:
print("---按行读取---")
for line in f:
print(line.strip()) # strip() 去除每行末尾的换行符
print("---按行读取结束---")
# 追加内容
# 'a' 模式:追加,在文件末尾添加内容
with open("my_file.txt", "a", encoding="utf-8") as f:
f.write("Appending new line.\n")
print("文件追加完成。")
# 再次读取,验证追加
with open("my_file.txt", "r", encoding="utf-8") as f:
print("---追加后内容---")
print(f.read())
with open(...) as f: 的好处: 这种方式被称为“上下文管理器”。它确保文件在使用完毕后(无论是否发生异常)都会自动关闭,避免资源泄露。强烈推荐使用。
文件模式:
'r':读取(默认)'w':写入(会覆盖原内容)'a':追加(在文件末尾添加)'rb', 'wb', 'ab':二进制模式,用于处理非文本文件(如图片、视频),不进行编码解码。程序运行时可能发生错误,这些错误被称为“异常”。合理的异常处理可以防止程序崩溃,提高健壮性。
# 常见异常示例
# print(10 / 0) # ZeroDivisionError: division by zero
# print(int("abc")) # ValueError: invalid literal for int() with base 10: 'abc'
# my_list = [1, 2]
# print(my_list[3]) # IndexError: list index out of range
# try...except...finally 语句
try:
num1 = int(input("请输入第一个数字: "))
num2 = int(input("请输入第二个数字: "))
result = num1 / num2
print(f"结果是: {result}")
except ValueError:
print("错误:请输入有效的整数!")
except ZeroDivisionError:
print("错误:除数不能为零!")
except Exception as e: # 捕获所有其他异常
print(f"发生了一个未知的错误: {e}")
else: # 如果try块没有发生异常,则执行else块
print("计算成功完成!")
finally: # 无论是否发生异常,finally块的代码都会执行
print("程序执行结束。")
# 示例:尝试打开一个不存在的文件
try:
with open("non_existent_file.txt", "r") as f:
content = f.read()
print(content)
except FileNotFoundError:
print("错误:文件未找到,请检查文件名或路径。")
except Exception as e:
print(f"读取文件时发生其他错误: {e}")
面向对象编程(Object-Oriented Programming, OOP)是一种重要的编程范式,它通过“类”和“对象”的概念来组织代码,模拟现实世界中的事物。
# 定义一个简单的类
class Dog:
# 类属性:所有Dog对象共享的属性
species = "Canis familiaris"
# 构造方法:在创建新对象时自动调用
# self 参数代表实例本身,是必须的
def __init__(self, name, breed):
self.name = name # 实例属性:每个Dog对象独有的属性
self.breed = breed
# 实例方法:操作对象行为的方法
def bark(self):
print(f"{self.name} says Woof!")
def description(self):
return f"{self.name}是一只{self.breed},属于{self.species}。"
# 创建对象(实例化)
my_dog = Dog("Buddy", "Golden Retriever")
your_dog = Dog("Lucy", "Labrador")
# 访问对象属性
print(f"我的狗的名字: {my_dog.name}")
print(f"你的狗的品种: {your_dog.breed}")
print(f"所有狗的物种: {Dog.species}") # 访问类属性
# 调用对象方法
my_dog.bark()
your_dog.bark()
print(my_dog.description())
print(your_dog.description())
这是OOP的三大核心特性。
将数据(属性)和操作数据的方法(行为)捆绑在一起,形成一个独立的单元(类)。同时,隐藏对象的内部实现细节,只暴露必要的接口给外部。
_ 开头表示“受保护的”(不建议外部直接访问),以双下划线 __ 开头表示“私有化”(实际上是名称改编,可以在外部访问但方式复杂)。
class Account:
def __init__(self, balance):
self.__balance = balance # 双下划线表示私有化(名称改编)
def deposit(self, amount):
if amount > 0:
self.__balance += amount
print(f"存款 {amount}元,当前余额: {self.__balance}元")
else:
print("存款金额必须大于0。")
def withdraw(self, amount):
if 0 < amount <= self.__balance:
self.__balance -= amount
print(f"取款 {amount}元,当前余额: {self.__balance}元")
else:
print("取款失败:金额无效或余额不足。")
def get_balance(self):
return self.__balance
my_account = Account(1000)
my_account.deposit(500)
my_account.withdraw(200)
my_account.withdraw(2000) # 失败
# print(my_account.__balance) # 访问会报错
print(f"当前账户余额: {my_account.get_balance()}元")
允许一个类(子类/派生类)继承另一个类(父类/基类)的属性和方法。子类可以重用父类的代码,并在此基础上添加新功能或修改现有功能。
# 父类
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
raise NotImplementedError("子类必须实现此方法") # 抽象方法
# 子类 Dog 继承 Animal
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name) # 调用父类的构造方法
self.breed = breed
def speak(self): # 重写父类方法
return f"{self.name} says Woof!"
# 子类 Cat 继承 Animal
class Cat(Animal):
def speak(self): # 重写父类方法
return f"{self.name} says Meow!"
my_dog = Dog("Bingo", "Poodle")
my_cat = Cat("Whiskers")
print(my_dog.speak())
print(my_cat.speak())
print(f"我的狗的名字是: {my_dog.name}, 品种是: {my_dog.breed}")
指不同类的对象对同一方法调用,表现出不同的行为。多态性是继承的另一个重要体现。
def make_animal_speak(animal):
print(animal.speak())
make_animal_speak(my_dog) # Dog对象调用speak()
make_animal_speak(my_cat) # Cat对象调用speak()
# 这就是多态:虽然调用的是同一个 make_animal_speak 函数和 animal.speak() 方法,
# 但由于 animal 是不同的对象类型,实际执行的 speak() 方法是不同的实现。
以双下划线 __ 开头和结尾的方法,它们在特定情况下被Python自动调用,例如创建对象、打印对象、进行算术运算等。它们让您的自定义对象能够支持内置函数或操作符的行为。
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
# 当使用 print() 或 str() 转换时调用
def __str__(self):
return f"Point({self.x}, {self.y})"
# 当使用 repr() 或在交互式环境中直接输入对象时调用,通常用于精确表示对象
def __repr__(self):
return f"Point(x={self.x}, y={self.y})"
# 定义加法操作的行为
def __add__(self, other):
if isinstance(other, Point):
return Point(self.x + other.x, self.y + other.y)
raise TypeError("只能与Point对象相加")
# 定义等于操作的行为
def __eq__(self, other):
if isinstance(other, Point):
return self.x == other.x and self.y == other.y
return False
# 定义 len() 函数的行为
def __len__(self):
return 2 # 假设Point的“长度”是其维度
p1 = Point(1, 2)
p2 = Point(3, 4)
p3 = Point(1, 2)
print(p1) # 调用 __str__
print(repr(p1)) # 调用 __repr__
p_sum = p1 + p2 # 调用 __add__
print(f"p1 + p2 = {p_sum}")
print(f"p1 == p2: {p1 == p2}") # 调用 __eq__
print(f"p1 == p3: {p1 == p3}") # 调用 __eq__
print(f"len(p1): {len(p1)}") # 调用 __len__
常见的魔术方法还有:__len__ (len())、__getitem__ (索引访问[])、__setitem__ (索引赋值[])、__call__ (使对象可调用)、__del__ (对象销毁)等。
迭代器是实现了 __iter__() 和 __next__() 方法的对象。__iter__() 返回迭代器本身,__next__() 返回序列中的下一个元素,直到没有更多元素时抛出 StopIteration 异常。
您可以使用 iter() 函数获取一个迭代器,然后使用 next() 函数获取下一个元素。
my_list = [10, 20, 30, 40]
my_iterator = iter(my_list) # 获取列表的迭代器
print(next(my_iterator)) # 10
print(next(my_iterator)) # 20
print(next(my_iterator)) # 30
print(next(my_iterator)) # 40
# print(next(my_iterator)) # 再次调用会抛出 StopIteration
# for 循环的本质就是在使用迭代器
for item in my_list: # 内部会自动调用 iter() 和 next()
print(item)
生成器是一种特殊的迭代器,通过在函数中使用 yield 关键字来定义。它不需要一次性将所有数据加载到内存中,而是按需生成元素,非常适合处理大量数据或无限序列。
# 定义一个生成器函数,生成斐波那契数列
def fibonacci_sequence(n):
a, b = 0, 1
count = 0
while count < n:
yield a # 使用 yield 关键字
a, b = b, a + b
count += 1
# 使用生成器
fib_gen = fibonacci_sequence(5)
print(next(fib_gen)) # 0
print(next(fib_gen)) # 1
print(next(fib_gen)) # 1
print(next(fib_gen)) # 2
print(next(fib_gen)) # 3
print("\n通过 for 循环使用生成器:")
for num in fibonacci_sequence(7):
print(num)
# 生成器表达式 (类似于列表推导式,但生成器)
gen_exp = (x**2 for x in range(5)) # 不是列表,是一个生成器对象
print(f"生成器表达式类型: {type(gen_exp)}")
print(next(gen_exp)) # 0
print(next(gen_exp)) # 1
生成器与列表的区别: 列表一次性在内存中存储所有元素;生成器则按需生成,节省内存,尤其适用于处理大数据集。
装饰器(Decorator)是Python中一个非常强大的特性,它允许您在不修改原函数代码的情况下,增加或修改函数的功能。本质上,装饰器是一个接受函数作为参数并返回一个新函数的函数。
# 定义一个简单的装饰器:计算函数执行时间
import time
def timer(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs) # 执行原函数
end_time = time.time()
print(f"函数 '{func.__name__}' 执行耗时: {end_time - start_time:.4f} 秒")
return result
return wrapper
# 使用装饰器
@timer # 等同于 my_long_running_function = timer(my_long_running_function)
def my_long_running_function():
"""一个模拟长时间运行的函数"""
print("开始执行长时间任务...")
time.sleep(2) # 模拟耗时操作
print("任务执行完毕。")
return "任务结果"
# 调用被装饰的函数
res = my_long_running_function()
print(f"获取任务结果: {res}")
@timer
def add_numbers(a, b):
print(f"正在计算 {a} + {b}...")
time.sleep(0.5)
return a + b
add_numbers(100, 200)
装饰器语法 @decorator_name 是一个语法糖。它等同于 my_function = decorator_name(my_function)。
上下文管理器是Python中用于管理资源(如文件、网络连接等)的机制,它确保资源在进入和退出某个代码块时能够正确地被获取和释放。with 语句就是上下文管理器最常见的应用。
# 使用 with 语句操作文件 (最常见的上下文管理器示例)
# 文件会在 with 块结束时自动关闭
with open("example.txt", "w") as f:
f.write("Hello from context manager!")
print("文件已写入并自动关闭。")
# 自定义上下文管理器:通过实现 __enter__ 和 __exit__ 方法
class MyContextManager:
def __init__(self, name):
self.name = name
print(f"初始化上下文管理器: {self.name}")
def __enter__(self):
print(f"进入上下文: {self.name} - 资源已获取")
return self # 可以返回一个对象,赋给 as 后的变量
def __exit__(self, exc_type, exc_val, exc_tb):
print(f"退出上下文: {self.name} - 资源已释放")
if exc_type: # 如果发生异常
print(f"发生异常类型: {exc_type}, 值: {exc_val}")
# return True # 如果返回 True,表示异常已被处理,不会向上抛出
return False # 默认返回 False,表示异常会继续传播
print("\n---使用自定义上下文管理器---")
with MyContextManager("数据库连接") as db_conn:
print(f"在上下文内部执行操作,获取到对象: {db_conn.name}")
# db_conn.execute_query("SELECT * FROM users") # 假设的操作
print("\n---使用自定义上下文管理器并引发异常---")
with MyContextManager("文件处理") as file_handler:
print(f"在上下文内部执行操作: {file_handler.name}")
raise ValueError("一个模拟的错误")
print("程序继续执行 (如果异常被 __exit__ 捕获)")
Python的强大之处很大一部分来源于其“电池包含”(batteries included)的哲学,即拥有丰富的标准库和活跃的第三方库生态系统。
os 模块: 提供与操作系统交互的功能,如文件和目录操作。
import os
# 获取当前工作目录
print(f"当前工作目录: {os.getcwd()}")
# 创建目录
# os.makedirs("new_dir/sub_dir", exist_ok=True) # exist_ok=True 避免目录已存在时报错
# print("目录创建成功。")
# 列出目录内容
# print(f"当前目录内容: {os.listdir('.')}")
# 路径拼接(推荐,跨平台兼容)
file_path = os.path.join(os.getcwd(), "my_file.txt")
print(f"完整文件路径: {file_path}")
sys 模块: 提供对Python解释器相关操作的访问。
import sys
# 获取Python版本信息
print(f"Python版本: {sys.version}")
# 获取命令行参数 (如果从命令行运行脚本)
# script.py arg1 arg2
# print(f"命令行参数: {sys.argv}")
# 退出程序
# sys.exit(0) # 0表示正常退出
datetime 模块: 处理日期和时间。
import datetime
# 获取当前日期和时间
now = datetime.datetime.now()
print(f"当前日期时间: {now}")
# 创建特定日期
specific_date = datetime.date(2023, 10, 26)
print(f"特定日期: {specific_date}")
# 格式化日期时间
formatted_date = now.strftime("%Y-%m-%d %H:%M:%S")
print(f"格式化日期时间: {formatted_date}")
# 计算时间差
future_date = datetime.datetime(2024, 1, 1, 0, 0, 0)
time_remaining = future_date - now
print(f"距离2024年1月1日还有: {time_remaining}")
json 模块: 用于处理JSON(JavaScript Object Notation)数据,常用于网络数据交换。
import json
# Python字典转换为JSON字符串
data = {
"name": "Bob",
"age": 28,
"isStudent": False,
"courses": ["Math", "Physics"]
}
json_string = json.dumps(data, indent=4, ensure_ascii=False) # indent美化输出,ensure_ascii处理中文
print("---Python字典转JSON字符串---")
print(json_string)
# JSON字符串转换为Python字典
json_data_str = '{"product": "Laptop", "price": 1200}'
loaded_data = json.loads(json_data_str)
print("---JSON字符串转Python字典---")
print(loaded_data)
print(f"产品名称: {loaded_data['product']}")
re 模块: 提供正则表达式操作,用于字符串的模式匹配和查找替换。
import re
text = "Hello, my email is [email protected] and another is [email protected]."
# 查找所有匹配的邮箱地址
emails = re.findall(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b', text)
print(f"找到的邮箱: {emails}")
# 替换
new_text = re.sub(r'email is (\S+)', r'contact is [屏蔽]', text)
print(f"替换后: {new_text}")
# 匹配并获取分组
match = re.search(r'my email is (\S+)', text)
if match:
print(f"匹配到的邮箱: {match.group(1)}")
正则表达式较为复杂,需要专门学习其语法。 上述例子仅作演示。
Python拥有一个活跃的第三方库社区,通过 pip 工具可以方便地安装和使用这些库。以下是几个非常流行且用途广泛的库:
# 安装第三方库的命令示例
pip install requests numpy pandas matplotlib
requests: 最受欢迎的HTTP库,用于发送HTTP请求(如获取网页内容、调用API)。
import requests
try:
response = requests.get('https://api.github.com/events')
response.raise_for_status() # 如果请求失败,则抛出异常
print("GitHub API响应状态码:", response.status_code)
# print("响应内容 (前500字符):", response.text[:500])
json_data = response.json() # 将JSON响应解析为Python字典/列表
print("第一个事件类型:", json_data[0]['type'])
except requests.exceptions.RequestException as e:
print(f"请求失败: {e}")
NumPy: Numerical Python,科学计算的基础库,提供了高性能的多维数组对象(ndarray)和用于处理这些数组的工具。是数据科学和机器学习的基石。
import numpy as np
# 创建NumPy数组
arr = np.array([1, 2, 3, 4, 5])
print(f"NumPy数组: {arr}")
print(f"数组类型: {type(arr)}")
# 数组运算(广播机制)
print(f"数组加5: {arr + 5}")
print(f"数组乘2: {arr * 2}")
# 矩阵操作
matrix = np.array([[1, 2], [3, 4]])
print(f"矩阵:\n{matrix}")
print(f"矩阵转置:\n{matrix.T}")
Pandas: 基于NumPy构建的数据分析库,提供了高性能、易于使用的数据结构(如DataFrame和Series),是数据清洗、处理和分析的首选工具。
import pandas as pd
# 创建一个DataFrame(类似于Excel表格或SQL表)
data = {
'Name': ['Alice', 'Bob', 'Charlie'],
'Age': [24, 27, 22],
'City': ['New York', 'Los Angeles', 'Chicago']
}
df = pd.DataFrame(data)
print("---Pandas DataFrame---")
print(df)
# 数据筛选
print("\n---筛选年龄大于25的人---")
print(df[df['Age'] > 25])
# 计算平均年龄
print(f"\n平均年龄: {df['Age'].mean()}")
Matplotlib: 强大的2D绘图库,可以生成各种高质量的图表(线图、散点图、柱状图等)。
import matplotlib.pyplot as plt
import numpy as np
# 生成数据
x = np.linspace(0, 10, 100) # 0到10之间100个等间距点
y = np.sin(x)
# 绘制线图
plt.figure(figsize=(8, 4)) # 设置图表大小
plt.plot(x, y, label='sin(x)', color='blue', linestyle='--')
plt.title('Simple Sine Wave')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.grid(True) # 显示网格
plt.legend() # 显示图例
plt.show() # 显示图表
# 绘制散点图
# plt.scatter(x, y)
# plt.title('Simple Scatter Plot')
# plt.show()
要查看Matplotlib绘制的图表,您需要在支持图形输出的环境中运行代码(如Jupyter Notebook或配置好的IDE)。
通过实践项目来巩固所学知识是最好的学习方法。以下是一些您可以尝试的小型项目想法:
csv或json标准库,或pandas库)。PEP 8 是Python官方推荐的编码风格指南,遵循它可以让您的代码更具可读性和一致性。
snake_case(小写,下划线分隔)CamelCase(驼峰命名,首字母大写)ALL_CAPS(大写,下划线分隔)当程序出现bug时,调试器可以帮助您逐行执行代码,查看变量的值,从而找出问题所在。
pdb(Python Debugger): Python自带的命令行调试器。
import pdb
def buggy_function(a, b):
result = a * b
# pdb.set_trace() # 在这里设置断点
final_result = result + 10 / 0 # 故意制造一个错误
return final_result
# buggy_function(5, 2) # 取消注释并运行,会在 pdb.set_trace() 处暂停
在 pdb 提示符下,常用命令:n (next), s (step into), c (continue), p variable (print variable)。
在处理大量数据或需要高性能的应用时,了解一些基本的性能优化技巧很有帮助。
.join() 方法拼接大量字符串比使用 + 运算符效率更高。过早优化是万恶之源: 在代码能正常工作之前,不要过度关注性能。只有在发现性能瓶颈时,才进行有针对性的优化。
恭喜您学到这里!这只是Python学习的开始,前方还有广阔的天地。
祝您在Python的学习旅程中充满乐趣和成就!不断练习,不断探索,您会发现Python的无限魅力。
持续学习: 编程是一个终身学习的过程。保持好奇心,多动手实践,多阅读优秀的开源代码,多参与社区交流。