三元表达式
在很多状况下,应用一般的 if/else
语句的代码可读性的确更好。自觉谋求三元表达式很容易引诱你写出简单、可读性差的代码。
所以,请记得只用三元表达式解决简略的逻辑分支。比方如下代码是适宜应用三元表达式的:
language = "python" if you.favor("dynamic") else "golang"
对于绝大多数状况,还是应用一般的 if/else
语句吧。比方上面代码
self.enabled = True if kwargs['enable'] and kwargs['already_started'] == 'Yes' and self.checked == 1 else Falseself.need_use_ssl = True if kwargs['use_ssl'] is True else False if kwargs['allow_insecure'] is False else True
下面两种状况应用三元表达式反而将代码写的很长,第二行还有条件嵌套,使代码更加不容易了解
上面章节会介绍简化 if-else
statement的具体技巧,这里咱们记住三元表达式须要慎用。
重构 if…else 语句
Nested if-else hell
如果你对这种代码十分观赏,并且心田有一种想要搞清楚它在干什么的激动,请略过这章的内容。
应用卫语语句简化函数
def get_payment_amount(account: Account) -> float: result = 0.0 if account.is_deactivated: result = get_deacticated_amount(account) else: if account.is_separated: result = get_separated_amount(account) else: if account.is_retired: result = get_retired_amount(account) else: result = get_normal_amount(account) return result
该代码段存在大量的条件嵌套,应用卫语简化这个代码段,也叫提前结束(early ending)
def get_payment_amount(account: Account) -> float: if account.is_deactivated: return get_deacticated_amount(account) if account.is_separated: return get_separated_amount(account) if account.is_retired: return get_retired_amount(account) return get_normal_amount(account)
重构后,根本移除了所有的 else 语句,使整个函数变得更加清晰,容易了解。
应用多态代替条件表达式
以下代码段是判断一个员工是否可能休假的代码
def is_eligible_for_pto(employee: Employee) -> bool: if employee.type == "Manager": return employee.hired_days > 100 and employee.performance >= 0.8 elif employee.type == "Developer": return employee.hired_days > 30 and employee.performance >= 0.6 and employee.is_on_duty is False elif employee.type == "Intern": return employee.hired_days > 7 and employee.performance >= 0.4 and employee.is_on_duty is False elif employee.type == "Director": return employee.is_on_duty is False return False
咱们曾经用卫语代替条件分支的办法重构过了,然而这个代码仍然看起来很繁琐,因为每个条件分支都有很长很简单的判断逻辑,而对于这个函数来说,它须要的常识太多了,必须晓得employee 这个对象的属性,以及影响 PTO 的相干条件能力判断进去。
咱们如果应用多态的形式来重构这段代码,可能将判断逻辑封装在具体的子类中,并且只须要在函数中调用相应接口即可,并不需要晓得对于 Employee这个对象更多的信息即可实现工作。
class Employee: type: str hired_days: int performance: float @property def pto_condition(self) -> bool: return Falseclass Manager(Employee): @property def pto_condition(self) -> bool: return self.hired_days > 100 and \ self.performance >= 0.8class Developer(Employee): @property def pto_condition(self) -> bool: return self.hired_days > 30 and \ self.performance >= 0.6 and \ self.is_on_duty is Falseclass Intern(Employee): @property def pto_condition(self) -> bool: return self.hired_days > 7 and \ self.performance >= 0.4 and \ self.is_on_duty is Falseclass Director(Employee): @property def pto_condition(self) -> bool: return self.is_on_duty is Falsedef is_eligible_for_pto(employee: Employee) -> bool: return employee.pto_condition is True
用否定条件判断代替 else 分支
bad:
def _to_list(src): if src: return src if isinstance(src, list) else [src] else: return []
good:
def _to_list(src): if not src: return [] return src if isinstance(src, list) else [src]
逻辑重构
应用 for...else
代替 flag 以简化代码
bad:
flag = Falsefor index in range(10): if index == 20: flag = True breakif not flag: print("not found it")
good:
for index in range(10): if index = 20: breakelse: print("not found it")
应用字典代替条件判断
Python 中是不存在 switch 语句的,(新版本才反对),所以,当存在较多条件分支时,会写十分长的if
判断语句,比方像上面这种:
def global_events_dispatcher(event): if event == 'event_1': return call_event_handler_1() elif event == 'event_2': return call_event_handler_2() elif event == 'event_3': return call_event_handler_3() else: raise UnknownEventError
这种代码岂但有多个条件分支,看起来比较复杂,同时也是反复代码的一种体现。
咱们能够利用 Python 的dict
对这段条件分支代码进行重构,缩小条件分支,去除反复代码。
def global_events_dispatcher(event): event_handlers = { 'event_1': call_event_handler_1, 'event_2': call_event_handler_2, 'event_3': call_event_handler_3, } if event_handlers.get(event, None): func = event_handlers(event) return func() raise UnknownEventError
重构后代码只有一个条件判断语句,函数的行为没有产生任何变动,让整个函数的逻辑变得更加容易了解。
补充
对于如何重构条件分支语句,能够延长浏览《重构:改善既有代码的设计(第 2 版)》第 10 章:简化条件逻辑,外面列举了多种常见的简化条件逻辑的重构手法,并配有大量的例子,举荐浏览。