0

我试图找出为什么我会看到这个。这是代码片段:

def check_status(addr,port=80):

    import urllib2

    if not addr.startswith('http://'): addr = "http://" + addr
    req = urllib2.Request(addr+":"+str(port))

    try:
        res = urllib2.urlopen(req,None,10)
        sts = str(res.code)

    except urllib2.URLError, er:
        sts = er.args

    print "Print-1\t: %s" % sts
    print "Print-2\t:", sts
    print "{0}\t: {1}".format('Print-3',sts)
    return sts


url = "google.comm"
sts = check_status(url)
print "Print-4\t: %s  %s" % (url, sts)

运行脚本,我在打印语句上得到了有趣的结果:

Print-1 : [Errno 8] nodename nor servname provided, or not known
Print-2 : (gaierror(8, 'nodename nor servname provided, or not known'),)
Print-3 : (gaierror(8, 'nodename nor servname provided, or not known'),)
Print-4 : google.comm  (gaierror(8, 'nodename nor servname provided, or not known'),)

谁能解释一下为什么stsprint-2、3 和 4 的打印方式不同?它仅使用单个格式字符串以正确的格式打印。%s我认为这与urllib2没有任何关系。我在这里想念什么?谢谢!

4

1 回答 1

2

将单个参数传递给%是不明确的,因此 Python 应用了在某些情况下令人困惑的规则,但通常是您想要的答案。如果参数不是元组,则将其视为包装在 1 元素元组中。

所以这:

print "Print-1\t: %s" % sts

... 打印str(sts[0])它是否是 1 元素元组,TypeError如果它是任何其他长度的元组,则引发 a,但str(sts)如果它只是一个字符串(或 anException或其他)则打印。

您的所有其他示例:

print "Print-2\t:", sts
print "{0}\t: {1}".format('Print-3',sts)
print "Print-4\t: %s  %s" % (url, sts)

......只是 print str(sts),因为他们没有这个神奇的规则。

在您的情况下,sts是一个 1 元素元组。所以,str(sts[0])就是你想要的,因为str(sts)相当于'(' + repr(sts[0]) + ',)'. 你很幸运,Print-1因为你偶然碰到了魔法规则。(你甚至可能不知道那er.args是一个元组。)


这种混淆正是人们不断建议弃用%-formatting 或更改它以使其始终将其参数视为序列等的原因。但由于它对于许多快速和肮脏的目的非常方便,因此这些建议总是被否决。

避免混淆自己的一种方法是始终将单个参数作为元组传递:print "Print-0\t: %s" % (sts,)。或者只是不使用%-formatting。

于 2013-05-30T18:58:48.930 回答