Python中类似C++ #ifdef/#define的实现:切换按日期/成本排序
问题描述
我定义了如下Python类:
class purchase: name: str day: int month: int year: int date: int # 按儒略日计算 cost: Decimal
我希望编写一个函数,根据用户选择对该类的对象列表按date或cost字段排序。我可以写两个仅排序字段不同的重复函数,但在C++中我会用类似下面的优雅实现,只用一个函数完成需求:
#ifdef flag == 1 #define SORTING_FIELD cost #else #define SORTING_FIELD date #endif
请问Python中是否有类似的实现方式?
解决方案
当然有,Python里有很多比C++宏更优雅的方式实现单函数多字段排序,完全不用写重复代码:
方法1:用lambda作为排序key
直接把目标排序字段名作为参数传入函数,通过lambda结合getattr提取对象属性:
from decimal import Decimal class purchase: def __init__(self, name, day, month, year, date, cost): self.name = name self.day = day self.month = month self.year = year self.date = date self.cost = cost def sort_purchases(purchases_list, sort_field): # 校验字段合法性,避免传入无效值 if sort_field not in ['date', 'cost']: raise ValueError("sort_field must be 'date' or 'cost'") return sorted(purchases_list, key=lambda x: getattr(x, sort_field))
调用时直接指定字段名即可:
# 示例用法 purchases = [ purchase("A", 1, 1, 2024, 2459999, Decimal("100.5")), purchase("B", 2, 1, 2024, 2460000, Decimal("90.0")) ] # 按date排序 sorted_by_date = sort_purchases(purchases, 'date') # 按cost排序 sorted_by_cost = sort_purchases(purchases, 'cost')
方法2:使用operator.attrgetter
如果觉得lambda不够直观,可以用operator模块的attrgetter,它专门用于提取对象属性,效率也更高:
from operator import attrgetter from decimal import Decimal class purchase: def __init__(self, name, day, month, year, date, cost): self.name = name self.day = day self.month = month self.year = year self.date = date self.cost = cost def sort_purchases(purchases_list, sort_field): if sort_field not in ['date', 'cost']: raise ValueError("sort_field must be 'date' or 'cost'") return sorted(purchases_list, key=attrgetter(sort_field))
用法和方法1完全一致,只是把key换成了attrgetter,适合需要提取多个属性组合排序的场景。
这些方法不需要像C++那样依赖宏定义,直接通过参数控制排序字段,代码更易读、易维护,也更符合Python的风格。
内容的提问来源于stack exchange,提问作者warmike_1
相关产品推荐
相关产品推荐

