10 个高级 Python 技巧,适合有经验的开发者

360影视 动漫周边 2025-05-28 01:54 2

摘要:# Define two dictionariesdict1 = {'a': 1, 'b': 2}dict2 = {'b': 3, 'c': 4}# Merge dictionariesmerged_dict = dict1 | dict2print(merg

允许你在表达式中为变量赋值。在循环和推导式中很有用,可以提高效率。

WaLrus 运算符在 while 循环中很有用,可以在同一个表达式中分配和测试值,尤其是在处理输入或迭代计算时。

# User input processinguser_input = input("Enter a number (or 'quit' to exit): ")while (user_input := input("Enter a number (or 'quit' to exit): ")) != 'quit': print(f'You entered: {user_input}')

在 Python 3.9 及更高版本中,引入了两个新的字典运算符:合并运算符和更新运算符(|=)。

合并两个字典

合并运算符 | 通过组合两个字典的内容来创建一个新的字典。如果存在重复的键,则右边的字典中的值会覆盖左边的字典中的值。

# Define two dictionariesdict1 = {'a': 1, 'b': 2}dict2 = {'b': 3, 'c': 4}# Merge dictionariesmerged_dict = dict1 | dict2print(merged_dict) # Output: {'a': 1, 'b': 3, 'c': 4}

这个例子展示了如何将两个字典合并成一个新的字典,其中第二个字典的值会覆盖第一个字典的值,如果键有重叠的话。

在原地更新字典

更新运算符 |= 通过从另一个字典中添加项来原地更新原始字典。类似于合并运算符,原始字典中的重叠键会被覆盖。

# Define two dictionariesdict1 = {'a': 1, 'b': 2}dict2 = {'b': 3, 'c': 4}# Update dict1 with dict2dict1 |= dict2print(dict1) # Output: {'a': 1, 'b': 3, 'c': 4}

在这个例子中,dict1 原地更新,包含了来自 dict2 的值。

使用 functools.lru_cache 来缓存昂贵的函数调用。

from functools import lru_cache@lru_cache(maxsize=100)def fib(n): if n

Python 中的 Enum 类用于定义枚举,枚举是一组绑定到唯一、常量值的符号名称。使用枚举可以使代码更易读、更易维护,因为它确保使用符号名称而不是任意的、通常未经解释的数值。

from enum import Enumclass Day(Enum): MONDAY = 1 TUESDAY = 2 WEDNESDAY = 3 THURSDAY = 4 FRIDAY = 5 SATURDAY = 6 SUNDAY = 7# Accessing an enum memberprint(Day.MONDAY)print(Day.FRIDAY.value) # Output the associated value

枚举非常适合表示一组相关的值,例如一周中的几天,其中每一天都可以通过符号名称来引用,而不是数字。

用于并行迭代两个列表。

names = ["Alice", "Bob", "Charlie"]ages = [24, 30, 18]for name, age in zip(names, ages): print(f"{name} is {age} years old")

Python 中的上下文管理器是一种强大的功能,用于资源管理,提供了一种在需要时精确分配和释放资源的方法。

使用 with 语句来处理自动资源管理。

with open('file.txt', 'r') as f: file_contents = f.read

动态导入模块。

from importlib import import_modulemath = import_module('math')math.sqrt(4)

Python 中的动态导入功能,通过 importlib 模块,允许在运行时程序性地加载模块,而不是在脚本开始时加载。此功能在各种场景中特别有用,并提供了许多好处:

1. 减少启动时间

动态导入可以显著减少应用程序的初始加载时间,将模块的导入推迟到实际需要时才进行。这对于具有许多依赖的大型应用程序特别有利,因为在启动时导入所有内容会导致不必要的延迟。

2. 高效管理内存

通过仅在需要时导入模块,动态导入有助于更有效地管理内存。仅偶尔使用的模块不会永久占用内存,这在内存受限的环境中是有益的。

3. 加载模块的灵活性

importlib 允许开发者根据变量名和条件来导入模块。这种灵活性在模块名可能无法提前知道的情况下至关重要,例如当它们依赖于用户输入或配置文件时。

import importlibmodule_name = "math"math_module = importlib.import_module(module_name)print(math_module.sqrt(16)) # Dynamically imported and used

4. 插件和扩展系统

动态导入非常适合支持插件或扩展的应用程序。开发者可以在不修改核心应用程序的情况下添加新功能或模块。这允许根据用户配置或运行时决策加载所需的插件。

# Suppose `plugin_name` is defined based on user input or a configuration fileplugin = importlib.import_module(f"plugins.{plugin_name}")plugin.run # Use the dynamically imported pluginp

5. 处理可选依赖

在某些应用程序的功能依赖于可能并非所有用户都安装的库的情况下,动态导入使得只有在访问这些功能时才加载这些库成为可能。这种做法避免了强制所有用户安装所有依赖项。

def optional_feature: try: optional_lib = importlib.import_module("optional_lib") except ImportError: optional_lib = None if optional_lib: optional_lib.do_something else: print("Optional feature not available.")

6. 自定义导入逻辑

importlib 提供了自定义导入系统的工具,允许实现高级行为,如从非标准源导入,或实现可能以不同的方式处理安全、压缩或加密的自定义加载器。

7. 测试和模拟

动态导入使得在测试过程中更容易用模拟实现来替换模块,这在单元测试中特别有用,因为某些模块不应该以标准形式加载。

8. 条件导入以实现跨平台兼容性

需要在多个平台上运行的应用程序可以使用动态导入来根据平台条件地导入平台特定的模块。这确保了兼容性,同时不会在特定平台上加载不必要的模块。

import sysif sys.platform == 'win32': windows_specific = importlib.import_module("win_specific")else: posix_specific = importlib.import_module("posix_specific")

总体而言,importlib 和动态导入为管理 Python 应用的模块化提供了一套强大的工具,增强了大型项目的灵活性、可扩展性和可维护性。它们允许开发者优化资源使用,并根据应用程序的具体需求和条件定制模块加载。

检查对象是否有属性。

class Car: def __init__(self, model, year): self.model = model self.year = yearcar = Car("Toyota Camry", 2021)# Check if the car has a 'color' attribute before accessing itif hasattr(car, 'color'): print(f'The car color is: {car.color}')else: print("No color information available.")# Output: No color information available.

安全地访问字典键。

d = {'a': 1, 'b': 2}d.get('c', 0)

捕获多个异常。

try: # risky codeexcept (TypeError, ValueError) as e: # handle multiple exceptions

Python 切片是一个强大的功能,它允许您使用简单直观的语法访问序列(如列表、字符串和元组)的各个部分。

使用切片可以反转字符串或列表。

您可以使用切片技巧 [::-1] 轻松地反转任何序列。这是 Python 中最著名的技巧之一,用于快速反转列表或字符串。

# Reversing a listmy_list = [1, 2, 3, 4, 5]reversed_list = my_list[::-1]print(reversed_list) # Output: [5, 4, 3, 2, 1]# Reversing a stringmy_string = "hello"reversed_string = my_string[::-1]print(reversed_string) # Output: 'olleh'

跳过元素

切片语法允许您在序列中跳过元素。您可以通过在切片操作中指定步长来实现这一点。这对于选择每 n 个元素特别有用。

# Skipping elements in a listnumbers = list(range(10))every_second = numbers[::2]print(every_second) # Output: [0, 2, 4, 6, 8]# Selecting every third character in a stringmy_string = "abcdefghijklmn"every_third = my_string[::3]print(every_third) # Output: 'adgjm'

创建子序列

您可以通过结合起始和结束索引以及步长来创建子序列。这允许更复杂的选取,并且对于处理序列的一部分很有用。

# Extracting a subsequence from a listnumbers = list(range(20))subsequence = numbers[5:15:2] # Start at index 5, end before index 15, step by 2print(subsequence) # Output: [5, 7, 9, 11, 13]# Substring from a string with stepsmy_string = "Hello, World!"substring = my_string[1:10:2] # Start at index 1, end before index 10, step by 2print(substring) # Output: 'el,W'

使用负索引

Python 支持切片中的负索引,这对于引用序列的末尾而无需知道其长度非常有用。

# Accessing last elementsmy_list = [1, 2, 3, 4, 5, 6]last_three = my_list[-3:]print(last_three) # Output: [4, 5, 6]# Substring from the end of a stringmy_string = "Hello, World!"last_part = my_string[-5:]print(last_part) # Output: 'orld!'

原地修改列表

切片也可以用来原地修改列表。这可以包括更改值或插入和删除元素。

# Replacing elementsmy_list = [1, 2, 3, 4, 5]my_list[1:4] = [9, 9, 9] # Replace elements at index 1 to 3print(my_list) # Output: [1, 9, 9, 9, 5]# Deleting elements using slicesmy_list = [1, 2, 3, 4, 5]del my_list[::2] # Delete every second elementprint(my_list) # Output: [2, 4]# Inserting elements without replacingmy_list = [1, 2, 3, 4, 5]my_list[2:2] = [999] # Insert at index 2 without replacementprint(my_list) # Output: [1, 2, 999, 3, 4, 5]

来源:自由坦荡的湖泊AI一点号

相关推荐