信步漫谈之Python———入门


语法

  • 数据结构
    • 元组tuple:不可变、有序、可重复
    • 列表list:可变、有序、可重复
    • 字典range:可变、无序、键不可重复
    • 集合set:可变、无序、不可重复
    • 冻结集合frozenset:不可变、无序、不可重复
  • 工具
    • del:可以按索引而不是按值从一个列表移除条目,或清空整个列表
    • passpass 是一个空操作语句,当语法上需要语句但不需要执行任何代码时使用。
    • range:生成不可变的数字序列
    • match:模式匹配(增强的 switch-case,python中没有switch)
    • ...(Ellipsis):可以用作代码中的占位符,表示“这里还有代码,但暂时没有写”。也可以在切片中表示“所有元素”。或在类型注解中,... 用于表示可变参数。

特殊值

  • None:表示空值或无值。
  • TrueFalse:表示布尔值,分别表示真和假。
  • 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
posted @ 2025-09-01 19:02  临渊启明  阅读(11)  评论(0)    收藏  举报