Python 如何正确使用默认值

Python 如何正确使用默认值,python,Python,鉴于以下功能: def httpstatus(self, url, data=None, timeout=None): if timeout is None: timeout = socket._GLOBAL_DEFAULT_TIMEOUT urlopen(url, data, timeout) 超时参数应该是可选的。但是如果是ommited,我想使用套接字。\全局\默认\超时值,如代码所示。但是,该成员是受保护的成员。这似乎不是正确的方法。所以不同的方法 de

鉴于以下功能:

def httpstatus(self, url, data=None, timeout=None):
    if timeout is None:
        timeout = socket._GLOBAL_DEFAULT_TIMEOUT
    urlopen(url, data, timeout)
超时参数应该是可选的。但是如果是ommited,我想使用套接字。\全局\默认\超时值,如代码所示。但是,该成员是受保护的成员。这似乎不是正确的方法。所以不同的方法

def httpstatus(self, url, data=None, timeout=None):
    if timeout is None:
        urlopen(url, data)
    else:
        urlopen(url, data, timeout)
哎呀,那个更脏了

返回套接字默认超时的正确方法是什么?

您可以使用:

def httpstatus(self, url, data=None, timeout=None):
    kwargs = {}
    if timeout is not None:
        kwargs['timeout'] = timeout
    urlopen(url, data, **kwargs)
甚至:

def httpstatus(self, url, data=None, **kwargs):
    # Don't forget to mention in documentation that all
    # extra arguments are passed to urlopen as is.
    urlopen(url, data, **kwargs)

如果您确实不想使用受保护的var,只需从套接字中获取编号,并从您获取编号的位置进行注释:

# settings
default_timeout = 100 # socket._GLOBAL_DEFAULT_TIMEOUT
另一个选项是使用默认值的
getattr

default_timeout = getattr(socket, '_GLOBAL_DEFAULT_TIMEOUT', 100)

def httpstatus(self, url, data=None, timeout=default_timeout):
    urlopen(url, data, timeout)

在我看来,你写的第一个变体不太明显,可读性差,更容易出错,而且通常比OP提交的最终版本更糟糕。第二个版本也不是很好,因为httpstatus()的调用者不需要知道它的实现是什么,特别是如果调用者愿意,可以添加urlopen()参数(鉴于Python source中普遍缺乏文档,他怎么知道呢?@jamond,你部分是对的:你提到的第二个版本的问题确实存在。但在Python中,您的文档中提到所有额外参数都传递给某个库函数是很常见的。@jarmod,您能解释一下:调用方可以添加urlopen()参数。。。我已经读了5遍,但仍然没有抓住这里的要点。@jamond如果代码完全如图所示,那么
if
-方法是可以的,但我确信这只是一个例子。在实际调用
urlopen
之前会有很多事情发生,在实际调用时,已经不清楚发生了什么;如果,你甚至可能会得到许多分支。@Paul好吧,在这种特殊情况下,这是不可能发生的。但是想象一下,
urlopen
有另一个参数,比如,
do_bad_thing
ans,如果它设置为
True
它做了一件坏事。在我的第二个示例中,函数的用户可能也会通过函数将此错误参数传递给
urlopen
。使用受保护的成员似乎很奇怪,或者在Python中这种情况并不少见?@Paul您想使用它吗。。。所以我认为在哪里使用它并不重要。您可以使一些模块/类选项等于这个受保护的套接字变量,并在函数定义中使用您的本地变量。另外,默认值不会从套接字库以及urlopen的参数序列中消失。@Paul嗯,Python中没有受保护的成员。他们礼貌地称他们为非公众人士。使用它们绝对不是个好主意。PEP-8明确表示,它们不打算由第三方(即您)使用。不知道是谁在按这里的-1按钮。。。我不确定如果你在包装
urllib2.urlopen
,为什么不使用
*args
**kwargs
def httpstatus(self,*args,**kwargs)
?@Blender我肯定他不仅仅是在包装,这只是一个很小的例子…@Blender,现在我只是包装,但我对什么是好方法感到好奇。也许我不应该寻找一个通用的方法。