打印带有和没有“字符串格式”的字符串

时间:2013-05-30 18:49:16

标签: python printing urllib2 string-formatting

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

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语句中得到了有趣的结果:

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'),)

任何人都可以解释为什么打印sts对于打印2,3和4有何不同?它仅使用单个%s格式化字符串以正确的格式打印。我不认为它与 urllib2 有任何关系。我在这里错过了什么?谢谢!

1 个答案:

答案 0 :(得分:2)

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

所以这个:

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

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

所有其他例子:

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

...只需打印str(sts),因为他们没有这条神奇的规则。

在您的情况下,sts是一个1元素的元组。因此,str(sts[0])就是您想要的,因为str(sts)等同于'(' + repr(sts[0]) + ',)'。你很幸运Print-1,因为你意外地达到了魔法规则。 (你甚至可能不知道er.args是一个元组。)


这种混淆正是为什么人们不断建议弃用% - 格式化,或者改变它以便它总是把它的论点视为一个序列等等。但是因为它对于这么多快速和肮脏的目的来说非常方便,这些建议总是被打败。

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