信步漫谈之Python———入门
语法
- 数据结构
- 元组
tuple:不可变、有序、可重复 - 列表
list:可变、有序、可重复 - 字典
range:可变、无序、键不可重复 - 集合
set:可变、无序、不可重复 - 冻结集合
frozenset:不可变、无序、不可重复
- 元组
- 工具
del:可以按索引而不是按值从一个列表移除条目,或清空整个列表pass:pass是一个空操作语句,当语法上需要语句但不需要执行任何代码时使用。range:生成不可变的数字序列match:模式匹配(增强的 switch-case,python中没有switch)...(Ellipsis):可以用作代码中的占位符,表示“这里还有代码,但暂时没有写”。也可以在切片中表示“所有元素”。或在类型注解中,...用于表示可变参数。
特殊值
None:表示空值或无值。True和False:表示布尔值,分别表示真和假。NotImplemented:用于表示某个操作没有被实现。它主要用于比较操作和算术操作中,当操作没有被定义时返回NotImplemented,而不是直接抛出异常。__debug__:表示当前是否处于调试模式。在调试模式下,__debug__的值为True,否则为False。__name__:表示当前模块的名称。如果模块是主程序运行,__name__的值为"__main__"__file__:表示当前模块的文件路径。__package__:表示当前模块所属的包名称。
魔法方法(双下划线开头)
__init__:用于设置对象的初始状态,即在创建对象时初始化对象的属性。它接收的第一个参数总是self,表示对象本身,后面可以跟其他参数__str__:返回对象的字符串表示,用于print函数。__repr__:返回对象的官方字符串表示,通常用于调试。__len__:返回对象的长度,用于len()函数。__getitem__和__setitem__:用于实现对象的索引操作。__call__:使对象可以像函数一样被调用。__eq__,__ne__,__lt__,__le__,__gt__,__ge__:实现对象的比较操作。__add__,__sub__,__mul__,__truediv__:实现对象的算术运算。__enter__和__exit__:实现上下文管理协议,通常用于with语句。__iter__和__next__:实现迭代器协议。__getattr__和__setattr__:自定义属性访问和设置行为。
知识点
- List 的 append() 和 extend() 的区别?
- append 添加的是单个元素,extend添加的是集合
- a, b = 10, 20
- 这种写法其实右侧就是一个元组,等同于 a, b = (10, 20)
__name__是一个内置的特殊变量,它的值取决于Python文件是如何被运行的- 当文件被直接运行时:
__name__的值为__main__ - 当文件被导入时:
__name__的值为文件名
- 当文件被直接运行时:
mro()方法:用于获取一个类的方法解析顺序(Method Resolution Order)。这个顺序决定了当调用一个方法时,Python会按照什么顺序在父类中查找该方法。- 抽象基类:继承
ABC类,并使用abstractmethod装饰器定义抽象方法。子类必须实现所有抽象方法,否则会报错。 - 动态类型:鸭子类型,它的核心思想是:“如果它看起来像鸭子,游起来像鸭子,叫起来也像鸭子,那么它就可以被称为鸭子。”换句话说,一个对象的有效性是由它当前的行为(方法和属性)决定的,而不是由它的类型决定的。
解包(Unpacking)
解包是 Python 中的一种语法特性,允许将一个可迭代对象(如元组、列表、字典等)的元素分配给多个变量。解包可以用于赋值、函数参数传递等场景。
# 基本形式
# var1, var2, ...:变量列表。
# iterable:可迭代对象,其元素数量必须与变量数量一致。
var1, var2, ... = iterable
# 元组解包
a, b = (1, 2)
print(a, b) # 输出:1 2
# 列表解包
c, d = [3, 4]
print(c, d) # 输出:3 4
# 字典解包
e, f = {'x': 5, 'y': 6}.values() # 如果用keys(),则输出键的信息
print(e, f) # 输出:5 6
# 字典键值对的解包
d = {'a': 1, 'b': 2, 'c': 3}
items = d.items()
(k1, v1), (k2, v2), (k3, v3) = items
print(k1, v1, k2, v2, k3, v3) # 输出:a 1 b 2 c 3
* 和 ** 是用于解包的特殊符号,它们在函数调用、参数传递、列表和字典操作中都有特定的用途。
简单的说:* 针对可迭代对象操作(列表或元组),**针对字典操作。
*的使用规则
# 在函数调用中,* 用于将可迭代对象(如列表、元组等)解包为位置参数。
# args 是一个元组(11, 12)。使用 *args 将元组解包为两个位置参数 x 和 y,然后传递给函数 func
def func(x, y):
print(x, y)
args = (11, 12)
func(*args) # 输出:11 12
# 在列表或元组中,* 用于捕获多余的元素。
a, *b, c = [1, 2, 3, 4, 5]
print(a, b, c) # 输出:1 [2, 3, 4] 5
**的使用规则
# 在函数调用中,** 用于将字典解包为关键字参数。
# kwargs 是一个字典 {'x': 11, 'y': 12}。使用 **kwargs 将字典解包为关键字参数 x=11 和 y=12,然后传递给函数 func。
def func(x, y):
print(x, y)
kwargs = {'x': 11, 'y': 12}
func(**kwargs) # 输出:11 12
# 在字典中,** 用于合并多个字典。
d1 = {'a': 1, 'b': 2}
d2 = {'c': 3, 'd': 4}
d3 = {**d1, **d2}
print(d3) # 输出:{'a': 1, 'b': 2, 'c': 3, 'd': 4}
*和**的混合使用
# *args 将元组 (11, 12, 13, 14) 解包为位置参数 a=11, b=12, args=(13, 14)。
# **kwargs 将字典 {'x': 15, 'y': 16} 解包为关键字参数 kwargs={'x': 15, 'y': 16}。
def func(a, b, *args, **kwargs):
print(a, b, args, kwargs)
args = (11, 12, 13, 14)
kwargs = {'x': 15, 'y': 16}
func(*args, **kwargs) # 输出:11 12 (13, 14) {'x': 15, 'y': 16}
生成器表达式
生成器表达式是一种简洁的语法,用于创建生成器。其基本形式如下
# expression:生成的值。
# variable:迭代变量。
# iterable:可迭代对象。
# condition:可选的条件表达式,用于过滤。
(expression for variable in iterable if condition)
# 示例
# expression 是 `(i, j)`,表示生成一个元组 `(i, j)`。
# variable 是 `i` 和 `j`,分别从 `range(3)` 中取值。
# iterable 是 `range(3)`,用于生成 `i` 和 `j` 的值。
# condition 是 `if self.board[i][j] == 0`,用于过滤满足条件的 `(i, j)`。
self.board = [
[1, 2, 3],
[4, 0, 6],
[7, 8, 9]
]
(i, j) for i in range(3) for j in range(3) if self.board[i][j] == 0
# 输出:这个生成器表达式会生成所有满足 `self.board[i][j] == 0` 的 `(i, j)` 值为:(1, 1)
语法范例
######################## 变量与数据类型
# 基本数据类型
name = "Alice" # 字符串 (str)
age = 30 # 整数 (int)
price = 19.99 # 浮点数 (float)
is_student = True # 布尔值 (bool)
# 容器类型
fruits = ["apple", "banana", "cherry"] # 列表 (List) - 有序,可变
coordinates = (10, 20) # 元组 (Tuple) - 有序,不可变
unique_numbers = {1, 2, 3} # 集合 (Set) - 无序,不重复
person = {"name": "Bob", "age": 25} # 字典 (Dictionary) - 键值对
# 空值
nothing = None # NoneType 类型,表示空
######################## 基础运算符
# 算术运算符
a = 10 + 5 # 加
b = 10 - 5 # 减
c = 10 * 5 # 乘
d = 10 / 5 # 除 (结果为浮点数 2.0)
e = 10 // 3 # 整除 (结果为整数 3)
f = 10 % 3 # 取模 (求余数,结果为 1)
g = 2 ** 3 # 幂运算 (2的3次方,结果为 8)
# 比较运算符
result = (10 > 5) # True
result = (10 == 10) # True
result = (10 != 5) # True
# 逻辑运算符
result = (True and False) # False (与)
result = (True or False) # True (或)
result = (not True) # False (非)
# 身份运算符 (检查是否为同一个对象)
a = [1, 2]
b = [1, 2]
c = a
print(a is b) # False,值相同但不是同一个对象
print(a is c) # True,是同一个对象
######################## 流程控制
score = 85
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B" # 这里会执行
elif score >= 70:
grade = "C"
else:
grade = "D"
print(grade) # 输出 B
# for 循环遍历序列
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(f"I like {fruit}")
# 使用 range() 函数
for i in range(5): # 从0循环到4
print(i)
# while 循环
count = 5
while count > 0:
print(count)
count -= 1 # 重要:确保循环条件最终会变为False,避免无限循环
# 循环控制 (break, continue)
for i in range(10):
if i == 3:
continue # 跳过本次循环的剩余代码,直接进入下一次循环
if i == 7:
break # 立即退出整个循环
print(i)
# 输出: 0, 1, 2, 4, 5, 6
######################## 函数定义
# 定义一个简单的函数
def greet(name):
"""这是一个问候函数(文档字符串)"""
return f"Hello, {name}!"
message = greet("World")
print(message) # 输出: Hello, World!
# 带默认参数的函数
def introduce(name, age=30): # age 有默认值
print(f"My name is {name}, I'm {age} years old.")
introduce("Alice") # 使用默认age: 30
introduce("Bob", 25) # 提供age参数: 25
# 关键字参数 (调用时指定参数名,顺序无关)
introduce(age=25, name="Bob")
######################## 异常处理
try:
# 尝试执行可能会出错的代码
num = int(input("请输入一个数字: "))
result = 10 / num
print(f"结果是: {result}")
except ValueError:
# 处理值错误(例如输入的不是数字)
print("错误:请输入一个有效的数字!")
except ZeroDivisionError:
# 处理除零错误
print("错误:不能除以零!")
except Exception as e:
# 捕获所有其他未知异常
print(f"发生了一个未知错误: {e}")
finally:
# 无论是否发生异常,finally 块中的代码都会执行
print("程序执行完毕。")
######################## 文件操作
# 写入文件
with open('example.txt', 'w', encoding='utf-8') as file:
file.write("Hello, World!\n")
file.write("这是第二行。")
# 文件在这里会自动关闭
# 读取文件
with open('example.txt', 'r', encoding='utf-8') as file:
content = file.read() # 读取全部内容
# lines = file.readlines() # 按行读取,返回一个列表
print(content)
######################## 面向对象编程
class Dog:
# 类属性 (所有实例共享)
species = "Canis familiaris"
# 初始化方法 (构造函数)
def __init__(self, name, age):
# 实例属性 (每个实例独有)
self.name = name
self.age = age
# 实例方法
def bark(self):
return f"{self.name} says: Woof!"
def get_info(self):
return f"{self.name} is {self.age} years old."
# 创建类的实例 (对象)
my_dog = Dog("Buddy", 5)
# 访问属性和调用方法
print(my_dog.name) # 输出: Buddy
print(my_dog.bark()) # 输出: Buddy says: Woof!
print(my_dog.get_info()) # 输出: Buddy is 5 years old.
######################## 列表、字典、集合推导式
# 列表推导式 (List Comprehension)
numbers = [1, 2, 3, 4, 5]
squared = [x**2 for x in numbers] # [1, 4, 9, 16, 25]
even_squared = [x**2 for x in numbers if x % 2 == 0] # [4, 16]
# 字典推导式 (Dictionary Comprehension)
names = ['Alice', 'Bob']
name_lengths = {name: len(name) for name in names} # {'Alice': 5, 'Bob': 3}
# 集合推导式 (Set Comprehension)
numbers_with_duplicates = [1, 2, 2, 3, 4, 4]
unique_squares = {x**2 for x in numbers_with_duplicates} # {1, 4, 9, 16}
######################## pass与 `...`(Ellipsis)的区别
# pass - 空语句
def func1():
pass # 完全空的操作
# ... - Ellipsis对象,常用于NumPy等库
def func2():
... # 也是一个占位符,但实际上是Ellipsis对象
print(type(pass)) # 语法错误,pass不是对象
print(type(...)) # <class 'ellipsis'>
######################## match使用
match subject:
case pattern1:
# 处理 pattern1
case pattern2:
# 处理 pattern2
case _:
# 默认情况
######################## ...(Ellipsis)使用
def my_function():
...
# 这里可以添加更多的代码
import numpy as np
array = np.array([[1, 2, 3], [4, 5, 6]])
print(array[..., 0]) # 在这里,... 表示“所有行”,0 表示第一列。
from typing import Any, Callable
def my_function(*args: Any, **kwargs: Any) -> None:
...
# ... 表示函数体的具体实现尚未提供。
魔法方法范例
class Adder:
def __init__(self, num):
self.num = num
def __call__(self, x):
return self.num + x
adder = Adder(5)
print(adder(3)) # 输出: 8
##########################################
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __eq__(self, other):
if isinstance(other, Person):
return self.name == other.name and self.age == other.age
return False
def __lt__(self, other):
if isinstance(other, Person):
return self.age < other.age
return NotImplemented
person1 = Person("Alice", 30)
person2 = Person("Alice", 30)
person3 = Person("Bob", 25)
print(person1 == person2) # 输出: True
print(person1 < person3) # 输出: False
##########################################
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
if isinstance(other, Vector):
return Vector(self.x + other.x, self.y + other.y)
return NotImplemented
def __sub__(self, other):
if isinstance(other, Vector):
return Vector(self.x - other.x, self.y - other.y)
return NotImplemented
v1 = Vector(2, 3)
v2 = Vector(5, 7)
v3 = v1 + v2
v4 = v1 - v2
print(v3.x, v3.y) # 输出: 7 10
print(v4.x, v4.y) # 输出: -3 -4
##########################################
class Person:
def __init__(self, name):
self.name = name
def __getattr__(self, item):
if item == "age":
return 30
raise AttributeError(f"{item} not found")
def __setattr__(self, key, value):
if key == "name":
super().__setattr__(key, value)
else:
raise AttributeError(f"Cannot set attribute {key}")
person = Person("Alice")
print(person.name) # 输出: Alice
print(person.age) # 输出: 30
try:
person.age = 25
except AttributeError as e:
print(e) # 输出: Cannot set attribute age

浙公网安备 33010602011771号