1. Python基础
1.1 变量和数据类型
- 变量:用来存储数据的容器。变量名可以是字母、数字和下划线组成,但不能以数字开头。
- 基本数据类型:
- 整数 (int):整数类型,表示正整数和负整数。
- 浮点数 (float):小数类型,表示带有小数点的数值。
- 字符串 (str):文本数据,用引号包围,例如:“Hello”。
- 布尔值 (bool):
True
或False
,用于逻辑判断。
name = "Alice" # 字符串
age = 25 # 整数
height = 5.6 # 浮点数
is_student = True # 布尔值
1.2 基础运算符
- 算术运算符:
+
(加)、-
(减)、*
(乘)、/
(除)、//
(整除)、%
(取余)、**
(幂运算)。 - 比较运算符:
==
(等于)、!=
(不等于)、>
(大于)、<
(小于)、>=
(大于等于)、<=
(小于等于)。 - 逻辑运算符:
and
、or
、not
。
x = 10
y = 3
print(x + y) # 输出: 13
print(x - y) # 输出: 7
print(x * y) # 输出: 30
print(x / y) # 输出: 3.3333...
print(x // y) # 输出: 3 (整除)
print(x % y) # 输出: 1 (取余数)
print(x ** y) # 输出: 1000 (幂运算)
2. 条件判断与循环
2.1 条件判断 (if-elif-else
)
- Python的条件语句用于控制程序的逻辑流,根据条件的真假执行不同的代码块。
- 使用冒号 (
:
) 表示条件语句的开始,并缩进代码块。
age = 20
if age < 18:
print("You are a minor.")
elif age == 18:
print("You just became an adult!")
else:
print("You are an adult.")
2.2 循环 (for
和 while
)
for
循环:用于遍历序列(列表、字符串等)。while
循环:当条件为True
时重复执行代码。
# for 循环
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)
# while 循环
count = 0
while count < 3:
print(f"Count is {count}")
count += 1
3. 函数
3.1 函数定义与调用
- 函数是Python中实现代码重用的一个非常重要的工具。使用
def
关键字定义函数。
# 定义函数
def greet(name):
print(f"Hello, {name}!")
# 调用函数
greet("Alice") # 输出: Hello, Alice!
3.2 带返回值的函数
- 使用
return
语句从函数返回结果。
def add(a, b):
return a + b
result = add(5, 3)
print(result) # 输出: 8
3.3 默认参数与可变长度参数
- 默认参数:在函数定义时为参数提供默认值。
- 可变长度参数:通过
*args
或**kwargs
处理可变数量的参数。
# 默认参数
def greet(name="Guest"):
print(f"Hello, {name}!")
greet() # 输出: Hello, Guest!
greet("Alice") # 输出: Hello, Alice!
# 可变参数
def add_all(*numbers):
total = 0
for number in numbers:
total += number
return total
print(add_all(1, 2, 3, 4)) # 输出: 10
4. 容器
4.1. 列表 (list
)
列表简介
- 列表是Python中最常用的可变序列,可以存储任意类型的对象,并且可以动态改变大小(增删元素)。
- 列表是有序的,允许重复元素。
常用方法和操作
# 创建列表
fruits = ["apple", "banana", "cherry"]
# 访问元素
print(fruits[0]) # 输出: apple
# 添加元素
fruits.append("orange") # 在列表末尾添加
fruits.insert(1, "blueberry") # 在指定位置插入元素
# 删除元素
fruits.remove("banana") # 删除指定元素
popped_item = fruits.pop() # 删除并返回最后一个元素
del fruits[1] # 删除指定位置的元素
# 计数和查找
print(fruits.count("apple")) # 输出: 1 (apple出现的次数)
print(fruits.index("cherry")) # 输出: 1 (cherry的索引位置)
# 排序和反转
fruits.sort() # 按字母顺序排序
fruits.reverse() # 反转列表顺序
# 列表复制
new_fruits = fruits.copy() # 浅拷贝
# 列表连接
fruits += ["grape", "melon"]
# 切片操作
print(fruits[1:3]) # 输出: 从索引1到2的子列表
# 定义两个列表
list1 = [1, 2, 3]
list2 = [4, 5, 6]
# 方法1: 使用 + 运算符
merged_list1 = list1 + list2
# 方法2: 使用 extend() 方法
list1.extend(list2) # 注意这会直接修改 list1
4.2. 元组 (tuple
)
元组简介
- 元组与列表类似,但元组是不可变的,意味着一旦创建就不能修改。
- 元组适用于存储不需要改变的数据。
常用方法和操作
# 创建元组
coordinates = (10, 20)
# 访问元素
print(coordinates[0]) # 输出: 10
# 元组的基本方法
print(coordinates.count(10)) # 输出: 1 (10出现的次数)
print(coordinates.index(20)) # 输出: 1 (20的索引位置)
# 元组不可变,所以不支持修改
# coordinates[0] = 30 # 这将抛出错误
元组解包
# 元组解包
x, y = coordinates
print(x) # 输出: 10
print(y) # 输出: 20
4. 3. 集合 (set
)
集合简介
- 集合是一个无序的、不可重复的元素集合。
- 集合适用于去重、集合运算(交集、并集等)。
常用方法和操作
# 创建集合
fruits_set = {"apple", "banana", "cherry"}
# 添加元素
fruits_set.add("orange")
# 删除元素
fruits_set.remove("banana") # 删除元素,若元素不存在会抛出错误
fruits_set.discard("banana") # 删除元素,若元素不存在不会抛出错误
popped_item = fruits_set.pop() # 随机删除并返回元素
# 集合运算
set1 = {"apple", "banana", "cherry"}
set2 = {"banana", "cherry", "date"}
# 并集
print(set1.union(set2)) # 输出: {'apple', 'date', 'cherry', 'banana'}
# 交集
print(set1.intersection(set2)) # 输出: {'cherry', 'banana'}
# 差集
print(set1.difference(set2)) # 输出: {'apple'}
# 子集与超集
print(set1.issubset(set2)) # 输出: False (set1不是set2的子集)
print(set1.issuperset(set2)) # 输出: False (set1不是set2的超集)
# 清空集合
fruits_set.clear()
去重操作
# 去除列表中的重复元素
numbers = [1, 2, 3, 4, 2, 3, 5]
unique_numbers = list(set(numbers)) # 将列表转换为集合去重,再转换为列表
4.4. 字典 (dict
)
字典简介
- 字典是一种键值对 (
key-value
) 的容器。每个键是唯一的,值可以是任意类型。 - 字典是无序的,在Python 3.7及以后,字典在插入时会保持顺序。
常用方法和操作
# 创建字典
person = {"name": "Alice", "age": 25, "city": "New York"}
# 访问值
print(person["name"]) # 输出: Alice
# 添加或修改键值对
person["job"] = "Engineer" # 添加新键值对
person["age"] = 26 # 修改已有键的值
# 删除键值对
person.pop("city") # 删除指定键并返回它的值
del person["age"] # 删除指定键
# 遍历字典
for key, value in person.items():
print(f"{key}: {value}")
# 获取键、值和键值对
print(person.keys()) # 输出: dict_keys(['name', 'job'])
print(person.values()) # 输出: dict_values(['Alice', 'Engineer'])
print(person.items()) # 输出: dict_items([('name', 'Alice'), ('job', 'Engineer')])
# 使用get方法访问键值,避免键不存在时抛出异常
print(person.get("age", "Unknown")) # 输出: Unknown (因为age键已被删除)
# 合并字典
person.update({"city": "San Francisco", "age": 30}) # 合并新的键值对
4. 5. 字符串 (str
)
字符串简介
- 字符串是Python中的文本容器,不可变。
- 字符串支持许多内置方法,帮助进行文本操作。
常用方法和操作
# 创建字符串
text = "Hello, Python!"
# 访问字符
print(text[0]) # 输出: H
# 字符串方法
print(text.lower()) # 输出: hello, python! (全部转为小写)
print(text.upper()) # 输出: HELLO, PYTHON! (全部转为大写)
print(text.replace("Python", "World")) # 输出: Hello, World! (替换子字符串)
print(text.split(", ")) # 输出: ['Hello', 'Python!'] (按分隔符切分字符串)
# 查找和计数
print(text.find("Python")) # 输出: 7 (返回子字符串的位置)
print(text.count("l")) # 输出: 2 (统计某个字符的出现次数)
# 删除空白
strip_text = " Hello, Python! "
print(strip_text.strip()) # 输出: Hello, Python! (去除两边的空白字符)
字符串格式化
name = "Alice"
age = 25
# 使用 f-string 进行格式化
print(f"My name is {name}, and I am {age} years old.") # 输出: My name is Alice, and I am 25 years old.
# 使用 format 方法
print("My name is {}, and I am {} years old.".format(name, age))
字符串切片
# 字符串切片
print(text[0:5]) # 输出: Hello (切片操作,取索引0到4的字符)
print(text[::-1]) # 输出: !nohtyP ,olleH (反转字符串)
下面是对Python常见容器及其方法的表格形式总结:
容器类型 | 描述 | 常用方法 | 示例 |
---|---|---|---|
列表 (list ) | 可变的有序序列,允许重复 | - append(x) 添加元素- insert(i, x) 在指定位置插入- remove(x) 删除第一个匹配的元素- pop([i]) 删除并返回最后或指定位置的元素- sort() 排序- reverse() 反转顺序- count(x) 统计元素出现次数- index(x) 返回元素的索引 | python fruits = ["apple", "banana"] fruits.append("cherry") |
元组 (tuple ) | 不可变的有序序列,允许重复 | - count(x) 统计元素出现次数- index(x) 返回元素的索引- 元组解包(多个变量赋值) | python coordinates = (10, 20) x, y = coordinates |
集合 (set ) | 无序、不可重复的元素集合 | - add(x) 添加元素- remove(x) 删除元素,不存在则报错- discard(x) 删除元素,不存在不报错- union(set) 并集- intersection(set) 交集- difference(set) 差集- issubset(set) 是否为子集- clear() 清空集合 | python set1 = {"apple", "banana"} set1.add("cherry") |
字典 (dict ) | 键值对的无序集合,键唯一 | - get(key, default) 获取键对应的值- keys() 获取所有键- values() 获取所有值- items() 获取所有键值对- pop(key) 删除并返回指定键的值- update(dict) 合并字典 | python person = {"name": "Alice"} person["age"] = 25 |
字符串 (str ) | 不可变的字符序列 | - lower() 转小写- upper() 转大写- replace(old, new) 替换子字符串- split(sep) 按分隔符切割- find(sub) 查找子字符串位置- count(sub) 统计子字符串出现次数- strip() 去除空白字符 | python text = "Hello" print(text.upper()) |
容器的特点总结:
- 列表:用于可变的、有序的数据存储。
- 元组:适合不可变的、有序数据存储,通常用于需要保护不被修改的数据。
- 集合:无序、元素唯一,适用于去重操作和集合运算。
- 字典:通过键值对进行存储,键唯一,适合快速查找数据。
- 字符串:不可变的字符序列,提供大量文本处理功能。
这个表格总结了每种容器的特性及常用方法,方便对比和理解不同容器的用途。
5. 面向对象编程 (OOP)
5.1 类与对象
- Python支持面向对象编程。类是对象的模板,属性和方法可以封装在类中。
# 定义类
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def bark(self):
print(f"{self.name} is barking!")
# 创建对象
my_dog = Dog("Buddy", 3)
print(my_dog.name) # 输出: Buddy
my_dog.bark() # 输出: Buddy is barking!
5.2 类的继承
- 继承允许新类从已有的类中获取属性和方法。
# 定义父类
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
print(f"{self.name} makes a sound")
# 定义子类
class Dog(Animal):
def speak(self):
print(f"{self.name} barks")
# 创建子类对象
dog = Dog("Buddy")
dog.speak() # 输出: Buddy barks
5.3 抽象类
在Python中,抽象类(Abstract Class)是用来定义接口的类,它不能被实例化,只能被继承。抽象类的主要目的是作为基类,为子类提供结构和约束,强制子类实现某些方法。抽象类通过 abc
模块(Abstract Base Classes)来实现。
抽象类的特点:
- 抽象类不能实例化。
- 抽象类可以包含抽象方法和具体方法。
- 抽象类中的抽象方法必须由子类实现,否则子类也会成为抽象类,无法实例化。
5.3.1. 创建抽象类
Python的 abc
模块提供了创建抽象类的支持。我们需要导入 ABC
类和 abstractmethod
装饰器来创建抽象类和抽象方法。
示例:
from abc import ABC, abstractmethod
# 定义抽象类
class Animal(ABC):
@abstractmethod
def sound(self):
"""抽象方法,子类必须实现"""
pass
# 不能实例化抽象类
# animal = Animal() # 这会抛出错误: TypeError: Can't instantiate abstract class Animal
# 定义子类
class Dog(Animal):
def sound(self):
return "Woof!"
class Cat(Animal):
def sound(self):
return "Meow!"
# 实例化子类
dog = Dog()
print(dog.sound()) # 输出: Woof!
cat = Cat()
print(cat.sound()) # 输出: Meow!
解释:
Animal
类是一个抽象类,它包含一个抽象方法sound()
,该方法没有具体实现。- 子类
Dog
和Cat
继承了Animal
,并且实现了sound()
方法。 - 如果
Dog
或Cat
没有实现sound()
,它们也会被视为抽象类,无法实例化。
5.3.2. 抽象类中的具体方法
抽象类不仅可以包含抽象方法,也可以包含具体的方法。这些方法可以在抽象类中定义并在子类中继承使用。
示例:
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def sound(self):
pass
def move(self):
"""具体方法"""
return "I can move"
class Dog(Animal):
def sound(self):
return "Woof!"
dog = Dog()
print(dog.sound()) # 输出: Woof!
print(dog.move()) # 输出: I can move
解释:
Animal
类中除了抽象方法sound()
外,还有一个具体方法move()
。- 子类
Dog
可以继承并使用move()
方法,而不必重新定义。
5.3.3. 抽象类的实际应用
抽象类常用于为一组相关的类提供接口。例如,在处理不同类型的支付方式时,可以定义一个抽象类 PaymentMethod
,然后让每种支付方式(如 CreditCard
、PayPal
等)继承它,并实现特定的支付逻辑。
示例:
from abc import ABC, abstractmethod
class PaymentMethod(ABC):
@abstractmethod
def pay(self, amount):
"""支付接口,子类必须实现"""
pass
class CreditCard(PaymentMethod):
def pay(self, amount):
return f"Paying {amount} using Credit Card"
class PayPal(PaymentMethod):
def pay(self, amount):
return f"Paying {amount} using PayPal"
# 使用支付方式
cc = CreditCard()
print(cc.pay(100)) # 输出: Paying 100 using Credit Card
pp = PayPal()
print(pp.pay(50)) # 输出: Paying 50 using PayPal
解释:
PaymentMethod
是一个抽象类,它定义了一个抽象方法pay()
。CreditCard
和PayPal
继承了PaymentMethod
并实现了各自的pay()
方法。- 这样可以强制不同的支付方式都有
pay()
方法,并保持支付接口的一致性。
5.3.4. 抽象类的优势
- 代码复用:抽象类可以定义具体方法,供子类继承使用,减少代码重复。
- 代码规范:通过定义抽象方法,抽象类确保子类必须实现某些方法,从而强制实现接口的统一。
- 接口设计:抽象类可以用来定义某一类事物的共同行为,简化代码设计。
总结:
特性 | 描述 |
---|---|
抽象类定义 | 通过继承 ABC 来定义抽象类,不能实例化。 |
抽象方法 | 使用 @abstractmethod 装饰器定义,必须在子类中实现。 |
具体方法 | 抽象类中可以包含具体方法,子类可以继承并使用。 |
实际应用 | 适合用于设计通用接口和强制子类实现特定行为。 |
抽象类在面向对象编程中非常有用,可以有效地帮助我们组织代码,确保子类符合接口规范,同时提供一些通用的功能。
6. 文件操作
6.1 文件读写
- Python可以轻松处理文件的读写操作,使用
open()
函数打开文件,并使用with
语句确保文件在使用后自动关闭。
# 写入文件
with open("example.txt", "w") as file:
file.write("Hello, Python!")
# 读取文件
with open("example.txt", "r") as file:
content = file.read()
print(content) # 输出: Hello, Python!
在Python中,文件的读取和写入是常见的操作,Python提供了内置的函数和方法来轻松实现这些功能。文件操作主要包括打开文件、读取内容、写入内容以及关闭文件。下面是对Python文件操作的总结。
1. 打开文件
open()
函数
- Python 使用
open()
函数来打开文件,返回一个文件对象。open()
函数的语法如下:
open(file, mode='r', encoding=None)
- 参数说明:
file
:文件路径。mode
:文件打开模式(见下表)。encoding
:编码格式(常用utf-8
)。
常见的文件打开模式:
模式 | 描述 |
---|---|
'r' | 以只读模式打开文件(默认模式)。 |
'w' | 以写入模式打开文件,若文件存在则清空文件内容,若文件不存在则创建新文件。 |
'a' | 以追加模式打开文件,写入的数据会附加到文件末尾,文件不存在则创建新文件。 |
'r+' | 以读写模式打开文件,文件必须存在。 |
'b' | 以二进制模式打开文件(可与其他模式组合,如 'rb' )。 |
't' | 以文本模式打开文件(默认模式,可与其他模式组合,如 'rt' )。 |
2. 读取文件
常用的文件读取方法:
方法 | 描述 |
---|---|
read(size=-1) | 读取整个文件内容或指定大小的字符/字节,若 size 为负值,则读取整个文件。 |
readline() | 读取文件的一行,遇到换行符结束。 |
readlines() | 读取文件的所有行并返回一个包含行的列表。 |
读取文件示例
# 打开文件并读取整个内容
with open('example.txt', 'r', encoding='utf-8') as file:
content = file.read() # 读取整个文件
print(content)
# 逐行读取文件
with open('example.txt', 'r', encoding='utf-8') as file:
for line in file:
print(line.strip()) # 打印每一行,strip() 去除换行符
分别读取文件的几种方式:
# 读取指定字符数
with open('example.txt', 'r', encoding='utf-8') as file:
partial_content = file.read(10) # 读取前10个字符
print(partial_content)
# 读取一行
with open('example.txt', 'r', encoding='utf-8') as file:
line = file.readline() # 读取第一行
print(line.strip())
# 读取所有行
with open('example.txt', 'r', encoding='utf-8') as file:
lines = file.readlines() # 返回文件中所有行的列表
for line in lines:
print(line.strip())
读取 JSON 文件
import json
# 假设你有一个名为 data.json 的文件
with open('data.json', 'r', encoding='utf-8') as file:
data = json.load(file)
# 现在 data 变量包含了从文件中解析出来的Python字典或列表
print(data)
import json
# 假设我们有一个名为 multi_line_data.json 的文件,其中每行都是一个独立的JSON对象
data_list = []
with open('multi_line_data.json', 'r', encoding='utf-8') as file:
for line in file:
# 从每一行读取并解析JSON数据
data = json.loads(line.strip())
data_list.append(data)
# 现在 data_list 包含了所有解析过的JSON对象
print(data_list)
3. 写入文件
常用的文件写入方法:
方法 | 描述 |
---|---|
write(string) | 将字符串写入文件。 |
writelines(list) | 将列表中的字符串写入文件,列表中的每个元素应为字符串。 |
写入文件示例
# 写入文件(覆盖模式)
with open('example.txt', 'w', encoding='utf-8') as file:
file.write("Hello, World!\n")
file.write("Python file handling is easy.\n")
# 追加模式
with open('example.txt', 'a', encoding='utf-8') as file:
file.write("This is an additional line.\n")
写入多行
lines = ["First line.\n", "Second line.\n", "Third line.\n"]
# 使用 writelines() 方法写入多行
with open('example.txt', 'w', encoding='utf-8') as file:
file.writelines(lines) # 每个元素代表一行
4. 文件关闭
- 在文件操作完成后,应该关闭文件以释放系统资源。这可以通过调用
close()
方法来完成。 - 使用
with
语句 是管理文件上下文的最佳实践,能够在代码块结束时自动关闭文件。
file = open('example.txt', 'r', encoding='utf-8')
content = file.read()
file.close() # 手动关闭文件
# 更好的方法是使用 with 语句:
with open('example.txt', 'r', encoding='utf-8') as file:
content = file.read() # 自动关闭文件
5. 二进制文件的读写
- 对于图片、音频等非文本文件,使用二进制模式进行读写。
读取二进制文件
# 读取图片文件
with open('image.png', 'rb') as file:
binary_content = file.read()
print(binary_content[:10]) # 读取前10字节
写入二进制文件
# 写入二进制文件
with open('output.bin', 'wb') as file:
file.write(b'\x00\xFF\x10\x20') # 写入字节数据
6. 文件的其他操作
seek()
和 tell()
方法
seek(offset, whence)
:用于移动文件指针到指定位置。offset
:偏移量,表示移动的字节数。whence
:起始位置,0
表示从文件头开始(默认),1
表示从当前位置开始,2
表示从文件末尾开始。
tell()
:返回当前文件指针的位置。
# 文件指针的操作
with open('example.txt', 'r', encoding='utf-8') as file:
print(file.read(5)) # 读取前5个字符
print(file.tell()) # 输出当前文件指针位置(5)
file.seek(0) # 移动到文件开始
print(file.read(5)) # 重新读取前5个字符
文件存在性检查
import os
# 检查文件是否存在
if os.path.exists('example.txt'):
print("File exists.")
else:
print("File does not exist.")
7. 异常处理
在文件操作中,使用异常处理可以确保在文件操作发生错误时能够安全关闭文件。
try:
with open('non_existent_file.txt', 'r', encoding='utf-8') as file:
content = file.read()
except FileNotFoundError:
print("File not found.")
except Exception as e:
print(f"An error occurred: {e}")
8. 总结表格
操作 | 方法 | 描述 |
---|---|---|
打开文件 | open(file, mode, encoding) | 打开文件,并返回文件对象 |
读取文件 | read() , readline() , readlines() | 读取整个文件、一行或所有行 |
写入文件 | write() , writelines() | 写入字符串或字符串列表 |
关闭文件 | close() | 关闭文件,释放资源 |
二进制操作 | rb , wb 模式 | 读取和写入二进制文件 |
文件指针 | seek(offset, whence) | 移动文件指针到指定位置 |
检查文件 | os.path.exists(file) | 检查文件是否存在 |
通过使用这些方法和技巧,Python中的文件操作可以变得非常简单且高效。在实际开发中,建议总是使用 with
语句来自动管理文件的打开和关闭,确保资源得到正确释放。
7. 异常处理
- Python中的异常处理使用
try-except
语句,用于捕获和处理代码运行时的错误。
try:
result = 10 / 0
except ZeroDivisionError:
print("Error: Cannot divide by zero!")
finally:
print("This block always runs.")
8. 常用库
8.1 datetime库
datetime
用于处理日期和时间。
import datetime
now = datetime.datetime.now()
print(now) # 输出当前日期和时间
formatted = now.strftime("%Y-%m-%d %H:%M:%S")
print(formatted) # 输出格式化的日期
8.2 random库
random
用于生成随机数。
import random
# 生成1到10之间的随机整数
print(random.randint(1, 10))
8.3 math库
math
提供了常见的数学函数和常量。
import math
print(math.sqrt(16)) # 输出: 4.0
print(math.pi) # 输出: 3.141592653589793
9. 进阶特性
9.1 列表生成式
- 列表生成式提供了一种简洁的语法,用于基于已有的列表生成新的列表。
squares = [x**2 for x in range(1,
11)]
print(squares) # 输出: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
9.2 装饰器
- 装饰器是修改函数行为的高级技术。
def my_decorator(func):
def wrapper():
print("Before function call")
func()
print("After function call")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
通过这份详细的学习笔记,可以帮助初学者从基础到进阶逐步掌握Python编程语言的核心概念、语法和实战技能。每一个知识点都配有代码示例,便于理解和实践。
9 Python的魔法函数
Python的魔法函数(Magic Methods),也叫特殊方法(Special Methods),是以双下划线开头和结尾的函数,如 __init__()
和 __str__()
。它们允许类具有某些特殊行为,能够重载或实现内置的运算符、内置函数、以及控制类的对象创建、销毁等。
魔法函数非常强大,主要用于类的内部机制,例如运算符重载、属性访问、对象的初始化等。下面是Python魔法函数的详细总结:
1. 对象创建与销毁
__init__(self, ...)
:构造函数
- 描述:当对象创建时调用,用于初始化对象。
- 示例:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
person = Person("Alice", 30) # 自动调用 __init__
__new__(cls, ...)
:实例创建
- 描述:控制实例的创建过程,通常和
__init__
配合使用。 - 示例:
class MyClass:
def __new__(cls):
print("Creating instance")
return super().__new__(cls)
def __init__(self):
print("Initializing instance")
obj = MyClass()
__del__(self)
:析构函数
- 描述:对象被删除或垃圾回收时调用。
- 示例:
class Resource:
def __del__(self):
print("Resource cleaned up")
r = Resource()
del r # 自动调用 __del__
2. 字符串表示与打印
__str__(self)
:用户友好的字符串表示
- 描述:定义对象的“可打印”表示,在使用
print()
或str()
函数时被调用。 - 示例:
class Person:
def __init__(self, name):
self.name = name
def __str__(self):
return f"Person(name={self.name})"
p = Person("Alice")
print(p) # 输出: Person(name=Alice)
__repr__(self)
:正式字符串表示
- 描述:用于调试时的表示,在
repr()
函数或调试器中调用,通常返回一个开发者友好的字符串。 - 示例:
class Person:
def __repr__(self):
return f"Person({self.name!r})"
3. 算术运算符重载
魔法函数 | 描述 | 示例 |
---|---|---|
__add__(self, other) | 实现 + 加法运算符 | a + b |
__sub__(self, other) | 实现 - 减法运算符 | a - b |
__mul__(self, other) | 实现 * 乘法运算符 | a * b |
__truediv__(self, other) | 实现 / 除法运算符 | a / b |
__floordiv__(self, other) | 实现 // 地板除法运算符 | a // b |
__mod__(self, other) | 实现 % 取模运算符 | a % b |
__pow__(self, other) | 实现 ** 幂运算符 | a ** b |
__neg__(self) | 实现一元负号 -a | -a |
示例:
class Number:
def __init__(self, value):
self.value = value
def __add__(self, other):
return Number(self.value + other.value)
def __str__(self):
return str(self.value)
n1 = Number(10)
n2 = Number(20)
print(n1 + n2) # 输出: 30
4. 比较运算符重载
魔法函数 | 描述 | 示例 |
---|---|---|
__eq__(self, other) | 实现 == 相等判断 | a == b |
__ne__(self, other) | 实现 != 不相等判断 | a != b |
__lt__(self, other) | 实现 < 小于判断 | a < b |
__le__(self, other) | 实现 <= 小于等于判断 | a <= b |
__gt__(self, other) | 实现 > 大于判断 | a > b |
__ge__(self, other) | 实现 >= 大于等于判断 | a >= b |
示例:
class Person:
def __init__(self, age):
self.age = age
def __lt__(self, other):
return self.age < other.age
p1 = Person(25)
p2 = Person(30)
print(p1 < p2) # 输出: True
5. 容器类操作
__len__(self)
:对象的长度
- 描述:定义对象在调用
len()
时的行为。 - 示例:
class MyList:
def __init__(self, items):
self.items = items
def __len__(self):
return len(self.items)
lst = MyList([1, 2, 3])
print(len(lst)) # 输出: 3
__getitem__(self, key)
:获取元素
- 描述:定义对象在使用
[]
获取元素时的行为。 - 示例:
class MyList:
def __init__(self, items):
self.items = items
def __getitem__(self, index):
return self.items[index]
lst = MyList([1, 2, 3])
print(lst[0]) # 输出: 1
__setitem__(self, key, value)
:设置元素
- 描述:定义对象在使用
[]
设置元素时的行为。 - 示例:
class MyList:
def __init__(self, items):
self.items = items
def __setitem__(self, index, value):
self.items[index] = value
lst = MyList([1, 2, 3])
lst[1] = 10
print(lst.items) # 输出: [1, 10, 3]
__delitem__(self, key)
:删除元素
- 描述:定义对象在使用
del
关键字删除元素时的行为。 - 示例:
class MyList:
def __init__(self, items):
self.items = items
def __delitem__(self, index):
del self.items[index]
lst = MyList([1, 2, 3])
del lst[1]
print(lst.items) # 输出: [1, 3]
6. 迭代器与生成器
__iter__(self)
:返回迭代器
- 描述:定义对象的迭代行为,通常返回
self
。 - 示例:
class MyRange:
def __init__(self, start, end):
self.current = start
self.end = end
def __iter__(self):
return self
def __next__(self):
if self.current >= self.end:
raise StopIteration
value = self.current
self.current += 1
return value
r = MyRange(1, 5)
for i in r:
print(i) # 输出: 1 2 3 4
7. 上下文管理
__enter__(self)
:进入上下文
- 描述:定义对象在使用
with
语句时进入上下文时的行为。 - 示例:
class Resource:
def __enter__(self):
print("Entering resource")
return self
def __exit__(self, exc_type, exc_value, traceback):
print("Exiting resource")
with Resource():
print("Using resource")
__exit__(self, exc_type, exc_value, traceback)
:退出上下文
- 描述:定义对象在退出
with
上下文时的行为,通常用于清理资源。
8. 调用对象
__call__(self, *args, **kwargs)
:让对象像函数一样调用
- 描述:定义对象在像函数一样被调用时的行为。
- 示例:
class MyFunction:
def __call__(self, x, y):
return x + y
f = MyFunction()
print(f(3, 4)) #
9. __main__
作用
__main__
是一个特殊的名称,当 Python 文件作为脚本直接运行时,Python 解释器将该文件的__name__
设置为__main__
。- 如果该文件被作为模块导入到其他文件中,则
__name__
会被设置为模块的名称,而不是__main__
。
用途
- 常用于区分模块是被直接运行还是被导入。通过使用
if __name__ == '__main__'
语句,可以控制代码块仅在直接执行脚本时运行,而不在导入时执行。
示例:
# script.py
def main():
print("This is the main function.")
if __name__ == '__main__':
main()
- 当你直接运行
script.py
时,输出将是:
This is the main function.
- 但是,如果你在另一个文件中导入
script.py
:
import script
- 输出将什么都没有,因为
main()
只在__name__ == '__main__'
条件满足时执行,而导入时__name__
不是__main__
。
小结
__main__
允许我们编写既可以作为脚本运行,也可以作为模块导入的代码。这样可以确保某些代码仅在脚本直接执行时才会运行,而不会在导入该模块时自动执行。
10. __all__
作用
__all__
是一个模块级变量,用于定义模块中哪些成员可以被其他模块通过from module import *
导入。- 它通常是一个列表,包含模块中应被公开的属性、函数、类等名称。如果没有定义
__all__
,则from module import *
会默认导入所有未以_
开头的对象。
用途
__all__
控制模块的导出接口,明确指定哪些对象应该被导入,避免意外地导入不必要的内部内容。
示例:
# module.py
__all__ = ['func1', 'MyClass']
def func1():
print("This is func1")
def func2():
print("This is func2")
class MyClass:
pass
class MyInternalClass:
pass
- 通过
from module import *
,只有func1
和MyClass
会被导入:
from module import *
func1() # 输出: This is func1
MyClass() # 导入成功
func2() # 会报错,因为 func2 没有包含在 __all__ 中
注意
__all__
只在使用from module import *
时生效。如果使用import module
或from module import specific_name
,__all__
不会影响这些导入方式。
小结
__all__
通过限制模块导出的内容,帮助开发者控制模块的接口,防止不必要的实现细节暴露给外部使用者。
总结
名称 | 作用 | 用途 |
---|---|---|
__main__ | 用于判断代码是被直接运行还是作为模块导入。 | 在脚本直接执行时运行某些代码,而在模块导入时不执行。 |
__all__ | 定义模块中哪些成员可以通过 from module import * 导入。 | 控制模块的导出接口,明确指定哪些对象应该被导入,隐藏内部实现。 |