不止一次听到对默认参数的批评, 因为它让 API 变得模糊.
对默认参数的批评
对默认参数的批评, 主要是在其他语言中 (静态语言, 动态语言由于没有『方法重载』, 出现得少). 究其原因, 我觉得主要是: 语法上不够自然, 对看代码的人不友好.
比如 C++ 中:
一个方法
void DoSomething(int a, int b=100);
调用的人
- DoSomething(1)
- DoSomething(1, 1000)
复制代码
. 如果没有充分的上下文, 乍一看, 还以为这是两个重载方法, 给人带来了心智负担.
所以在 C++ 中, 一般比较少使用默认参数.
Python 是如何处理的
Python 中, 也不能避免上面的缺陷, 甚至缺陷更加厉害 . 比如还是上面的代码, Python 允许你这样写代码:
- DoSomething(1)
- DoSomething(1, 1000)
- DoSomething(1, b=1000)
复制代码
这就很坑爹了, 要是参数一多, 组合情况更加多, 甚至还莫名其妙报错. 1 是正常操作, 2 是坏习惯的写法, 3 是好习惯的写法.
所以, 从这个角度来看, Python 似乎让情况变得更加糟糕了. 那么, 是否应该『因为怕噎着, 所以干脆不吃饭, 饿死』?
正确的做法
完全不必如此. 并且, 这是体现作为 API 作者的素养的机会来了.
首先是 Python 3(假设 >= 3.5). 利用新特性即可, 让调用端只能使用第 3 种写法. 比如
- def DoSomething(a, *, b=10, c=100, d=1000):
- pass
调用端只能:
要么按照不去理会默认参数: DoSomething(100)
要么多打点字符: DoSomething(100, b=100, c=11, d=0) ( 这样, 代码美观很多. )
复制代码
其次是 Python 2. 解决方案是: 换 Python 3. 或者你假设你旁边的 Python 使用者, 都是高素质人才, 大家都是坚定按照最佳实践写代码 (这种概率有多大?).
另外, 现在已经没有人或文章, 谈论 2 和 3 的问题了. 保守派的新项目, 都是 Python 3.5 起 了 ( 俺们的新项目是 3. 6 ).
来源: https://juejin.im/post/5b9dcdccf265da0a9a395dc9