<p>这在FineManual(tm)中有解释:<a href="https://docs.python.org/2/tutorial/controlflow.html#more-on-defining-functions" rel="nofollow noreferrer">https://docs.python.org/2/tutorial/controlflow.html#more-on-defining-functions</a></p>
<p>注意,在Python中,定义可选参数默认值的表达式在执行<code>def</code>语句(这是顶级函数的第一次导入)时仅为eval'd ony一次,这可能会导致意外行为(cf<a href="https://stackoverflow.com/q/1132941/41316">"Least Astonishment" and the Mutable Default Argument</a>)。</p>
<p>此外,“默认值”必须是<em>表达式</em>,而不是语句,因此不能在此处进行任何错误处理。wrt/您尝试使用<code>sys.argv[2]</code>作为默认值的情况,至少有两个原因是错误的:</p>
<ol>
<li>正如您已经注意到的,如果<code>len(sys.argv) < 3</code></li>
<li>它使您的功能依赖于<code>sys.argv</code>,因此您不能在不同的上下文中重用它</li>
</ol>
<p>这里正确的解决方案是处理“入口点”代码(即<code>__main__</code>部分)中的所有用户输入(<code>sys.argv</code>或其他内容)-您的函数不应该知道参数值来自何处(<code>sys.argv</code>、HTTP请求、文本文件或其他内容)。</p>
<p>因此,长话短说:要么使用硬编码值(如果有意义的话)要么使用“sentinel”值(<code>None</code>是一个很好的候选者)作为可选参数的默认值,并在<code>__main__</code>部分(或者在<code>main()</code>部分调用的<code>__main__</code>函数中执行所有用户输入解析,这样就不会污染模块的具有不相关变量的命名空间):</p>
<pre><code>def func(arg, optarg=None):
#code here
def main(*args):
#parse args
#call func with the right args
if __name__ == "__main__":
import sys
main(*sys.argv)
</code></pre>