Python中级工程师必会的指令
进阶Python开发,掌握这些指令让你从初级迈向中级
欢迎大家关注此公众号,后台点击按钮【免费资料】可免费获取【Python入门30节课】电子书
此外小庄推荐一本适合于新手\小白入手一本 Python基础书籍,欢迎大家订阅,也感谢大家支持,我才有更新的动力
前言
作为Python中级工程师,你需要在基础知识之上,掌握更高级的编程技巧和设计模式。本文将介绍中级工程师必须掌握的指令和概念,帮助你提升代码质量和开发效率。
一、高级数据结构
1.1 collections模块
from collections import defaultdict, Counter, OrderedDict, deque, namedtuple
# defaultdict - 默认字典
dd = defaultdict(list)
dd['fruits'].append('apple')
dd['fruits'].append('banana')
dd['vegetables'].append('carrot')
print(dd)
# Counter - 计数器
text = "hello world"
counter = Counter(text)
print(counter.most_common(3))
# OrderedDict - 有序字典
od = OrderedDict()
od['first'] = 1
od['second'] = 2
od['third'] = 3
# deque - 双端队列
dq = deque([1, 2, 3, 4, 5])
dq.appendleft(0)
dq.append(6)
dq.popleft()
dq.pop()
# namedtuple - 命名元组
Point = namedtuple('Point', ['x', 'y'])
p = Point(10, 20)
print(p.x, p.y)
1.2 heapq模块 - 堆
import heapq
# 创建堆
heap = []
heapq.heappush(heap, 3)
heapq.heappush(heap, 1)
heapq.heappush(heap, 2)
# 弹出最小值
print(heapq.heappop(heap)) # 1
# 堆化列表
data = [5, 3, 1, 4, 2]
heapq.heapify(data)
# 获取最大/最小的n个元素
data = [5, 3, 1, 4, 2, 8, 7, 6]
print(heapq.nlargest(3, data)) # [8, 7, 6]
print(heapq.nsmallest(3, data)) # [1, 2, 3]
# 合并多个有序迭代器
iter1 = [1, 3, 5]
iter2 = [2, 4, 6]
merged = list(heapq.merge(iter1, iter2))
print(merged) # [1, 2, 3, 4, 5, 6]
1.3 bisect模块 - 二分查找
import bisect
# 插入元素
data = [1, 3, 5, 7, 9]
bisect.insort(data, 4)
print(data) # [1, 3, 4, 5, 7, 9]
# 查找插入位置
print(bisect.bisect_left(data, 4)) # 2
print(bisect.bisect_right(data, 4)) # 3
# 查找元素
print(bisect.bisect(data, 5)) # 4
二、迭代器和生成器
2.1 迭代器
# 创建迭代器
classCountDown:
def__init__(self, start):
self.start = start
def__iter__(self):
returnself
def__next__(self):
ifself.start <= 0:
raise StopIteration
self.start -= 1
returnself.start + 1
# 使用迭代器
countdown = CountDown(5)
for num in countdown:
print(num) # 5, 4, 3, 2, 1
# 内置迭代器函数
print(next(iter([1, 2, 3])))
2.2 生成器
# 生成器函数
deffibonacci(n):
a, b = 0, 1
for _ inrange(n):
yield a
a, b = b, a + b
# 使用生成器
for num in fibonacci(10):
print(num)
# 生成器表达式
squares = (x**2for x inrange(10))
print(list(squares))
# 生成器的优势:节省内存
import sys
list_comp = [x**2for x inrange(1000)]
gen_exp = (x**2for x inrange(1000))
print(sys.getsizeof(list_comp)) # 较大
print(sys.getsizeof(gen_exp)) # 很小
2.3 itertools模块
import itertools
# 无限迭代器
counter = itertools.count(start=1, step=2)
print(next(counter)) # 1
print(next(counter)) # 3
# cycle - 循环迭代器
cycle = itertools.cycle(['A', 'B', 'C'])
for _ inrange(6):
print(next(cycle)) # A, B, C, A, B, C
# chain - 链接迭代器
list1 = [1, 2, 3]
list2 = [4, 5, 6]
chained = list(itertools.chain(list1, list2))
print(chained) # [1, 2, 3, 4, 5, 6]
# product - 笛卡尔积
colors = ['red', 'blue']
sizes = ['S', 'M', 'L']
products = list(itertools.product(colors, sizes))
print(products)
# permutations - 排列
print(list(itertools.permutations([1, 2, 3], 2)))
# combinations - 组合
print(list(itertools.combinations([1, 2, 3], 2)))
# groupby - 分组
data = [('A', 1), ('A', 2), ('B', 3), ('B', 4)]
for key, group in itertools.groupby(data, key=lambda x: x[0]):
print(key, list(group))
# accumulate - 累积
data = [1, 2, 3, 4, 5]
print(list(itertools.accumulate(data))) # [1, 3, 6, 10, 15]
print(list(itertools.accumulate(data, lambda x, y: x * y))) # [1, 2, 6, 24, 120]
三、装饰器
3.1 基本装饰器
import functools
import time
# 基本装饰器
deftimer(func):
@functools.wraps(func)
defwrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} 执行时间: {end - start}秒")
return result
return wrapper
@timer
defslow_function():
time.sleep(1)
return"完成"
result = slow_function()
3.2 带参数的装饰器
import functools
defrepeat(n):
defdecorator(func):
@functools.wraps(func)
defwrapper(*args, **kwargs):
for _ inrange(n):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
defgreet(name):
print(f"Hello, {name}!")
greet("Alice")
3.3 类装饰器
import functools
classCache:
def__init__(self):
self.cache = {}
def__call__(self, func):
@functools.wraps(func)
defwrapper(*args):
if args notinself.cache:
self.cache[args] = func(*args)
returnself.cache[args]
return wrapper
@Cache()
defexpensive_function(x):
print(f"计算 {x}...")
return x ** 2
print(expensive_function(5)) # 计算 5... 25
print(expensive_function(5)) # 25 (从缓存)
3.4 内置装饰器
# @property - 属性装饰器
classCircle:
def__init__(self, radius):
self._radius = radius
@property
defradius(self):
returnself._radius
@radius.setter
defradius(self, value):
if value < 0:
raise ValueError("半径不能为负数")
self._radius = value
@property
defarea(self):
return3.14159 * self._radius ** 2
circle = Circle(5)
print(circle.radius)
print(circle.area)
circle.radius = 10
# @staticmethod - 静态方法
classMathUtils:
@staticmethod
defadd(a, b):
return a + b
print(MathUtils.add(1, 2))
# @classmethod - 类方法
classDate:
def__init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
@classmethod
from_string(cls, date_string):
year, month, day = map(int, date_string.split('-'))
return cls(year, month, day)
date = Date.from_string('2024-01-15')
print(date.year, date.month, date.day)
四、上下文管理器
4.1 使用with语句
# 文件上下文管理器
withopen('file.txt', 'w') as f:
f.write('Hello')
# 自定义上下文管理器
classFileManager:
def__init__(self, filename, mode):
self.filename = filename
self.mode = mode
self.file = None
def__enter__(self):
self.file = open(self.filename, self.mode)
returnself.file
def__exit__(self, exc_type, exc_val, exc_tb):
ifself.file:
self.file.close()
returnFalse
with FileManager('file.txt', 'w') as f:
f.write('Hello')
4.2 contextlib模块
from contextlib import contextmanager
# 使用装饰器创建上下文管理器
@contextmanager
deftimer():
start = time.time()
yield
end = time.time()
print(f"执行时间: {end - start}秒")
with timer():
time.sleep(1)
# suppress - 抑制异常
from contextlib import suppress
with suppress(FileNotFoundError):
os.remove('nonexistent_file.txt')
# redirect_stdout - 重定向输出
from contextlib import redirect_stdout
import io
f = io.StringIO()
with redirect_stdout(f):
print('Hello')
output = f.getvalue()
print(f'捕获的输出: {output}')
五、元编程
5.1 type()动态创建类
# 动态创建类
MyClass = type('MyClass', (object,), {'x': 10})
obj = MyClass()
print(obj.x)
# 动态添加方法
defsay_hello(self):
returnf"Hello, {self.name}!"
Person = type('Person', (object,), {'say_hello': say_hello})
p = Person()
p.name = "Alice"
print(p.say_hello())
5.2 元类
# 自定义元类
classSingletonMeta(type):
_instances = {}
def__call__(cls, *args, **kwargs):
if cls notin cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
classSingleton(metaclass=SingletonMeta):
pass
s1 = Singleton()
s2 = Singleton()
print(s1 is s2) # True
5.3 __slots__优化
classPoint:
__slots__ = ['x', 'y']
def__init__(self, x, y):
self.x = x
self.y = y
p = Point(1, 2)
print(p.x, p.y)
# p.z = 3 # AttributeError
六、异步编程
6.1 asyncio基础
import asyncio
# 协程函数
asyncdefhello():
print("Hello")
await asyncio.sleep(1)
print("World")
# 运行协程
asyncio.run(hello())
# 多个协程并发
asyncdeffetch_data(url, delay):
await asyncio.sleep(delay)
returnf"{url} 数据"
asyncdefmain():
tasks = [
fetch_data("url1", 1),
fetch_data("url2", 2),
fetch_data("url3", 3),
]
results = await asyncio.gather(*tasks)
print(results)
asyncio.run(main())
6.2 异步上下文管理器
import asyncio
classAsyncResource:
asyncdef__aenter__(self):
print("获取资源")
await asyncio.sleep(0.1)
returnself
asyncdef__aexit__(self, exc_type, exc_val, exc_tb):
print("释放资源")
await asyncio.sleep(0.1)
returnFalse
asyncdefmain():
asyncwith AsyncResource() as resource:
print("使用资源")
asyncio.run(main())
6.3 异步迭代器
import asyncio
classAsyncCounter:
def__init__(self, start, end):
self.start = start
self.end = end
def__aiter__(self):
returnself
asyncdef__anext__(self):
ifself.start >= self.end:
raise StopAsyncIteration
await asyncio.sleep(0.1)
self.start += 1
returnself.start - 1
asyncdefmain():
asyncfor num in AsyncCounter(0, 5):
print(num)
asyncio.run(main())
七、设计模式
7.1 单例模式
classSingleton:
_instance = None
def__new__(cls, *args, **kwargs):
if cls._instance isNone:
cls._instance = super().__new__(cls)
return cls._instance
def__init__(self, value):
self.value = value
s1 = Singleton(1)
s2 = Singleton(2)
print(s1 is s2) # True
print(s1.value) # 2
7.2 工厂模式
from abc import ABC, abstractmethod
classAnimal(ABC):
@abstractmethod
defspeak(self):
pass
classDog(Animal):
defspeak(self):
return"Woof!"
classCat(Animal):
defspeak(self):
return"Meow!"
classAnimalFactory:
@staticmethod
defcreate_animal(animal_type):
if animal_type == "dog":
return Dog()
elif animal_type == "cat":
return Cat()
else:
raise ValueError(f"Unknown animal type: {animal_type}")
animal = AnimalFactory.create_animal("dog")
print(animal.speak())
7.3 观察者模式
classSubject:
def__init__(self):
self._observers = []
defattach(self, observer):
self._observers.append(observer)
defdetach(self, observer):
self._observers.remove(observer)
defnotify(self, message):
for observer inself._observers:
observer.update(message)
classObserver:
def__init__(self, name):
self.name = name
defupdate(self, message):
print(f"{self.name} 收到消息: {message}")
subject = Subject()
observer1 = Observer("观察者1")
observer2 = Observer("观察者2")
subject.attach(observer1)
subject.attach(observer2)
subject.notify("新消息")
7.4 策略模式
from abc import ABC, abstractmethod
classSortStrategy(ABC):
@abstractmethod
defsort(self, data):
pass
classBubbleSort(SortStrategy):
defsort(self, data):
n = len(data)
for i inrange(n):
for j inrange(0, n-i-1):
if data[j] > data[j+1]:
data[j], data[j+1] = data[j+1], data[j]
return data
classQuickSort(SortStrategy):
defsort(self, data):
iflen(data) <= 1:
return data
pivot = data[len(data) // 2]
left = [x for x in data if x < pivot]
middle = [x for x in data if x == pivot]
right = [x for x in data if x > pivot]
returnself.sort(left) + middle + self.sort(right)
classSorter:
def__init__(self, strategy):
self.strategy = strategy
defsort(self, data):
returnself.strategy.sort(data)
data = [5, 3, 1, 4, 2]
sorter = Sorter(BubbleSort())
print(sorter.sort(data))
sorter = Sorter(QuickSort())
print(sorter.sort(data))
八、性能优化
8.1 使用内置函数
# 使用内置函数而不是手动循环
# 不推荐
total = 0
for x inrange(1000000):
total += x
# 推荐
total = sum(range(1000000))
# 使用map和filter
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))
even = list(filter(lambda x: x % 2 == 0, numbers))
8.2 使用生成器节省内存
# 不推荐:创建完整列表
defget_squares(n):
return [x**2for x inrange(n)]
# 推荐:使用生成器
defget_squares_gen(n):
for x inrange(n):
yield x**2
8.3 使用局部变量
# 不推荐
defcalculate():
result = 0
for i inrange(1000000):
result += math.sqrt(i) # 每次都查找math模块
return result
# 推荐
defcalculate():
result = 0
sqrt = math.sqrt # 局部变量
for i inrange(1000000):
result += sqrt(i)
return result
8.4 使用__slots__
# 不推荐
classPoint:
def__init__(self, x, y):
self.x = x
self.y = y
# 推荐
classPoint:
__slots__ = ['x', 'y']
def__init__(self, x, y):
self.x = x
self.y = y
九、类型提示
9.1 基本类型提示
from typing importList, Dict, Tuple, Optional, Union
defgreet(name: str) -> str:
returnf"Hello, {name}!"
defprocess_items(items: List[str]) -> Dict[str, int]:
return {item: len(item) for item in items}
defget_user(user_id: int) -> Optional[Dict[str, str]]:
if user_id > 0:
return {"id": str(user_id), "name": "User"}
returnNone
defprocess(value: Union[int, str]) -> str:
returnstr(value)
9.2 自定义类型
from typing import TypeVar, Generic, List
T = TypeVar('T')
classStack(Generic[T]):
def__init__(self) -> None:
self._items: List[T] = []
defpush(self, item: T) -> None:
self._items.append(item)
defpop(self) -> T:
returnself._items.pop()
defpeek(self) -> T:
returnself._items[-1]
stack: Stack[int] = Stack()
stack.push(1)
stack.push(2)
print(stack.pop())
总结
作为Python中级工程师,掌握这些进阶技能是关键:
- 1. 高级数据结构 - collections、heapq、bisect
掌握这些技能,你就能写出更优雅、更高效的Python代码。
关注我,获取更多Python技术干货!