提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
学习笔记目录
- 前言
- 一、What is Python?
- 二、一些操作方法
- 1. 字符串 切片 下标取值 拼接 格式化
- 2. 字符串 find & count, replace & upper%lower, split & strip
- 3. 传统格式化输出 &F表达式 format进阶
- 4. 列表 长度 更新列表 加法 乘法 切片取值
- 5. 列表 del & append & insert & clear & remove & pop & index & reverse & extend & copy & sort & count
- 6. 元组 - Tuple
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- Stack 类
- 类方法、类实例方法和静态方法
- 实现浅拷贝
- 可变/不可变对象
- 引用计数机制、垃圾回收机制和内存池机制
- 猴子补丁(Monkey Patching)
- Python装饰器
- set函数/ 字典函数
- Lambda函数
- dir() 函数
- filter()方法
- sub()或subn()函数 & match()和search() & re模块和random模块 & PyChecker和Pylint
- 小小总结
- 爬虫(Scrapy),浏览器 request -- 模拟成浏览器 对数据进行解析 简单反爬(header),多任务异步爬虫 多线程 多进程 协程,数据库(MySQL Mongodb redis),面向对象
- 总结
前言
记录下好好学习的日子。
一、What is Python?
- 解释型脚本语言,不太关心底层原理
- 网站开发,机器视觉,数据处理,游戏开发,嵌入式开发
Django, Tornado, Flask框架
(网站开发,小程序开发,平台开发,ERP系统) - Python开发,爬虫开发,数据挖掘,人工智能,自动化测试,自动化运维
- 解释器与编译器
独特的脚本语言,脚本语言优势在于,不需要事先“编译”,可以直接读取文件,一边解释一边执行,也就是说Python不需要像Java/ C++要首先进行编译,再进行运行- 面向对象(每个变量都是一个类,有自己的属性attribute和方法method)
- 语法块(用缩进 四个空格,行首的空格不能随意书写),
- 注释(行内#,行间注释写在两组连续三单引号之间‘‘‘),
- 续行(行尾输入一个反斜杠加一个空格(\ ),再换行,若行尾语法明显未完成(比如以逗号结尾),可以直接续行),
- 打印print(),sep与end参数,输入input(),
- 变量 无需指定变量类型,也不需要提前声明变量,
- 删除变量del(),复制变量 直接赋值,有时仅仅复制一个引用,(如a给b,此后b与a的改动仍会互相影响),必要时通过<span>a is b</span>来判断是否同址
- 模块 通过<span>import pandas<span>的方式加载模块(或<span>import pandas as pd<span>),并用形如<span>pandas.DataFrame<span>(或<span>pd.DataFrame<span>)的方式调用模块内的方法。也可使用<span>from pandas import DataFrame<span>的方式,则在下文可使用<span>DataFrame<span>作为调用名。
- 帮助 配合使用dir()与help()命令,前者是输出变量所有的成员
- Python可一行以;分开显示多条语句
import keyword
print(keyword.kwlist) - \n 换行,\t制表符,\r 覆盖,\b 删除(backspace),\ 两个表示一个,原字符 使转义字符不起作用 r/R
- 变量命名规则 字母 数字 下划线(不可以是关键字)
二、一些操作方法
前情提要
- 不可变数据:Number String Tuple
可变数据:List Dictionary Set - Python3支持int float bool complex
整型 浮点型 布尔型 复数 - 加减乘除,向下取余,取模,幂运算
大于 大于等于 小于 小于等于 不等于 等于 - 布尔值可用and or not运算
- Python的空值 None
内置函数的返回值
1. 字符串 切片 下标取值 拼接 格式化
- 切片 取左不取右 [ : ]整个字符串
- 索引 下标
- 拼接 +,‘,’.join()
- 格式化,format(),’ '.format()
Python进行字符串操作的示例代码,包括字符串切片、下标取值、拼接和格式化。
# 创建一个示例字符串
original_string = "Hello, this is a sample string for string manipulation in Python."
# 字符串切片
substring = original_string[7:21] # 从下标7到21之间的子字符串
print("Substring:", substring)
# 下标取值
first_character = original_string[0] # 获取字符串的第一个字符
last_character = original_string[-1] # 获取字符串的最后一个字符
print("First character:", first_character)
print("Last character:", last_character)
# 字符串拼接
string1 = "This is the first part of a string."
string2 = " And this is the second part of the string."
combined_string = string1 + string2 # 两个字符串拼接
print("Combined string:", combined_string)
# 字符串格式化
name = "Alice"
age = 30
formatted_string = "My name is {} and I am {} years old.".format(name, age)
print("Formatted string:", formatted_string)
这段代码演示了如何使用字符串切片、下标取值、拼接和格式化字符串
2. 字符串 find & count, replace & upper%lower, split & strip
- find:查找元素位置
查找的字符串存在多个则返回第一出现的字符串下标 找不到则返回-1
第一个参数:字符串片段
第二个参数:起始点
第三个参数:终止位置-1 - count:统计字符串片段在字符串中出现的次数
找不到则返回0 - replace:替换指定的字符串片段
第一个参数:要替换的
第二个参数:替换之后的
第三个参数:替换次数(默认从前往后替换所有) - upper%lower:将小写(大写)字母转为大写(小写)字母
- split:指定分割点对字符串分割
第一个参数:分割点
第二个参数:次数(默认找到所有分割点分割) - strip:去除字符串首尾的空格
# 示例字符串
text = "Python is a powerful programming language. Python is versatile."
# 使用find方法查找子字符串在原字符串中的位置
substring = "Python"
index = text.find(substring)
if index != -1:
print(f"'{substring}' found at index {index}")
else:
print(f"'{substring}' not found")
# 使用count方法计算子字符串在原字符串中的出现次数
count = text.count(substring)
print(f"'{substring}' appears {count} times in the text")
# 使用replace方法替换字符串中的子字符串
new_text = text.replace(substring, "Java")
print("Replaced text:", new_text)
# 使用upper和lower方法将字符串转换为大写和小写
upper_text = text.upper()
lower_text = text.lower()
print("Uppercase text:", upper_text)
print("Lowercase text:", lower_text)
# 使用split方法将字符串拆分为单词列表
words = text.split()
print("Words in the text:", words)
# 使用strip方法去除字符串两端的空白字符
text_with_whitespace = " This is a string with whitespace. "
stripped_text = text_with_whitespace.strip()
print("Stripped text:", stripped_text)
这段代码展示了如何执行这些字符串操作
3. 传统格式化输出 &F表达式 format进阶
- 传统格式化输出方法:%
%s:为字符占位,任意类型都可以
%d:为数值类型占位
%f:为浮点数占位 - F表达式(F、f都一样)
len():字符串的长度
format:格式化输出(进阶)
- 格式化小数长度(四舍五入):.2f
- 将小数按百分比形式展示:.2%
# 传统格式化输出方法(%)
name = "John"
age = 25
height = 1.75
# 使用 % 进行格式化
print("Name: %s, Age: %d, Height: %.2f" % (name, age, height))
# F表达式(F、f都一样)
print(f"Name: {name}, Age: {age}, Height: {height:.2f}")
# 进阶的format方法
# 1. 格式化小数长度(四舍五入):.2f
# 2. 将小数按百分比形式展示:.2%
decimal_number = 3.14159
# 使用 format 进行格式化
formatted_decimal = "{:.2f}".format(decimal_number)
print("Formatted Decimal: {}".format(formatted_decimal))
# 将小数按百分比形式展示
percentage_formatted = "{:.2%}".format(decimal_number)
print("Percentage Formatted: {}".format(percentage_formatted))
这个代码演示了如何使用传统的 % 格式化输出方法和新的 F 表达式进行字符串格式化,以及使用 format 方法进行更进一步的格式化,包括控制小数的长度和将小数以百分比形式展示
4. 列表 长度 更新列表 加法 乘法 切片取值
- 列表的长度len()
- 更新列表中的值
- 列表的加法和乘法操作
- 列表的切片取值
# 1. 获取列表的长度使用 len()
my_list = [1, 2, 3, 4, 5]
list_length = len(my_list)
print(f"Length of the list: {list_length}")
# 2. 更新列表中的值
index_to_update = 2
new_value = 10
if 0 <= index_to_update < list_length:
my_list[index_to_update] = new_value
print(f"Updated list: {my_list}")
else:
print(f"Invalid index for update: {index_to_update}")
# 3. 列表的加法和乘法操作
list1 = [1, 2, 3]
list2 = [4, 5, 6]
# 列表加法
result_addition = list1 + list2
print(f"List addition: {result_addition}")
# 列表乘法
scalar = 2
result_multiplication = list1 * scalar
print(f"List multiplication: {result_multiplication}")
# 4. 列表的切片取值
start_index = 1
end_index = 4
sliced_list = my_list[start_index:end_index]
print(f"Sliced list from index {start_index} to {end_index - 1}: {sliced_list}")
5. 列表 del & append & insert & clear & remove & pop & index & reverse & extend & copy & sort & count
- sort函数,用于将列表进行排序。
补:常见ASCII码大小规则,0到9 < A到Z < a到z。 - del关键字
del a:在计算机(内存)当中,a变量定义列表,删除
del a[1]:删除掉列表当中的指定值 - append方法
append函数用于任何向列表末尾添加元素 - insert方法
insert函数用于向列表中插入元素
insert函数的第一个参数是插入的位置,第二个参数是要插入的对象 - clear函数用于将列表清空
- remove函数
用于从列表移除元素(注意:执行结果,若列表中有重复元素,只会移除匹配到的第一个) - pop函数
用于移除列表中指定位置的元素,并返回要移除的元素(在默认情况下,移除列表中最后一个元素) - index函数
用于返回所匹配的元素的索引
该函数的第一个参数是待查找的对象,第二个参数是查找的起始范围,第三个参数是查找的结束范围 - reverse函数
用于将列表反向排列 - extend函数
用于在列表的末尾添加另一个列表
与append函数相比,extend函数可以一次性添加多个元素
注意:
使用extend函数和列表加法的结果是一样的,但是extend西数会将另一个列表并入当前列表
而列表加法是返回新的列表,为节约内存空间,更堆荐使用extend函数来实现大列表的连接操作
- copy函数
用于创建列表的副本 - sort函数
用于将列表进行排序 - count函数
用于统计某个元素在列表中出现的次数
# 定义一个示例列表
my_list = [3, 1, 4, 1, 5, 9, 2, 6, 5]
# 1. 使用 sort 函数对列表进行排序
my_list.sort()
print("Sorted List:", my_list)
# 2. 使用 del 关键字删除列表或列表中的指定元素
del my_list[1] # 删除索引为 1 的元素
print("After deleting index 1:", my_list)
# 3. 使用 append 方法向列表末尾添加元素
my_list.append(7)
print("After appending 7:", my_list)
# 4. 使用 insert 方法在指定位置插入元素
my_list.insert(2, 8) # 在索引为 2 的位置插入元素 8
print("After inserting 8 at index 2:", my_list)
# 5. 使用 clear 方法清空列表
my_list.clear()
print("After clearing the list:", my_list)
# 重新定义示例列表
my_list = [3, 1, 4, 1, 5, 9, 2, 6, 5]
# 6. 使用 remove 方法移除指定元素
my_list.remove(5) # 移除值为 5 的第一个元素
print("After removing first occurrence of 5:", my_list)
# 7. 使用 pop 方法移除指定位置的元素
popped_element = my_list.pop(3) # 移除索引为 3 的元素并返回
print("Popped element:", popped_element)
print("After popping element at index 3:", my_list)
# 8. 使用 index 方法查找元素的索引
index_of_6 = my_list.index(6)
print("Index of 6:", index_of_6)
# 9. 使用 reverse 方法反转列表
my_list.reverse()
print("Reversed List:", my_list)
# 10. 使用 extend 方法将另一个列表添加到当前列表
another_list = [7, 8, 9]
my_list.extend(another_list)
print("After extending with another list:", my_list)
# 11. 使用 copy 方法创建列表副本
copied_list = my_list.copy()
print("Copied List:", copied_list)
# 12. 再次使用 sort 方法对列表进行排序
my_list.sort(reverse=True) # 降序排序
print("Sorted List in descending order:", my_list)
# 13. 使用 count 方法统计某个元素出现的次数
count_of_1 = my_list.count(1)
print("Count of 1:", count_of_1)
6. 元组 - Tuple
与列表类似
创建元组
# Creating a tuple
my_tuple = (1, 2, 3, 'hello', True)
与列表不同
- 元组的元素不能修改
- 元组写在小括号()里
- 元素之间用逗号隔开
- 组中的元素类型可以不相同
# Accessing elements of a tuple
print("Elements of the tuple:")
for item in my_tuple:
print(item)
# Trying to modify a tuple (which is not allowed)
try:
my_tuple[0] = 5 # This will raise an error
except TypeError as e:
print("Error:", e)
# Length of a tuple
print("Length of the tuple:", len(my_tuple))
# Slicing a tuple
print("Slicing the tuple:", my_tuple[1:4])
# Concatenating tuples
tuple1 = (1, 2, 3)
tuple2 = ('a', 'b', 'c')
concatenated_tuple = tuple1 + tuple2
print("Concatenated tuple:", concatenated_tuple)
# Nested tuples
nested_tuple = ((1, 2), (3, 4), (5, 6))
print("Nested tuple:", nested_tuple)
# Unpacking a tuple
a, b, c = (10, 20, 30)
print("Unpacked values:", a, b, c)
# Tuple with single element (note the trailing comma)
single_element_tuple = (5,)
print("Single element tuple:", single_element_tuple)
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
Stack 类
Stack 类实现
该实现基于内置的 list 数据结构,具有常见的栈操作。
class Stack:
def __init__(self):
"""
构造函数,初始化一个空的栈。
"""
self.items = []
def push(self, item):
"""
将元素压入栈顶。
:param item: 待压入的元素
"""
self.items.append(item)
def pop(self):
"""
弹出栈顶的元素,并返回其值。
如果栈为空,抛出 IndexError。
:return: 栈顶元素的值
"""
if not self.is_empty():
return self.items.pop()
else:
raise IndexError("pop from an empty stack")
def peek(self):
"""
返回栈顶的元素值,但不移除元素。
如果栈为空,抛出 IndexError。
:return: 栈顶元素的值
"""
if not self.is_empty():
return self.items[-1]
else:
raise IndexError("peek from an empty stack")
def is_empty(self):
"""
检查栈是否为空。
:return: 如果栈为空则返回 True,否则返回 False
"""
return len(self.items) == 0
def size(self):
"""
返回栈中元素的个数。
:return: 栈中元素的个数
"""
return len(self.items)
# 示例用法:
if __name__ == "__main__":
# 创建一个新的栈
my_stack = Stack()
# 压入一些元素
my_stack.push(5)
my_stack.push(10)
my_stack.push(15)
# 打印栈的大小
print("Stack size:", my_stack.size())
# 查看栈顶元素
print("Top element:", my_stack.peek())
# 弹出栈顶元素
popped_item = my_stack.pop()
print("Popped element:", popped_item)
# 检查栈是否为空
print("Is the stack empty?", my_stack.is_empty())
在栈为空时进行 pop 或 peek 操作会引发 IndexError,这是为了增加代码的健壮性。总体而言,该实现具有 O(1) 的时间复杂度,因为 list 的 append 和 pop 操作都是常数时间的。
类方法、类实例方法和静态方法
类方法(class method)、实例方法(instance method)和静态方法(static method)
当涉及到时,Python提供了三个不同的装饰器:@classmethod、@instancemethod和@staticmethod。
class MyClass:
class_variable = 0 # 类变量
def __init__(self, instance_variable):
self.instance_variable = instance_variable # 实例变量
@classmethod
def class_method(cls):
"""
类方法示例
"""
cls.class_variable += 1
print(f"Class method called. Class variable: {cls.class_variable}")
def instance_method(self):
"""
实例方法示例
"""
self.instance_variable += 1
print(f"Instance method called. Instance variable: {self.instance_variable}")
@staticmethod
def static_method():
"""
静态方法示例
"""
print("Static method called.")
# 创建类实例
obj1 = MyClass(1)
obj2 = MyClass(2)
# 调用类方法
MyClass.class_method() # 输出: Class method called. Class variable: 1
# 调用实例方法
obj1.instance_method() # 输出: Instance method called. Instance variable: 2
# 调用静态方法
MyClass.static_method() # 输出: Static method called.
"""
class_variable: 这是一个类变量,属于整个类而不是类的实例。
类方法可以修改和访问这个变量。
instance_variable: 这是一个实例变量,每个类实例都有自己的副本。
实例方法可以修改和访问这个变量。
@classmethod:
这个装饰器定义了一个类方法,它接受cls参数,表示类本身。
在这个例子中,class_method用于修改和访问类变量。
@instancemethod:
尽管Python中没有专门的@instancemethod装饰器,
但实例方法默认就是这种类型的方法,它接受self参数,表示类的实例。
在这个例子中,instance_method用于修改和访问实例变量。
@staticmethod:
这个装饰器定义了一个静态方法,它不接受类或实例作为参数。
在这个例子中,static_method是一个与类和实例无关的方法。
"""
实现浅拷贝
使用切片操作/ 使用 copy
模块的 copy()
函数/ 使用列表推导式
简单的示例,演示了使用三种不同方法进行浅拷贝的操作。
import copy
# 方法一:使用切片操作
def shallow_copy_with_slice(original_list):
# 切片操作创建新的对象,具有相同的值但不同的内存地址
shallow_copied_list = original_list[:]
return shallow_copied_list
# 方法二:使用copy模块的copy()函数
def shallow_copy_with_copy(original_list):
# 使用copy()函数创建新的对象,具有相同的值但不同的内存地址
shallow_copied_list = copy.copy(original_list)
return shallow_copied_list
# 方法三:使用列表推导式
def shallow_copy_with_list_comprehension(original_list):
# 列表推导式创建新的对象,具有相同的值但不同的内存地址
shallow_copied_list = [x for x in original_list]
return shallow_copied_list
# 示例用法
if __name__ == "__main__":
# 原始列表
original_list = [1, 2, [3, 4], 5]
# 使用切片操作进行浅拷贝
sliced_copy = shallow_copy_with_slice(original_list)
print("Slice Copy:", sliced_copy)
# 使用copy模块的copy()函数进行浅拷贝
copied_with_copy = shallow_copy_with_copy(original_list)
print("Copy with copy():", copied_with_copy)
# 使用列表推导式进行浅拷贝
list_comprehension_copy = shallow_copy_with_list_comprehension(original_list)
print("List Comprehension Copy:", list_comprehension_copy)
# 验证浅拷贝对嵌套对象的影响
original_list[2][0] = 'X'
print("Original List:", original_list)
print("Slice Copy after modification:", sliced_copy)
print("Copy with copy() after modification:", copied_with_copy)
print("List Comprehension Copy after modification:", list_comprehension_copy)
每个浅拷贝方法都被封装成一个函数,并通过对原始列表进行修改来验证浅拷贝对嵌套对象的影响。
需要注意的是,浅拷贝只复制了原对象的顶层元素,如果原对象中包含嵌套对象,则浅拷贝只会复制嵌套对象的引用,而不会复制嵌套对象本身。如果需要复制嵌套对象,则需要使用深拷贝。
可变/不可变对象
不可变对象
bool/ int/ float/ tuple/ str/ frozenset
可变对象
list/ set/ dict
def clear_list(l):
llist = []
llist = [1, 2, 3]
clear_list(llist)
print(llist)
Python可变参数作为默认参数
def flist(llist=[1]):
llist.append(1)
print(llist)
flist()
flist()
Python args **kwargs 函数传递中args **kwargs含义是什么
- 用来处理可变参数
- *args被打包成tuple
- **kwargs被打包成dict
def print_multiple_args(*args):
print(type(args), args)
for idx, val in enumerate(args):
print(idx,val)
print_multiple_args('a', 'b', 'c')
def print_kwargs(**kwargs):
print(type(kwargs), kwargs)
for k, v in kwargs.items():
print('{}: {}'.format(k, v))
print_kwargs(a = 1, b = 2)
def print_all(a, *args, **kwargs):
print(a)
if args:
print(args)
if kwargs:
print(kwargs)
引用计数机制、垃圾回收机制和内存池机制
简单的示例,演示引用计数和垃圾回收的基本概念。
请注意,内存池机制通常是由Python解释器内部处理的,因此我们将着重于引用计数和垃圾回收。
import sys
class Object:
def __init__(self, name):
self.name = name
def __del__(self):
print(f"Deleting {self.name}")
# 创建对象并观察引用计数
obj1 = Object("Object 1")
obj2 = obj1 # 增加引用计数
print(sys.getrefcount(obj1)) # 3,包括函数参数和getrefcount本身的引用
# 手动删除引用,观察引用计数的变化
del obj2
print(sys.getrefcount(obj1)) # 2
# 循环引用示例
obj3 = Object("Object 3")
obj4 = Object("Object 4")
obj3.ref = obj4
obj4.ref = obj3
# 手动断开循环引用
obj3.ref = None
obj4.ref = None
# 引发垃圾回收
import gc
gc.collect()
# 创建循环引用对象,演示垃圾回收机制
obj5 = Object("Object 5")
obj6 = Object("Object 6")
obj5.ref = obj6
obj6.ref = obj5
# 手动断开循环引用
obj5.ref = None
obj6.ref = None
# 引发垃圾回收
gc.collect()
在这个简单的例子中,我们创建了一个Object类,用于模拟Python对象。我们演示了引用计数的基本概念,以及如何手动创建和断开引用,以观察引用计数的变化。然后,我们创建了一个循环引用的情况,并使用gc.collect()手动触发垃圾回收。
简单的示例,演示了Python的垃圾回收系统和内存管理模块的基本用法。
这个示例包括一个函数,该函数创建和使用一些对象,然后演示了垃圾回收的过程。
import gc
def create_objects():
# 创建一些对象
obj1 = [1, 2, 3]
obj2 = {'a': 1, 'b': 2, 'c': 3}
obj3 = 42
# 打印对象的引用计数
print("引用计数(obj1):", gc.get_referrers(obj1))
print("引用计数(obj2):", gc.get_referrers(obj2))
print("引用计数(obj3):", gc.get_referrers(obj3))
# 手动删除引用,以便触发垃圾回收
del obj1
del obj2
del obj3
# 显式调用垃圾回收
gc.collect()
print("垃圾回收后的引用计数(obj1):", gc.get_referrers(obj1))
print("垃圾回收后的引用计数(obj2):", gc.get_referrers(obj2))
print("垃圾回收后的引用计数(obj3):", gc.get_referrers(obj3))
# 主程序
if __name__ == "__main__":
create_objects()
请注意,Python通常能够自动处理大多数内存管理任务,而无需手动介入。在实际应用中,不太需要直接操作引用计数和垃圾回收,除非涉及到特殊情况。
猴子补丁(Monkey Patching)
一种在运行时动态修改类或模块的技术。在Python中,猴子补丁通常用于扩展或修改现有功能而无需修改源代码。
class MyClass:
def original_method(self):
return "Original behavior"
# 定义一个新的方法,用于替换原始方法
def new_method(self):
return "Patched behavior"
# 在运行时动态将新方法绑定到原始方法的位置
MyClass.original_method = new_method
# 创建类的实例并调用原始方法
obj = MyClass()
result = obj.original_method()
print(result) # 输出:Patched behavior
这里定义了一个简单的类MyClass,其中包含一个名为original_method的方法,该方法返回字符串"Original behavior"。
class MyClass:
def original_method(self):
return "Original behavior"
定义了一个新的方法new_method,该方法将替换原始方法的行为,返回字符串"Patched behavior"。
def new_method(self):
return "Patched behavior"
使用猴子补丁,将新方法动态地绑定到类的原始方法位置,从而修改类的行为。
MyClass.original_method = new_method
创建类的实例,并调用原始方法,输出将是修改后的行为"Patched behavior"。
obj = MyClass()
result = obj.original_method()
print(result) # 输出:Patched behavior
实际应用中,需要注意潜在的问题,例如命名冲突、代码可读性降低等。在使用猴子补丁时,确保仔细考虑代码的设计和维护性。
Python装饰器
一个简单的Python装饰器示例,用于记录函数执行时间。
import time
def timing_decorator(func):
"""
装饰器函数,用于记录函数执行时间。
Args:
func (callable): 要装饰的函数。
Returns:
callable: 被装饰后的函数。
"""
def wrapper(*args, **kwargs):
"""
包装函数,添加记录执行时间的功能。
Args:
*args: 函数参数。
**kwargs: 关键字参数。
Returns:
Any: 被装饰函数的返回值。
"""
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
execution_time = end_time - start_time
print(f"{func.__name__} 执行时间: {execution_time:.4f} 秒")
return result
return wrapper
@timing_decorator
def example_function():
"""
示例函数,用于演示装饰器功能。
"""
print("开始执行示例函数")
time.sleep(2)
print("示例函数执行完毕")
# 使用装饰后的函数
example_function()
set函数/ 字典函数
当需要从列表中删除重复元素时,可以使用set函数或字典函数。
set
def remove_duplicates_with_set(input_list):
"""
Remove duplicates from a list using the set function.
Parameters:
- input_list (list): The input list with potential duplicate elements.
Returns:
- list: A new list with duplicates removed.
"""
# Step 1: Create a set from the input list to automatically remove duplicates.
unique_set = set(input_list)
# Step 2: Convert the set back to a list to maintain the original order.
unique_list = list(unique_set)
return unique_list
# Example usage:
a = [1, 2, 4, 2, 4, 5, 6, 5, 7, 8, 9, 0]
result_set = remove_duplicates_with_set(a)
print(result_set)
字典
def remove_duplicates_with_dict(input_list):
"""
Remove duplicates from a list using the dictionary function.
Parameters:
- input_list (list): The input list with potential duplicate elements.
Returns:
- list: A new list with duplicates removed.
"""
# Step 1: Create an empty dictionary.
unique_dict = {}
# Step 2: Use dictionary keys to automatically remove duplicates.
unique_dict = unique_dict.fromkeys(input_list)
# Step 3: Convert the dictionary keys back to a list to maintain the original order.
unique_list = list(unique_dict.keys())
return unique_list
# Example usage:
a = [1, 2, 4, 2, 4, 5, 6, 5, 7, 8, 9, 0]
result_dict = remove_duplicates_with_dict(a)
print(result_dict)
在这两个例子中,时间复杂度主要取决于转换为set或dict的过程,通常为O(n)。
空间复杂度也是O(n),因为需要存储唯一的元素。
选择使用set或dict的主要区别在于是否需要保留原始顺序,因为set会对元素进行排序,而dict则不会。
Lambda函数
lambda函数是一种匿名函数,通常用于需要快速定义单行函数,但又不想费神去命名一个函数的场合。
lambda函数使用关键字lambda后跟一个或多个参数,后面紧跟一个冒号,然后是表达式。表达式的计算结果就是函数的返回值。
# 定义一个lambda函数,输入两个参数a和b,返回它们的和
add = lambda a, b: a + b
# 主程序入口
def main():
try:
# 调用lambda函数
result = add(3, 5)
# 打印结果
print("结果:", result)
except Exception as e:
# 捕捉异常并打印错误信息
print("发生异常:", str(e))
# 判断脚本是否作为主程序执行
if __name__ == "__main__":
# 调用主程序入口
main()
涉及到对象地址、lambda函数、GIL、多线程和多进程的相关内容
import threading
import multiprocessing
# 获取对象地址示例
def get_object_address(obj):
return id(obj)
# lambda函数实现两个数相乘
multiply = lambda a, b: a * b
# 示例使用 lambda 函数
result = multiply(5, 4)
print(f"Lambda function result: {result}")
# GIL示例 - 多线程
def thread_function():
for _ in range(5):
print("Thread running")
# 创建两个线程
thread1 = threading.Thread(target=thread_function)
thread2 = threading.Thread(target=thread_function)
# 启动线程
thread1.start()
thread2.start()
# 等待两个线程结束
thread1.join()
thread2.join()
# GIL示例 - 多进程
def process_function():
for _ in range(5):
print("Process running")
# 创建两个进程
process1 = multiprocessing.Process(target=process_function)
process2 = multiprocessing.Process(target=process_function)
# 启动进程
process1.start()
process2.start()
# 等待两个进程结束
process1.join()
process2.join()
# Python解释器示例
def interpret_code():
code = "print('Hello, World!')"
compiled_code = compile(code, '<string>', 'exec')
exec(compiled_code)
# 执行解释器示例
interpret_code()
包含了对对象地址的获取、lambda函数的使用、GIL的说明、多线程和多进程的示例以及Python解释器的演示。
dir() 函数
函数的作用是返回对象的属性、方法列表。它可以用于查看模块、类、函数等对象的属性和方法。
简单的例子,其中包含了模块、类、函数等不同对象,并使用 dir() 函数查看它们的属性和方法:
# -*- coding: utf-8 -*-
# 模块示例
module_variable = "I am a module variable"
def module_function():
"""
模块中的一个函数
"""
print("I am a module function")
class ModuleClass:
"""
模块中的一个类
"""
class_variable = "I am a class variable"
def __init__(self):
self.instance_variable = "I am an instance variable in ModuleClass"
def instance_method(self):
"""
类中的一个实例方法
"""
print("I am an instance method in ModuleClass")
def main():
# 调用模块中的函数
module_function()
# 创建模块中的类的实例
module_instance = ModuleClass()
# 调用模块中类的实例方法
module_instance.instance_method()
# 使用 dir() 函数查看模块的属性和方法
print("\nAttributes and methods of the module:")
print(dir())
# 使用 dir() 函数查看类的属性和方法
print("\nAttributes and methods of the ModuleClass:")
print(dir(ModuleClass))
# 使用 dir() 函数查看类实例的属性和方法
print("\nAttributes and methods of the module_instance:")
print(dir(module_instance))
if __name__ == "__main__":
main()
"""
模块示例: 包含了一个模块变量、一个模块函数和一个模块类。
类示例: 包含了一个类变量、一个实例变量和一个实例方法。
主函数 main(): 在此函数中,我们演示了如何调用模块的函数、创建类的实例以及调用类的实例方法。
使用 dir() 函数: 我们使用 dir() 函数查看了模块、类以及类实例的属性和方法。
这展示了 dir() 的多用途性,可用于各种对象。
"""
filter()方法
使用Python内置的filter()方法过滤列表
我们定义了一个函数is_even,该函数接受一个数字作为参数,然后返回该数字是否为偶数。接着,我们使用filter()方法将这个函数应用于包含数字的列表,得到一个新的列表,其中包含所有偶数。
def is_even(num):
"""
判断一个数字是否为偶数。
Parameters:
- num (int): 要判断的数字。
Returns:
- bool: 如果数字是偶数,则返回True;否则返回False。
"""
return num % 2 == 0
def filter_even_numbers(numbers):
"""
使用filter()方法过滤列表中的偶数。
Parameters:
- numbers (list): 包含数字的列表。
Returns:
- list: 包含所有偶数的新列表。
"""
even_numbers = list(filter(is_even, numbers))
return even_numbers
# 示例用法
if __name__ == "__main__":
# 定义包含数字的列表
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 使用filter_even_numbers函数过滤偶数
even_numbers = filter_even_numbers(numbers)
# 输出结果
print("原始列表:", numbers)
print("过滤后的偶数列表:", even_numbers)
sub()或subn()函数 & match()和search() & re模块和random模块 & PyChecker和Pylint
简单的示例,演示了使用re模块进行字符串查询和替换,random模块生成随机数,以及PyChecker和Pylint的使用示例。
import re
import random
# 查询和替换文本字符串的方法
def replace_pattern(text, pattern, replacement):
"""
使用re模块中的sub()函数替换字符串中的模式。
Args:
- text (str): 输入文本字符串
- pattern (str): 要替换的模式
- replacement (str): 替换的内容
Returns:
- str: 替换后的文本字符串
"""
result = re.sub(pattern, replacement, text)
return result
# 示例
original_text = "Hello, world! This is an example."
pattern_to_replace = r'\bexample\b' # 匹配单词"example"
replacement_text = "sample"
modified_text = replace_pattern(original_text, pattern_to_replace, replacement_text)
print("Original Text:", original_text)
print("Modified Text:", modified_text)
print("="*50)
# match()和search()的区别
# match()检查字符串开头是否与模式匹配,search()在字符串中搜索模式的第一个匹配值。
def check_match_at_beginning(text, pattern):
"""
使用re模块中的match()函数检查字符串开头是否与模式匹配。
Args:
- text (str): 输入文本字符串
- pattern (str): 要匹配的模式
Returns:
- bool: 是否匹配
"""
result = re.match(pattern, text)
return bool(result)
def find_first_match(text, pattern):
"""
使用re模块中的search()函数在字符串中搜索模式的第一个匹配值。
Args:
- text (str): 输入文本字符串
- pattern (str): 要搜索的模式
Returns:
- str or None: 第一个匹配值,如果没有找到则返回None
"""
result = re.search(pattern, text)
return result.group() if result else None
# 示例
pattern_to_match = r'^Hello' # 匹配以"Hello"开头的字符串
pattern_to_search = r'world' # 在字符串中搜索"world"
print("Match at beginning:", check_match_at_beginning(original_text, pattern_to_match))
print("First match:", find_first_match(original_text, pattern_to_search))
print("="*50)
# 随机数生成的方法
def generate_random_number(start, end):
"""
使用random模块生成指定范围内的随机整数。
Args:
- start (int): 随机数范围的起始值
- end (int): 随机数范围的结束值
Returns:
- int: 生成的随机整数
"""
result = random.randint(start, end)
return result
# 示例
random_number = generate_random_number(1, 100)
print("Random Number:", random_number)
print("="*50)
# PyChecker和Pylint的使用示例
# 请确保安装了PyChecker和Pylint模块
# PyChecker的使用
# 命令行运行: pychecker your_script.py
# Pylint的使用
# 命令行运行: pylint your_script.py
# 或者使用VSCode等集成开发环境中的插件
# 注意:PyChecker和Pylint的具体使用可能需要根据实际项目配置进行调整。
小小总结
未编号内容小结
# Python内存管理
# 对象的引用计数机制
# 引用计数增加
x = 42 # x引用了整数对象42
y = x # y也引用了同一个对象
# 引用计数减少
del x # x不再引用对象
y = 17 # y引用了另一个对象
# 垃圾回收机制
# Python使用垃圾回收器在运行时自动释放不再使用的对象
# 无需手动释放内存,但循环引用可能导致内存泄漏
# 内存池机制
# Python使用内存池来管理小型对象,提高内存分配效率
# 对象池存储并重复使用小型对象,减少内存碎片化
# Lambda函数
# 匿名函数,用于短小的回调函数
# 示例:将列表中的偶数加倍
numbers = [1, 2, 3, 4, 5]
doubled = list(map(lambda x: x * 2 if x % 2 == 0 else x, numbers))
print(doubled)
# Python中tuple和list的转换
# 使用tuple()和list()函数
# 转换为tuple
my_list = [1, 2, 3]
my_tuple = tuple(my_list)
# 转换为list
my_tuple = (4, 5, 6)
my_list = list(my_tuple)
# 删除list中重复元素的方法
# 使用set()函数或字典去重
# 使用set函数
my_list = [1, 2, 2, 3, 4, 4, 5]
unique_list = list(set(my_list))
# 使用字典函数
my_list = [1, 2, 2, 3, 4, 4, 5]
unique_list = list(dict.fromkeys(my_list))
# Python中拷贝对象的方法
# 赋值、浅拷贝、深拷贝
# 赋值
original_list = [1, 2, 3]
copied_list = original_list
# 浅拷贝
import copy
original_list = [1, [2, 3], 4]
copied_list = copy.copy(original_list)
# 深拷贝
deep_copied_list = copy.deepcopy(original_list)
# Python中except用法和作用
# 捕获异常并执行相应的语句
try:
result = 10 / 0
except ZeroDivisionError:
print("Error: Cannot divide by zero")
except Exception as e:
print(f"An unexpected error occurred: {e}")
else:
print("Division successful")
# Python中pass语句的作用
# 作为占位符或创建占位程序
def placeholder_function():
pass
# 用于创建一个没有具体实现的函数,防止出现语法错误
# 或者用于创建一个占位的代码块
if condition:
pass
# 避免空的if语句导致语法错误
经典小题
寻找第二大数
def find_second_largest(nums):
"""
寻找数组中的第二大数
参数:
nums (list): 包含整数的列表
返回:
int: 数组中的第二大数
"""
# 确保数组长度大于等于2
if len(nums) < 2:
return "数组长度不足"
# 初始化最大值和第二大值
largest = second_largest = float('-inf')
# 遍历数组
for num in nums:
if num > largest:
# 当前元素大于最大值,更新最大值和第二大值
second_largest = largest
largest = num
elif largest > num > second_largest:
# 当前元素大于第二大值但小于最大值,更新第二大值
second_largest = num
# 返回第二大值
return second_largest
# 示例数组
num_list = [34, 11, 23, 56, 78, 0, 9, 12, 3, 7, 5]
# 寻找第二大数并输出
result = find_second_largest(num_list)
print("数组中的第二大数是:", result)
"""
使用更具描述性的函数名和变量名,增强代码可读性。
添加函数注释,描述函数的目的、输入参数和返回值。
使用float('-inf')初始化最大值和第二大值,以处理数组中可能存在负数的情况。
增加对数组长度小于2的检查,确保数组中有足够的元素。
使用for num in nums简化遍历过程,提高代码简洁性。
在条件语句中添加对第二大值的更新条件,确保在最大值和第二大值相等时不会出现错误。
返回第二大值而不是直接打印,以增强函数的灵活性。
"""
统计一段字符串中字符出现次数
def count_char_occurrences(input_str):
"""
Count the occurrences of each character in the input string.
Args:
- input_str (str): The input string for character counting.
Returns:
- dict: A dictionary where keys are characters and values are their occurrences.
"""
char_count_dict = {} # Initialize an empty dictionary to store character occurrences.
for char in input_str:
# Using get() method to safely retrieve the value for a character,
# and default to 0 if the character is not already in the dictionary.
char_count_dict[char] = char_count_dict.get(char, 0) + 1
return char_count_dict
def format_char_count(char_count_dict):
"""
Format the character count dictionary into a string.
Args:
- char_count_dict (dict): Dictionary with character occurrences.
Returns:
- str: Formatted string representing character counts.
"""
formatted_str = ""
for char, count in char_count_dict.items():
# Concatenate each character and its count to the result string.
formatted_str += char + str(count)
return formatted_str
# Example usage:
input_str = "AAABBCCAC"
char_count_dict = count_char_occurrences(input_str)
formatted_result = format_char_count(char_count_dict)
# Print the result.
print(formatted_result)
"""
函数解释:
count_char_occurrences: 该函数接受一个字符串参数,返回一个字典,记录了字符串中每个字符的出现次数。
format_char_count: 该函数接受一个字符计数的字典,并返回一个格式化的字符串,表示每个字符及其出现次数。
算法分析:
使用一个字典 char_count_dict 来存储每个字符的出现次数。
遍历输入字符串,对于每个字符,使用 get() 方法安全地获取字典中的值,并将其加1。
最后,将字典转换为格式化的字符串。
函数和变量名使用小写字母和下划线,符合Python的命名约定。
代码缩进符合PEP 8规范,增强了代码的可读性。
"""
时间复杂度: 遍历输入字符串,时间复杂度为O(n),其中 n 是输入字符串的长度。
空间复杂度: 使用了一个字典来存储字符的出现次数,空间复杂度为O©,其中 c 是字符集的大小。在这个例子中,由于字符集通常比较小,因此空间复杂度可以视为常数级别。
爬虫(Scrapy),浏览器 request – 模拟成浏览器 对数据进行解析 简单反爬(header),多任务异步爬虫 多线程 多进程 协程,数据库(MySQL Mongodb redis),面向对象
X selenium X
网页加载全过程 Devtools
(html内容和数据进行融合)
NetWork抓包,Preserve log,All Fetch/XHR JS CSS Img,url:Headers Payload Preview Response Initiator Timing Cookies
服务器端渲染
输入域名,服务器组装html内容,返回给浏览器html页面源代码
客户端渲染
第一次访问返回一个html结构,html的内容和数据进行融合是发生在浏览器上的
(这个过程一般通过脚本来完成JS)
99% — 页面源代码 XHR JS
Elements,永远不要相信Elements(实时效果)
xpath bs re,所有解析都不要以Elements为准,以页面源代码或者response.txt为准
总结
汇总主要的操作方法,记录下好好学习Python的日子。