一、基础语法(必考,筛人)
1.Python是解释型语言吗?
是。python通常由解释器执行源码或字节码,不像C/C++那样提前编译成机器码。
但是这不代表python没有编译过程。.py文件通常会先编译成字节码,再由python虚拟机执行。
2. == 和 is 的区别
== 是比较值是否相同。
is 是比较内存地址是否相同(是否是同一个对象)。
a = [1, 2]
b = [1, 2]
print(a == b)
print(a is b)
c = 256
d = 256
print(c is d) # True,小整数缓存
c = 257
d = 257
print(c is d) # 不一定,看解释器实现
输出:
True
False
True
False
解释:
虽然 a 和 b 的值是一样的,但是它们是两个不同的列表对象。
3.可变对象和不可变对象,举例说明
不可变:tuple, float, int, frozenset, str。修改本质上是创建新对象。
可变:list, dict, set。原地修改,内存地址不变。
a = [1, 2, 3]
a.append(4)
print(a)
s = "ab"
s += "c"
print(s)
输出:
[1,2,3,4]
abc
注意:字符串看似被修改了,实际上是创建了一个新的字符串对象。
4.python中可哈希和不可哈希是啥意思?
在python中,一个对象能否被哈希,直接决定了它能否当dict的键或存入集合。
一个对象如果同时满足两个条件,那它就是可哈希的:
1.有__hash__()方法,能算出一个固定的哈希值(一个整数)。
2.有__eq__()方法,可以和其他对象比较是否相等。
并且要遵守一个铁律:
如果 a==b, 那么 hash(a) == hash(b) 必然成立。
总结:python中内置的不可变数据类型,基本上都可哈希。
在python中,可变类型通常不可哈希的。它们要么根本没有__hash__()方法,要么直接设为None, 强行哈希会抛出TypeError。
# hash() 能够执行成功就是可哈希
hash("test") #成功
hash([1,2,3]) #TypeError
hash((1,2)) #成功
5.为啥列表不能作为字典Key?
因为列表是可变数据类型,这就意味着它不可哈希,无法作为字典dict的Key。
6.python中的变量需要声明类型吗?
不需要。python是动态类型语言,变量名只是对象的引用。
动态类型语言:指变量的类型是在程序运行的时候才确定的,写代码时不用你提前声明。
常见的静态类型语言:Java,C++。
常见的动态类型语言:Python、Javascript。
7.深拷贝和浅拷贝
拷贝会创建一个新的对象。
浅拷贝只复制对象本身,内部嵌套的引用还是指向原对象。也就是说:外壳是新的,里面到的东西还是原来的。总之:浅拷贝会创建一个新的复合对象,但是内部嵌套的子对象,只复制了引用,不会递归复制。
import copy
a = [1, 2, [3, 4]]
b = copy.copy(a) # 浅拷贝
# 检查对象
print(a is b) # False,外层是新对象
# 修改不可变元素(没有嵌套问题)
b[0] = 10
print(a) # [1, 2, [3, 4]] –>不变
print(b) # [10, 2, [3, 4]]
# 修改嵌套的可变子对象
b[2][0] = 100
print(a) # [1, 2, [100, 4]] –>跟着变了
print(b) # [1, 2, [100, 4]]
深拷贝递归复制所有嵌套对象。新旧对象之间完全独立,互补影响。
import copy
a = [1, 2, [3, 4]]
b = copy.deepcopy(a)
# 修改嵌套子对象
b[2][0] = 100
print(a) # [1,2,[3,4]]
print(b) # [1,2,[100,4]]
# a 和 b完全独立了
| 赋值 b = a | ❌ | ❌ |
| 浅拷贝 copy.copy(a) | ✅ | ❌ |
| 深拷贝 copy.deepcopy(a) | ✅ | ✅ |
8.列表推导式
什么是列表推导式?
一种简洁、优雅创建列表的语法。
# 基本语法
result = []
for i in range(10):
if i % 2 == 0:
result.append(i * i)
# 列表推导式
result = [i * i for i in range(10) if i % 2 == 0] # 结果:[0, 4, 16, 36, 64]
result = [i if i % 2 == 0 else -i for i in range(10)] # 注意:if-else要放在 for 前面
9.字符串如何反转?(算法题)
我们先讲讲什么是切片?切片是序列所共有的特性,字符串切片就是从字符串中提取出一部分(子串)的过程。
基本语法
字符串[起始位置:结束位置:步长]
三个参数都是可选的,用冒号分隔:
| 起始位置 | 从哪个索引开始取(包含) | 步长为正时默认 0,步长为负时默认 -1 |
| 结束位置 | 取到哪个索引为止(不包含) | 步长为正时默认末尾,步长为负时默认开头 |
| 步长 | 每次移动几个索引,正数向右走,负数向左走 | 1 |
# 实现字符串的反转
s = "python"
print(s[::-1])
10.字符串拼接为什么会推荐选join?
循环中频繁使用 + 拼接字符串,会产生多个中间字符串对象。
大量字符串拼接时,推荐使用 join()。
words = ["python", "is", "my", "main", "language"]
print(" ".join(words))
11.split()和 strip()有什么区别?
split() 用于分割字符串。
strip() 用于去除字符串首尾空白或者指定字符。
s = " a, b, c "
print(s.strip())
print(s.strip().split(","))
输出:
a, b, c
['a', 'b', 'c']
12.append() 和 extend()有啥区别?
append() 添加一个元素。
extend() 展开可迭代对象后逐个添加。
a = [1, 2]
a.append([3, 4])
print(a)
b = [1, 2]
b.extend([3, 4])
print(b)
输出:
[1, 2, [3, 4]]
[1, 2, 3, 4]
13.list.sort() 和 sorted() 有什么区别?
list.sort() 是原地排序,返回None。
sorted() 会返回一个新的列表。
a = [3, 1, 4]
b = sorted(a)
print(a)
print(b)
a.sort()
print(a)
输出:
[3, 1, 2]
[1, 2, 3]
[1, 2, 3]
14.元组一定不可变吗?
元组本身属于不可变数据类型,但是如果元组中包含可变对象,可变对象内部仍然可以修改。
t = ([1, 2], "a")
t[0].append(3)
print(t) # ([1, 2, 3], "a")
15.字典如何安全获取不存在的Key?
使用get()方式。
user = {"name":"yuanyuan"}
print(user.get("age")) # None
print(user.get("age", 18)) # 18
16.字典如何遍历 Key 和 Value?
user = {"name":"xiaoyuan", "age":18}
for k, v in user.items():
print(k, v)
输出:
name xiaoyuan
age 18
17.什么是字典推导式?
d = {x: x * x for x in range(3)}
print(d) # {0: 0, 1: 1, 2: 4}
18.集合有哪些特点?
Set的特点:
1)元素唯一(元素中不会包含重复的元素)
2)无序性 这也就疑问着其元素没有索引,也不会记录插入顺序
3)元素必须可哈希
4)支持数学集合运算
5)Set 和 Forzenset
-
set:可变,可以增删元素。
-
frozenset:不可变,创建后不能修改,可以作为字典的键或另一个集合的元素
num = [1, 2, 3, 3, 5, 6]
print(set(nums)) #{1, 2, 3, 5, 6}
# 集合的常用运算
m = {1, 2, 3}
n = {3, 2, 6}
print(a | b) # 并运算 {1, 2, 3, 4}
print(a & b) # 交运算 {2, 3}
print(a – b) # 差运算 {1}
19.如何取列表中出现最多的元素?
这里用的方法利用了字典dict的特性,避免了多次遍历列表。其时间复杂度是O(n)。
lst = [1, 2, 3, 3, 2, 3, 5, 1, 3]
freq = {}
for item in lst:
freq[item] = freq.get(item, 0) + 1
# 找最大值
most_common = max(freq, key = freq.get)
count = freq[most_common]
print(f"出现最多的元素是{most_common}, 出现了{count}次")
20.python函数参数有哪些类型?
常见的参数类型有:
1.默认参数
2.位置参数
3.关键字参数
4.可变位置参数 *args
5.可变关键字参数 **kwargs
def demo(a, b = 2, *args, **kwargs):
print(a, b, args, kwargs)
demo(1, 3, 4, 5, name = "xiaoyuan") # 1 3 (4, 5) {'name':'xiaoyuan'}
21.默认参数有啥需要注意的?
默认参数只在函数定义时创建依次。
如果默认参数是列表、字典等可变对象,可能导致数据被多次调用共享。
def add_item(item, box = []):
box.append(item)
return box
print(add_item("a")) # ['a']
print(add_item("b")) # ['a', 'b']
22. *args 和 **kwargs
| *args | arguments | 任意数量的位置参数 | 元组 (tuple) |
| **kwargs | keyword arguments | 任意数量的关键字参数 | 字典 (dict) |
def total(*args):
return sum(args)
print(total(1, 2, 3)) # 6
def show(**args):
print(kwargs)
show(name = "xiaoyuan", age = 19) # {'name':'xiaoyuan', 'age':18}
23.python函数是对象吗?
是。函数可以赋值给变量,也可以作为参数传递。
def hello():
return "hello"
f = hello
print(f()) # hello
24.什么是高阶函数?
接收函数作为参数,或者返回函数的函数,称之为高阶函数。
def apply(func, value):
return func(value)
print(apply(abs, -10)) # 10
| map() | 对可迭代对象每个元素应用函数,返回迭代器 | function, iterable |
| filter() | 过滤出使函数返回 True 的元素 | function, iterable |
| sorted() | 返回排序后的新列表 | iterable, key, reverse |
| max() | 返回最大值(可指定比较规则) | iterable, key |
| min() | 返回最小值(可指定比较规则) | iterable, key |
25.lamda表达式是什么?
lamda是匿名函数,适合简单逻辑。
add = lambda a, b: a + b
print(add(1, 2)) # 3
26.map()
map() 会对可迭代对象中的每个元素应用函数。
nums = [1, 2, 3]
print(list(map(lambda x: x * 2, nums)))
27.filter()
filter() 用于过滤元素。
nums = [1, 2, 3, 4]
print(list(filter(lambda x: x % 2 == 0, nums))) # [2, 4]
28.zip()
zip() 会把多个可迭代对象按位置打包。
names = ["a", "b"]
scores = [89, 90]
print(list(zip(name, scores))) # [('a', 90}, ('b', 80)]
29.python中作用域查找规则是什么?
Python 变量查找遵循 LEGB 规则:
x = "global"
def outer():
x = "outer"
def inner():
x = "inner"
print(x)
inner()
outer() # inner
30.global有啥作用?
global 用于在函数内部声明并修改全局变量。
count = 0
def inc():
global count
count += 1
inc()
print(count) # 1
31.nonlocal
nonlocal 用于修改外层函数作用域中的变量
def outer():
count = 0
def inner():
nonlocal count
count += 1
return count
return inner
f = outer()
print(f()) # 1
print(f()) # 2
32.什么是闭包?
函数内部定义函数,并且内部函数引用了外部函数的变量,这个结构就是闭包。
def make_multiplier(n):
def mul(x):
return x * n
return mul
double = make_multiplier(2)
print(double(5)) # 10
33.什么是装饰器?
装饰器本质上也是一个函数,用于在不修改原函数代码的情况下增强功能。
def lof(func):
def wrapper():
print("before")
func()
print("after")
return wrapper
@log
def hello():
print("hello")
hello()
# before
# hello
# after
34.装饰器如何保留原函数信息?
使用 functools.wraps
from functools import wraps
def log(func):
@wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
@log
def hello():
"""say hello"""
print("hello")
print(hello.__name__)
print(hello.__doc__)
# hello
# say hello
35.带参数的装饰器怎么用?
from functools import wraps
def repeat(n):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for _ in range(n):
func(*args, **kwargs)
return wrapper
return decorator
@repeat(2)
def say():
print("hi")
say()
# hi
# hi
36.python如何捕获异常?
try:
# 可能出错的代码
result = 10 / 0
except:
# 出错后执行的代码
print("出错了!")
37.try…except…else…finally 执行顺序是什么?
else 在没有异常时执行;
finally 无论是否异常都会执行。
try:
x = 10 / 2
except ZeroDivisionError:
print("except")
else:
print("else:", x)
finally:
print("finally")
# else: 5.0
# finally
38.如何主动抛出异常?
使用 raise。
def check_age(age):
if age < 0:
raise ValueError("age cannot be negative")
return age
try:
check_age(-1)
except ValueError as e:
print(e) # age cannot be negative
39.如何自定义捕获异常?
class BusinessError(Exception):
pass
raise BusinessError("业务异常") # BusinessError: 业务异常
40.为啥推荐使用 with open()?
with 会自动关闭文件, 避免资源泄露。—>安全自动的资源管理
with 语句其实是在调用一个上下文管理器。文件对象实现了一个协议,包含两个魔法方法:
__enter__:进入 with 块时被调用,并返回文件对象本身(赋给 as 后面的变量)。
__exit__:离开 with 块时一定会被调用。它的职责就是执行 file.close()。
41.什么是迭代器?
实现 __iter__() 和 __next__() 的对象就是迭代器。
nums = iter([1, 2, 3])
print(next(nums))
print(next(nums))
42.什么是可迭代对象?
能被 for 循环遍历的对象,就是可迭代对象。
常见可迭代对象:
1) list
2) tuple
3) dict
4) str
5) set
6) 生成器
43.什么是生成器?
包含 yield 的函数会返回生成器。生成器会按需产生数据。
生成器优点:生成器节省内存,适合处理大数据流。
def gen():
yield 1
yield 2
g = gen()
print(next(g)) # 1
print(next(g)) # 2
44.yield from 有什么作用?
yield from 可以把子生成器的值交给外层生成器
def gen():
yield from [1, 2, 3]
print(list(gen())) # [1, 2, 3]
45.生成器表达式和列表推导式有什么区别?
生成器表达式按需计算。
列表推导式会依次性生成完整列表。
| 数据量小,需要多次访问 | 列表推导式 | 可重复使用,语法简单 |
| 数据量大(百万级以上) | 生成器表达式 | 节省内存 |
| 需要索引、切片、长度 | 列表推导式 | 生成器不支持这些操作 |
| 作为函数参数 | 生成器表达式 | 无需额外括号 |
g = (x * x for x in range(3))
print(g) # <generator object <genexpr> at 0x…>
print(list(g)) # [0, 1, 4]
46.类和对象有什么区别?
类是模板,对象是类的实例。
class User:
pass
u = User()
print(type(u)) # <class '__main__.User'>
47. __init__ 是构造函数吗?
严格来说不是, __init__ 是初始化方法,对象创建后会调用它。
真正创建对象的是 __new__
class User:
def __init__(self, name):
self.name = name
u = User("xiaoming")
pritn(u.name) # xiaoming
48.实例属性和类属性有什么区别?
实例属性属于对象。类属性属于类。
class User:
role = "tester"
u1 = User()
u2 = User()
u1.name = "john"
print(u1.role)
print(u2.role)
print(u1.name)
49. 类方法、静态方法、实例方法有什么区别?
实例方法默认接收 self。
类方法默认接收 cls。
静态方法不自动接收对象或类。
| 装饰器 | 无 | @classmethod | @staticmethod |
| 第一个参数 | self(实例对象) | cls(类) | 无特殊参数 |
| 调用方式 | 通常 obj.method() | Class.method() 或 obj.method() | Class.method() 或 obj.method() |
| 能访问类属性 | 可以(通过类名或 self.__class__) | 可以(通过 cls) | 不能直接访问(除非写类名) |
| 能访问实例属性 | 可以(通过 self) | 不能(没有 self) | 不能(没有 self) |
| 适用场景 | 操作具体对象的数据 | 工厂方法、操作类属性、需要继承 | 工具函数、无需类/实例数据 |
class Demo:
def ins(self):
print("instance")
@classmethod
def cls_method(cls):
print("class")
@staticmethod
def static_method():
print("static")
d = Demo()
d.ins()
Demo.cls_method()
Demo.static_method()
输出:
instance
class
static
50.什么是继承?
子类可以复用父类的属性和方法。
class Animal:
def speak(self):
print("animal speak")
class Dog(Animal):
pass
Dog().speak() # animal speak
51.什么是方法重写?
子类重新定义父类方法,就是方法重写。
class Animal:
def speak(self):
print("animal")
class Dog(Animal):
def speak(self):
print("wang")
Dog().speak() # wang
52.super()有什么作用?
super() 用于调用父类方法。
class Base:
def hello(self):
print("base hello")
class Child(Base):
def hello(self):
super().hello()
print("child hello")
Child().hello()
# base hello
# child hello
53.python支持多继承吗?
支持。多继承也就是一个子类可以继承多个父类。方法解析顺序由MRO决定。
class A:
def hello(self):
print("A")
class B(A):
pass
class C(A):
def hello(self):
print("C")
class D(B, C):
pass
D().hello()
print(D.mro())
# C
# [<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
54.什么是魔法方法?
以双下划线开头和结尾的方法。例如:
__str__
__repr__
__len__
__exit__
class User:
def __str__(self):
return "User object"
print(User()) # User object
55.__repr__ 和 __str__ 有什么区别?
__str__ 面向用户,输出更友好。
__repr__ 面向开发者和调试。
class User:
def __repr__(self):
return "User(name='vito')"
u = User()
print(repr(u))
# User(name='vite')
56.@property 有什么作用?
@property 可以把方法当属性访问,同时封装计算逻辑。
class Circle:
def __init__(self, r):
self.r = r
@property
def area(self):
return 3.14 * self.r * self.r
c = Circle(2)
print(c.area) # 12.56
57.模块与包有什么区别?
一个 .py 文件可以是模块。包含多个模块的目录可以作为包。
# demo.py
def hello():
return "hello"
使用:
# import demo
# print(demo.hello())
58.if __name__ == "__main__" 有什么作用?
判断当前文件是被直接运行,还是被其他模块导入。
def main():
print("running main")
if __name__ == "__main__":
main() # running main
59.python 如何管理第三方依赖?
常用 pip 安装依赖,并推荐使用虚拟环境。
为啥推荐使用虚拟环境呢?
虚拟环境允许为每个python项目创建独立的依赖库目录,避免不同项目间的依赖冲突。
python -m venv .venv
source .venv/bin/activate
pip install requests
60.requirements.txt有什么作用?
用于记录项目依赖,方便环境复现。
pip install -r requirements.txt # 安装依赖
61.pyproject.toml 是什么?
pyproject.toml 是现代 Python 项目常见配置文件,可配置:
- 项目信息
- 构建系统
- pytest 配置
- black 配置
- mypy 配置
- ruff 配置
[project]
name = "demo"
version = "0.1.0"
[tool.pytest.ini_options]
testpaths = ["tests"]
62.python如何读取环境变量?
import os
os.environ["APP_ENV"] = "dev"
print(os.getenv("APP_ENV") # dev
63.__all__ 有什么作用?
__all__ 用于控制 from module import * 导入的内容。
__all__ = ["hello"]
def hello():
print("hello")
def hidden():
print("hidden")
64.线程适合什么场景?
线程适合 IO 密集型任务,例如:
- 网络请求
- 文件读写
- 数据库访问
- 接口调用
import threading
import time
def task(name):
time.sleep(1)
print(name, "done")
t1 = threading.Thread(target=task, args=("A",))
t2 = threading.Thread(target=task, args=("B",))
t1.start()
t2.start()
t1.join()
t2.join()
# A done
# B done
65.什么是GIL?
GIL 是 CPython 中的全局解释器锁。
它会限制多个线程同时执行 Python 字节码,所以 CPU 密集型任务通常无法通过多线程获得明显性能提升。
def cpu_task():
return sum(i * i for i in range(100000))
print(cpu_task()) # 333328333350000
66.进程适合什么场景?
进程适合 CPU 密集型任务。
多进程可以利用多核 CPU。
from multiprocessing import Pool
def square(x):
return x * x
if __name__ == "__main__":
with Pool(2) as pool:
print(pool.map(square, [1, 2, 3])) # 【1, 4, 9】
67.为啥Windows下多进程要写 if __name__ = "__main__"?
因为 Windows 创建子进程时会重新导入主模块。
如果不加保护,可能导致子进程重复创建子进程。
from multiprocessing import Process
def hello():
print("hello")
if __name__ == "__main__":
p = Process(target=hello)
p.start()
p.join() # hello
68.协程适合什么场景?
协程适合高并发 IO 场景,例如:
- 网络请求
- WebSocket
- 异步数据库
- 异步爬虫
- 高并发接口调用
import asyncio
async def main():
print("start")
await asyncio.sleep(1)
print("end")
asyncio.run(main())
# start
# end
69.async 和 await 是什么?
async 用于定义协程函数。
await 用于等待异步操作完成。
async 用于定义一个协程函数,await 就是暂停点,告诉程序“这个地方需要等会,你先去干别的吧。”
import asyncio
async def fetch():
await asyncio.sleep(1)
return "data"
async def main():
result = await fetch()
print(result)
asyncio.run(main()) # data
70.json.dumps() 和 json.loads()有什么区别?
json.dumps() 把 Python 对象转成 JSON 字符串。
json.loads() 把 JSON 字符串转成 Python 对象。
import json
s = json.dumps({"name": "vito"}, ensure_ascii=False)
print(s)
obj = json.loads(s)
print(obj["name"])
输出:
{"name":"vite"}
vito
71.如何查看对象占用内存?
import sys
a = [1, 2, 3]
print(sys.getsizeof(a)) # 88
# 具体数值和 Python 版本、操作系统有关
72.python代码规范主要看什么?
73. 面试中如何回答“你怎么提升 Python 代码质量”?
74.Python中创建虚拟环境的文件
venv/
│
├── bin/ # 在Unix/Linux系统中存放可执行文件
│ ├── activate # 激活虚拟环境的脚本
│ ├── python # 虚拟环境的Python解释器
│ └── pip # 虚拟环境的pip工具
│
├── Scripts/ # 在Windows系统中存放可执行文件
│ ├── activate.bat # Windows下的激活脚本
│ ├── python.exe # 虚拟环境的Python解释器
│ └── pip.exe # 虚拟环境的pip工具
│
├── Lib/ # 存放安装的第三方库
│ └── site-packages/
│
└── pyvenv.cfg # 虚拟环境配置文件
75.Python中什么是语法糖?
语法糖是指在编程语言中,不改变功能但是让代码更易读、更简洁的语法形式。注意:它只是对现有语法的“甜蜜”包装,底层实现完全等价。
Python中常见的语法糖
| 装饰器 | @decorator | func = decorator(func) | 函数包装的简洁写法 |
| 列表推导式 | [x*2 for x in lst] | lst2 = [] for x in lst: lst2.append(x*2) |
生成列表的声明式写法 |
| 字典推导式 | {k:v for k,v in d.items()} | d2 = {} for k,v in d.items(): d2[k] = v |
生成字典的声明式写法 |
| 集合推导式 | {x for x in lst} | s = set() for x in lst: s.add(x) |
生成集合的声明式写法 |
| 生成器表达式 | (x*2 for x in lst) | 生成器函数中用 yield | 惰性求值的迭代器 |
| with 语句 | with obj as f: | f = obj.__enter__() try: … finally: f.__exit__() |
自动资源管理 |
| 比较链 | a < b < c | a < b and b < c | 链式比较 |
| 三元运算符 | x if cond else y | if cond: x else: y |
条件表达式 |
| f-string | f"值:{val}" | "值:{}".format(val) | 字符串插值 |
| 星号解包 | a, *b = [1,2,3] | a = lst[0] b = lst[1:] |
可迭代对象解包 |
| 星号展开 | func(*args, **kwargs) | 手动传递参数 | 参数展开传递 |
| 切片 | lst[1:5:2] | lst[slice(1,5,2)] | 序列切片操作 |
| 算术运算符 | a + b | a.__add__(b) | 运算符重载的语法糖 |
| 比较运算符 | a == b | a.__eq__(b) | 比较运算符重载 |
| 属性访问 | obj.attr | getattr(obj, 'attr') | 属性访问 |
| 属性赋值 | obj.attr = val | setattr(obj, 'attr', val) | 属性赋值 |
| 索引访问 | obj[key] | obj.__getitem__(key) | 索引/键访问 |
| in 运算符 | x in obj | obj.__contains__(x) | 成员检查 |
| 断言 | assert condition, msg | if __debug__: if not condition: raise AssertionError(msg) |
调试断言 |
| 海象运算符 | if (n := len(lst)) > 0: | n = len(lst) if n > 0: |
表达式内赋值 |
| for…else | for x in lst: … else: … |
需要手动加标志位判断 | 循环正常结束执行 |
| lambda | lambda x: x*2 | def anonymous(x): return x*2 |
匿名函数 |
| 字符串乘法 | "ab" * 3 | 循环拼接 | 字符串重复 |
| 列表加法 | [1,2] + [3,4] | list.extend() | 列表拼接 |
| 多变量交换 | a, b = b, a | temp = a a = b b = temp |
变量值交换 |
| 同时赋值 | x, y = 1, 2 | x = 1 y = 2 |
多变量初始化 |



