python入门(一)个人笔记
简单区分
数据结构 | 主要用途 | 可变性 | 典型场景 | 例子 |
---|---|---|---|---|
字典 (dict) | 键值对映射 | 可变 | 快速查找、配置信息 | {"name": "Alice", "age": 25} |
集合 (set) | 唯一元素存储、集合运算 | 可变 | 去重、成员检查 | {1, 2, 3, 4} |
列表 (list) | 动态有序序列 | 可变 | 数据收集、临时存储 | [1, 2, 3, 4, 5] |
元组 (tuple) | 不可变有序序列 | 不可变 | 字典键、函数返回值、常量 | (1, 2, 3) |
Python 推导式
>数据类型 | 推导式类型 | 语法格式 |
---|---|---|
列表 [] | 列表推导式 | [表达式 for 元素 in 可迭代对象] |
带条件的列表推导式 | [表达式 for 元素 in 可迭代对象 if 条件] | |
嵌套循环的列表推导式 | [表达式 for 元素1 in 可迭代对象1 for 元素2 in 可迭代对象2] | |
字典{} | 字典推导式 | {键表达式: 值表达式 for 元素 in 可迭代对象} |
带条件的字典推导式 | {键表达式: 值表达式 for 元素 in 可迭代对象 if 条件} | |
集合{} | 集合推导式 | {表达式 for 元素 in 可迭代对象} |
带条件的集合推导式 | {表达式 for 元素 in 可迭代对象 if 条件} | |
生成器() | 生成器表达式 | (表达式 for 元素 in 可迭代对象) |
带条件的生成器表达式 | (表达式 for 元素 in 可迭代对象 if 条件) |
迭代器与生成器
它们都用于实现迭代(逐个访问元素)
相关概念
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。当所有元素被访问完继续向前访问时会报错。
生成器就是特殊的迭代器。
- 普通迭代器:
- 通常由容器类型(如列表 list、元组 tuple、集合 set、字典 dict)直接提供。
- 通过实现 iter() 和 next() 方法(例如自定义迭代器类)来支持迭代。
- 特殊迭代器:
- 是一种特殊的迭代器,通过函数 + yield 关键字或生成器表达式(如 (x for x in range(5)))创建。
加深理解
使用场景
- 处理大文件:逐行读取文件,避免一次性加载整个文件。从而节省内存。
- 生成无限序列:生成器非常适合生成无限序列。生成斐波那契数列、素数序列等。
- 数据流处理:在处理数据流时,生成器可以逐个处理数据,避免一次性加载所有数据,从而提高效率。
- 管道式数据处理:生成器可以用于构建管道式的数据处理流程,每个生成器负责一个处理步骤,数据在生成器之间逐个传递。
- 延迟计算:生成器是惰性的,只有在需要时才会计算下一个值。这使得生成器非常适合延迟计算,节省计算资源。
- 简化代码逻辑:生成器的语法简洁,使用yield关键字实现复杂的迭代逻辑。
- 内存优化:生成器可以逐个生成值,避免一次性将所有数据加载到内存中,从而节省内存。
- 自定义迭代逻辑:通过实现__iter__()和__next__()方法自定义迭代顺序。
函数
类型属于对象,对象有不同类型的区分,变量是没有类型的
这句话描述了 Python 的动态类型系统(Dynamic Typing)的核心特性。
- 类型属于对象(Types belong to objects)
在 Python 中,数据的类型是绑定在对象(Object)本身上的,而不是绑定在变量(Variable)上。
对象:Python 中一切皆对象(如整数 42、字符串 "hello"、列表 [1, 2, 3] 等)。
类型信息:每个对象内部会存储自己的类型(如 int、str、list)。
a = 42 # 对象 42 的类型是 int
b = "hello" # 对象 "hello" 的类型是 str
- 变量是没有类型的(Variables are untyped)
Python 的变量本质上是对象的引用(Reference),它只是一个名字(Name),可以随时绑定到任何类型的对象上。
变量本身没有类型:它只是指向某个对象的标签。
动态绑定:同一个变量可以先后指向不同类型的对象。
x = 42 # x 绑定到 int 类型的对象
x = "hello" # 现在 x 绑定到 str 类型的对象
x = [1, 2] # 现在 x 绑定到 list 类型的对象
- 对象有不同类型的区分(Objects have distinct types)
Python 的对象类型是严格区分的,不同类型的对象支持不同的操作。
类型决定行为:对象的类型决定了它能做什么(如 + 对数字是加法,对字符串是拼接)。
运行时类型检查:操作是否合法由对象的类型决定(而非变量)。
a = 5
b = "hello"
print(a + b) # 报错!int 和 str 不能直接相加
可变和不可变对象
不可变对象类型:
int(整数)、float(浮点数)、bool(布尔值)、str(字符串)、tuple(元组)、frozenset(不可变集合)、bytes(字节串)
可变对象类型:
list(列表)、dict(字典)、set(集合)、bytearray(可变字节数组)
lambda【匿名】 函数
- lambda 函数是一种小型、匿名的、内联函数,它可以具有任意数量的参数,但只能有一个表达式。
- lambda 函数通常用于编写简单的、单行的函数,通常在需要函数作为参数传递的情况下使用,例如在 map()、filter()、reduce() 等函数中。
装饰器
装饰器是一种非常强大的功能,它允许你在不修改原始函数代码的情况下,动态地为函数添加新的功能。装饰器本质上是一个返回函数的高阶函数,它接收一个函数作为参数,并返回一个新的函数。
装饰器的作用
- 增强函数功能:
在不修改原始函数代码的情况下,为函数添加额外的功能。例如,日志记录、性能测试、权限验证、缓存等。 - 代码复用:
将重复的逻辑封装到装饰器中,避免在多个函数中重复编写相同的代码。 - 解耦:
将核心业务逻辑与辅助功能分离,使代码更加清晰、易于维护。
举例说明
函数
import functools
def log_decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
print(f"调用函数 {func.__name__},参数为:{args}, {kwargs}")
result = func(*args, **kwargs)
print(f"函数 {func.__name__} 返回值为:{result}")
return result
return wrapper
@log_decorator
def add(a, b):
return a + b
result = add(3, 4)
输出
调用函数 add,参数为:(3, 4), {}
函数 add 返回值为:7
- log_decorator 是一个装饰器函数,它接收一个函数 func 作为参数</font。
- wrapper是装饰器内部定义的一个嵌套函数,它包装了原始函数 func。
- @functools.wraps(func)是一个内置的装饰器,用于保留原始函数的元信息(如函数名、文档字符串等)。如果不使用它,wrapper 函数会覆盖原始函数的元信息。
- wrapper 函数的逻辑:
-1.打印调用函数的信息,包括函数名和传入的参数。
-2.调用原始函数 func,并将结果存储在变量 result 中。
-3.打印函数的返回值。
-4.返回原始函数的返回值。
类
def my_decorator(cls):
class Wrapper:
def __init__(self, *args, **kwargs):
self.wrapped = cls(*args, **kwargs)
def display(self):
print("在类方法之前执行")
self.wrapped.display()
print("在类方法之后执行")
return Wrapper
@my_decorator
class MyClass:
def display(self):
print("这是 MyClass 的 display 方法")
obj = MyClass()
obj.display()
除了函数装饰器,Python 还支持类装饰器。类装饰器是包含 call 方法的类,它接受一个函数作为参数,并返回一个新的函数。
这里既然聊到了类,那就说一下类相关的知识。
如何定义类:
1.使用关键字class关键字定义类
2.使用init初始化类的实例
3.自定义其他方法
#使用 class 关键字定义类。使用首字母大写。
class MyClass:
#构造函数 __init__ 用于初始化类的实例,它接受一个参数 name 并将其存储在实例变量 self.name 中。
def __init__(self, name):
self.name = name
#方法 greet 用于打印一条问候信息,它使用了实例变量 self.name。
def greet(self):
print(f"Hello, {self.name}!")
如何使用写好的类
1.创建类的实例
2.调用实例方法
obj = MyClass("Alice")
obj.greet()