1. 语言基础
1.1 数据类型与变量
Python 是一门动态类型语言,这意味着你不需要显式声明变量的类型。Python 解释器会根据你赋予变量的值自动推断其类型。这使得 Python 代码简洁易懂,但同时也需要注意一些潜在的问题。
1.1.1 Python 数据类型概述
Python 提供了多种内置数据类型,以下是一些常见的类型:
-
数值类型:
- 整型 (int):用于表示整数,例如 10, -5, 0
- 浮点型 (float):用于表示小数,例如 3.14, -2.5, 0.0
- 复数类型 (complex):用于表示复数,例如 2+3j
- 字符串类型 (str):用于表示文本,例如 “Hello world!”, “Python”
-
布尔类型 (bool):用于表示真假,只有
True
和False
两种值 -
列表类型 (list):有序可变序列,用方括号
[]
包裹,元素之间用逗号,
分隔 -
元组类型 (tuple):有序不可变序列,用圆括号
()
包裹,元素之间用逗号,
分隔 -
字典类型 (dict):无序可变键值对集合,用花括号
{}
包裹,键值对之间用冒号:
分隔
1.1.2 变量声明与赋值
在 Python 中,使用 =
符号来给变量赋值。
name = "Alice"
age = 25
is_student = True
需要注意的是,变量名必须以字母或下划线开头,后面可以跟字母、数字或下划线。同时,Python 变量名区分大小写。
1.1.3 类型转换
有时我们需要将不同数据类型之间进行转换,Python 提供了一些内置函数来实现类型转换:
-
int()
:将其他数据类型转换为整型 -
float()
:将其他数据类型转换为浮点型 -
str()
:将其他数据类型转换为字符串类型 -
bool()
:将其他数据类型转换为布尔类型
例如:
number = "10"
int_number = int(number) # 将字符串转换为整型
1.2 运算符与表达式
运算符是用来对操作数执行特定操作的符号,表达式则是由操作数和运算符组合而成的计算公式。
1.2.1 算术运算符
算术运算符用于进行数值计算,包括:
运算符 | 描述 | 示例 | 结果 |
---|---|---|---|
+ | 加法 | 10 + 5 | 15 |
- | 减法 | 10 - 5 | 5 |
* | 乘法 | 10 * 5 | 50 |
/ | 除法 | 10 / 5 | 2.0 |
// | 整数除法 | 10 // 5 | 2 |
% | 取余 | 10 % 5 | 0 |
** | 幂运算 | 10 ** 2 | 100 |
1.2.2 比较运算符
比较运算符用于比较两个操作数的大小或是否相等,结果为布尔值(True 或 False)。
运算符 | 描述 | 示例 | 结果 |
---|---|---|---|
== | 等于 | 10 == 5 | False |
!= | 不等于 | 10 != 5 | True |
> | 大于 | 10 > 5 | True |
< | 小于 | 10 < 5 | False |
>= | 大于等于 | 10 >= 5 | True |
<= | 小于等于 | 10 <= 5 | False |
1.2.3 逻辑运算符
逻辑运算符用于对布尔值进行操作,包括:
运算符 | 描述 | 示例 | 结果 |
---|---|---|---|
and | 逻辑与 | True and True | True |
or | 逻辑或 | True or False | True |
not | 逻辑非 | not True | False |
1.2.4 位运算符
位运算符用于对操作数的二进制位进行操作,包括:
运算符 | 描述 | 示例 | 结果 |
---|---|---|---|
& | 按位与 | 10 & 5 | 0 |
| | 按位或 | 10 | 5 | 15 |
^ | 按位异或 | 10 ^ 5 | 15 |
~ | 按位取反 | ~10 | -11 |
<< | 左移 | 10 << 2 | 40 |
>> | 右移 | 10 >> 2 | 2 |
1.2.5 赋值运算符
赋值运算符用于将值赋给变量,包括:
运算符 | 描述 | 示例 | 等价于 |
---|---|---|---|
= | 赋值 | x = 10 | x = 10 |
+= | 加法赋值 | x += 5 | x = x + 5 |
-= | 减法赋值 | x -= 5 | x = x - 5 |
*= | 乘法赋值 | x *= 5 | x = x * 5 |
/= | 除法赋值 | x /= 5 | x = x / 5 |
//= | 整数除法赋值 | x //= 5 | x = x // 5 |
%= | 取余赋值 | x %= 5 | x = x % 5 |
**= | 幂运算赋值 | x **= 5 | x = x ** 5 |
&= | 按位与赋值 | x &= 5 | x = x & 5 |
|= | 按位或赋值 | x |= 5 | x = x | 5 |
^= | 按位异或赋值 | x ^= 5 | x = x ^ 5 |
<<= | 左移赋值 | x <<= 5 | x = x << 5 |
>>= | 右移赋值 | x >>= 5 | x = x >> 5 |
1.2.6 运算符优先级
在表达式中,不同的运算符具有不同的优先级。优先级高的运算符先执行,优先级低的运算符后执行。可以使用括号 ()
来改变运算顺序,括号内的表达式优先执行。
以下列出了一些常用运算符的优先级,从高到低排序:
-
幂运算
**
-
按位取反
~
-
乘法、除法、整数除法、取余
*
,/
,//
,%
-
加法、减法
+
,-
-
位运算
<<
,>>
,&
,^
,|
-
比较运算符
==
,!=
,>
,<
,>=
,<=
-
逻辑运算符
not
,and
,or
-
赋值运算符
=
,+=
,-=
,*=
,/=
,//=
等等
1.2.7 表达式
表达式是由操作数和运算符组合而成的计算公式, Python 解释器会根据运算符的优先级和结合性来计算表达式的值。
例如:
-
10 + 5 * 2
:由于乘法运算符优先级高于加法运算符,所以先执行5 * 2
,得到结果 10,然后再执行10 + 10
,最终结果为 20。 -
(10 + 5) * 2
:由于括号内的表达式优先执行,所以先执行10 + 5
,得到结果 15,然后再执行15 * 2
,最终结果为 30。
1.3 控制流语句
控制流语句允许我们控制程序执行的流程,改变程序的执行顺序。它们使程序能够根据条件做出决策,重复执行代码块,以及在需要时跳出循环。
1.3.1 条件语句 (if-elif-else)
条件语句根据条件判断,选择执行不同的代码块。
语法:
if 条件1:
代码块1
elif 条件2:
代码块2
else:
代码块3
- if: 如果条件1为真,则执行代码块1。
- elif: 如果条件1为假,则判断条件2,如果条件2为真,则执行代码块2。可以有多个 elif 语句。
- else: 如果所有条件都为假,则执行代码块3。else 语句是可选的。
示例:
score = int(input("请输入分数:"))
if score >= 90:
print("优秀")
elif score >= 80:
print("良好")
elif score >= 70:
print("中等")
else:
print("不及格")
1.3.2 循环语句 (for, while)
循环语句用于重复执行一段代码,直到满足特定条件为止。
for 循环
for 循环用于遍历序列 (例如列表、元组、字符串) 中的每个元素。
语法:
for 变量 in 序列:
代码块
- 变量: 用于保存当前迭代的元素值。
- 序列: 需要遍历的序列。
示例:
names = ["Alice", "Bob", "Charlie"]
for name in names:
print("Hello, " + name)
while 循环
while 循环会一直执行代码块,直到条件变为假。
语法:
while 条件:
代码块
- 条件: 循环的判断条件。
示例:
count = 0
while count < 5:
print(count)
count += 1
1.3.3 循环控制语句 (break, continue)
循环控制语句用于在循环中改变执行流程。
break 语句
break 语句用于立即退出循环。
示例:
for i in range(10):
if i == 5:
break
print(i)
continue 语句
continue 语句用于跳过当前迭代,继续执行下一轮循环。
示例:
for i in range(10):
if i % 2 == 0:
continue
print(i)
1.4 函数
函数是 Python 代码的模块化单元,它可以接受输入参数,执行一系列操作,并返回结果。函数可以提高代码的可重用性和可读性,使程序更加模块化和易于维护。
1.4.1 函数定义与调用
函数定义:
def 函数名(参数列表):
"""函数文档字符串"""
代码块
return 返回值
- def: 定义函数的关键字。
- 函数名: 函数的名称,必须以字母或下划线开头,可以包含字母、数字和下划线。
- 参数列表: 函数接受的参数列表,多个参数用逗号隔开。
- 函数文档字符串: 描述函数功能的字符串,可以使用三引号包裹。
- 代码块: 函数体,包含要执行的代码。
- return: 返回函数的结果,可以省略,此时函数返回 None。
函数调用:
函数名(参数列表)
- 函数名: 要调用的函数名称。
- 参数列表: 传递给函数的参数,顺序和类型要与函数定义中的参数列表一致。
示例:
def greet(name):
"""向用户问好"""
print("Hello, " + name + "!")
greet("Alice") # 调用 greet 函数,传递参数 "Alice"
1.4.2 函数参数与返回值
参数:
- 位置参数: 按顺序传递的参数,调用函数时参数的顺序要与函数定义中的参数顺序一致。
- 关键字参数: 使用参数名和参数值对的形式传递参数,可以改变参数的顺序。
- 默认参数: 函数定义中为参数指定默认值,如果调用函数时未提供该参数,则使用默认值。
- 可变参数: 使用 *args 来接收任意数量的位置参数,这些参数会被打包成一个元组。
- 关键字可变参数: 使用 **kwargs 来接收任意数量的关键字参数,这些参数会被打包成一个字典。
返回值:
- 函数可以使用 return 语句返回值,返回值可以是任何类型的值,包括数字、字符串、列表、字典等。
- 如果函数没有 return 语句,则默认返回 None。
示例:
def calculate_sum(a, b=10): # b 为默认参数,默认值为 10
"""计算两个数的和"""
return a + b
result = calculate_sum(5) # 调用函数,传递一个参数,使用 b 的默认值
print(result) # 输出 15
result = calculate_sum(5, 20) # 调用函数,传递两个参数,覆盖 b 的默认值
print(result) # 输出 25
def sum_all(*args): # 使用 *args 接收任意数量的位置参数
"""计算所有参数的和"""
total = 0
for arg in args:
total += arg
return total
result = sum_all(1, 2, 3, 4, 5) # 传递多个参数
print(result) # 输出 15
1.4.3 递归函数
递归函数是指在函数内部调用自身的函数。
示例:
def factorial(n):
"""计算 n 的阶乘"""
if n == 0:
return 1
else:
return n * factorial(n - 1)
result = factorial(5)
print(result) # 输出 120
注意: 递归函数必须有一个终止条件,否则会无限递归下去导致程序崩溃。
1.4.4 匿名函数 (lambda)
匿名函数是指没有名称的函数,使用 lambda 关键字定义。
语法:
lambda 参数列表: 表达式
- lambda: 定义匿名函数的关键字。
- 参数列表: 函数的参数列表。
- 表达式: 函数体,只能包含一个表达式,返回值为该表达式的结果。
示例:
square = lambda x: x * x
print(square(5)) # 输出 25
add = lambda x, y: x + y
print(add(10, 20)) # 输出 30
注意: 匿名函数通常用于简化代码,尤其是在需要使用函数作为参数或返回值的情况下。
2. 数据结构
数据结构是组织和存储数据的特定方式,在编程中扮演着至关重要的角色。Python 提供了多种内置数据结构,让我们可以方便地管理数据。
2.1 列表 (List)
列表是一种有序的可变数据结构,可以存储不同类型的元素。
2.1.1 列表创建与访问
-
创建列表: 使用方括号
[]
包含元素,元素之间用逗号,
分隔。my_list = [1, 2, 3, "hello", True]
-
访问元素: 使用索引访问列表中的元素,索引从 0 开始。
print(my_list[0]) # 输出: 1 print(my_list[3]) # 输出: hello
-
负索引: 负索引从列表末尾开始计数,-1 代表最后一个元素,-2 代表倒数第二个元素,以此类推。
print(my_list[-1]) # 输出: True print(my_list[-3]) # 输出: 3
2.1.2 列表操作 (添加、删除、修改)
-
添加元素:
-
append(x)
: 在列表末尾添加元素。 -
insert(i, x)
: 在指定索引i
处插入元素x
。 -
extend(iterable)
: 将可迭代对象的所有元素添加到列表末尾。
my_list.append(4) my_list.insert(1, "world") my_list.extend([5, 6]) print(my_list) # 输出: [1, 'world', 2, 3, 'hello', True, 4, 5, 6]
-
-
删除元素:
-
remove(x)
: 删除第一个值为x
的元素。 -
pop(i)
: 删除指定索引i
处的元素,并返回该元素的值。 -
del list[i]
或del list[i:j]
: 删除指定索引或切片范围内的元素。
my_list.remove("hello") removed_item = my_list.pop(2) del my_list[0:2] print(my_list) # 输出: [3, True, 4, 5, 6]
-
-
修改元素: 使用索引直接修改元素的值。
my_list[0] = "new_value" print(my_list) # 输出: ['new_value', True, 4, 5, 6]
2.1.3 列表遍历
-
使用 for 循环遍历:
for item in my_list: print(item)
-
使用索引遍历:
for i in range(len(my_list)): print(my_list[i])
2.2 元组 (Tuple)
元组是一种有序的不可变数据结构,使用圆括号 ()
包含元素。
2.2.1 元组创建与访问
-
创建元组: 使用圆括号
()
包含元素,元素之间用逗号,
分隔。my_tuple = (1, 2, "hello", True)
-
访问元素: 使用索引访问元组中的元素,索引从 0 开始。
print(my_tuple[0]) # 输出: 1 print(my_tuple[2]) # 输出: hello
-
负索引: 负索引从元组末尾开始计数,-1 代表最后一个元素,-2 代表倒数第二个元素,以此类推。
print(my_tuple[-1]) # 输出: True print(my_tuple[-3]) # 输出: 2
2.2.2 元组不可变性
元组是不可变的,这意味着一旦创建,就不能修改其元素。
my_tuple[0] = "new_value" # 会导致错误
2.2.3 元组与列表的区别
特性 | 列表 | 元组 |
---|---|---|
可变性 | 可变 | 不可变 |
括号 | [] |
() |
使用场景 | 存储需要修改的数据 | 存储不需要修改的数据 |
- 列表适合存储需要频繁添加、删除、修改元素的数据。
- 元组适合存储不需要修改的数据,例如存储常量、坐标等。
2.3 字典 (Dictionary)
字典是一种无序的键值对集合,使用花括号 {}
包含键值对,键和值之间用冒号 :
分隔,键值对之间用逗号 ,
分隔。
2.3.1 字典创建与访问
-
创建字典: 使用花括号
{}
包含键值对。my_dict = {"name": "John", "age": 30, "city": "New York"}
-
访问元素: 使用键访问字典中的值。
print(my_dict["name"]) # 输出: John print(my_dict["age"]) # 输出: 30
-
不存在的键: 访问不存在的键会导致
KeyError
错误。print(my_dict["hobby"]) # 抛出 KeyError
-
使用
get()
方法访问:get()
方法可以安全地访问键,如果键不存在,则返回None
或指定的值。print(my_dict.get("hobby")) # 输出: None print(my_dict.get("hobby", "unknown")) # 输出: unknown
2.3.2 字典操作 (添加、删除、修改)
-
添加元素: 使用新的键和值直接赋值。
my_dict["hobby"] = "reading" print(my_dict) # 输出: {'name': 'John', 'age': 30, 'city': 'New York', 'hobby': 'reading'}
-
删除元素:
-
del dict[key]
: 删除指定键的键值对。 -
pop(key)
: 删除指定键的键值对,并返回该键对应的值。
del my_dict["city"] print(my_dict) # 输出: {'name': 'John', 'age': 30, 'hobby': 'reading'} city = my_dict.pop("hobby") print(my_dict) # 输出: {'name': 'John', 'age': 30} print(city) # 输出: reading
-
-
修改元素: 使用键直接修改值。
my_dict["age"] = 31 print(my_dict) # 输出: {'name': 'John', 'age': 31, 'hobby': 'reading'}
2.3.3 字典遍历
-
遍历键: 使用
for key in dict.keys()
遍历字典的所有键。for key in my_dict.keys(): print(key) # 输出: name, age, hobby
-
遍历值: 使用
for value in dict.values()
遍历字典的所有值。for value in my_dict.values(): print(value) # 输出: John, 31, reading
-
遍历键值对: 使用
for key, value in dict.items()
遍历字典的所有键值对。for key, value in my_dict.items(): print(f"{key}: {value}") # 输出: name: John, age: 31, hobby: reading
2.4 集合 (Set)
集合是一种无序的、不可重复的元素集合,使用花括号 {}
包含元素,元素之间用逗号 ,
分隔。
2.4.1 集合创建与访问
-
创建集合: 使用花括号
{}
包含元素。
注意:空集合必须使用set()
函数创建。my_set = {1, 2, 3, 4} empty_set = set()
-
访问元素: 集合是无序的,无法通过索引访问元素。可以判断元素是否存在于集合中:
print(1 in my_set) # 输出: True print(5 in my_set) # 输出: False
2.4.2 集合操作 (交集、并集、差集)
-
交集: 使用
&
或intersection()
方法求两个集合的交集。set1 = {1, 2, 3} set2 = {2, 3, 4} intersection_set = set1 & set2 print(intersection_set) # 输出: {2, 3}
-
并集: 使用
|
或union()
方法求两个集合的并集。union_set = set1 | set2 print(union_set) # 输出: {1, 2, 3, 4}
-
差集: 使用
-
或difference()
方法求两个集合的差集。difference_set = set1 - set2 print(difference_set) # 输出: {1}
2.4.3 集合的不可重复性
集合中的元素是唯一的,不允许重复。
my_set = {1, 2, 2, 3}
print(my_set) # 输出: {1, 2, 3}
3. 面向对象编程
面向对象编程 (OOP) 是一种编程范式,它将程序视为一组相互作用的对象,每个对象都包含数据和操作这些数据的函数。OOP 帮助组织和管理大型程序,使其更容易维护和扩展。
3.1 类与对象
3.1.1 类定义
-
类 是对象的蓝图,它定义了对象的属性和方法。
-
在 Python 中,使用
class
关键字定义类,后面跟着类名和冒号:class Dog: # 类体
-
类体包含了类的属性和方法的定义。
3.1.2 对象创建
-
对象 是类的实例,它拥有类定义的属性和方法。
-
在 Python 中,使用类名和括号创建对象:
my_dog = Dog()
-
这行代码创建了一个名为
my_dog
的Dog
类对象。
3.1.3 属性与方法
-
属性 是对象的特征,通常用变量表示。
-
方法 是对象的行为,通常用函数表示。
class Dog: def __init__(self, name, breed): self.name = name self.breed = breed def bark(self): print(f"{self.name} barks!")
-
__init__
方法是构造函数,用于初始化对象属性。 -
self
参数表示当前对象,用于访问对象的属性和方法。 -
bark
方法定义了狗叫的行为。
3.1.3 实例化和调用类的方法
class Dog:
def __init__(self, name, breed):
self.name = name
self.breed = breed
def bark(self):
print(f"{self.name} barks!")
my_dog = Dog("Buddy", "Golden Retriever")
print(f"My dog's name is {my_dog.name} and it's a {my_dog.breed}.")
my_dog.bark()
3.2 封装
封装是面向对象编程中的一个重要概念,它将数据和操作数据的方法捆绑在一起,形成一个独立的、自包含的单元,即对象。封装的目标是隐藏对象的内部实现细节,只对外暴露必要的接口,以控制对对象的访问。
3.2.1 类
类是封装的核心概念,它定义了对象的属性和方法。属性表示对象的特征,方法表示对象的行为。
class Dog:
def __init__(self, name, breed):
self.name = name
self.breed = breed
def bark(self):
print("Woof!")
my_dog = Dog("Buddy", "Golden Retriever")
print(my_dog.name) # 输出:Buddy
my_dog.bark() # 输出:Woof!
3.2.2 私有属性和方法
- 使用双下划线
__
开头的属性和方法被认为是私有的,只能在类内部访问。 - 私有属性和方法有助于隐藏实现细节,防止外部代码误操作。
class Dog:
def __init__(self, name, breed):
self.name = name
self.__breed = breed # 私有属性
def bark(self):
print("Woof!")
def __private_method(self): # 私有方法
print("This is a private method.")
my_dog = Dog("Buddy", "Golden Retriever")
print(my_dog.name) # 可以访问公有属性
# print(my_dog.__breed) # AttributeError: private access
my_dog.bark() # 可以调用公有方法
# my_dog.__private_method() # AttributeError: private access
注意: 虽然 Python 的私有机制是通过名称改写来实现的,仍然可以通过一些技巧来访问私有属性和方法。例如,使用 _ClassName__attribute_name
或者 _ClassName__method_name
可以访问私有属性和方法。
# 通过名称改写访问私有属性
print(my_dog._Dog__breed) # 输出:Golden Retriever
# 通过名称改写访问私有方法
my_dog._Dog__private_method() # 输出:This is a private method.
3.2.3 属性装饰器
- Python 中可以使用
@property
装饰器将方法转换为属性,允许开发者通过类似访问属性的方式来调用方法。 - 同时,可以使用
@name.setter
和@name.deleter
装饰器来定义属性的 setter 和 deleter 方法,分别用于设置和删除属性的值。 - 使用属性装饰器可以更方便地控制对属性的访问,并隐藏内部实现细节。
class Dog:
def __init__(self, name, breed):
self._name = name
self._breed = breed
@property
def name(self):
return self._name
@name.setter
def name(self, value):
self._name = value
@name.deleter
def name(self):
del self._name
my_dog = Dog("Buddy", "Golden Retriever")
print(my_dog.name) # 输出:Buddy
my_dog.name = "Max"
print(my_dog.name) # 输出:Max
del my_dog.name
# print(my_dog.name) # AttributeError: 'Dog' object has no attribute 'name'