2013-05-30 158 views
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语句有趣的结果:

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

出于好奇,你为什么这样做'STS = STR(res.code)'的成功案例,但在'错误的情况下不'STS = STR(er.args)? (如果你这样做了,这个问题永远不会出现,你不会学到新的东西,所以它可能是最好的。只是,我很难理解为什么一个整数不是一个可接受的值传递,但任意异常参数的元组是。) – abarnert

+0

@abarnert:这真是一个有趣的问题。我想我是这样做的,以确保我重新调整一个字符串,而不是一个整数。这实际上是我的一个非常古老的脚本,我正在努力添加一些额外的东西,并被结果击中。顺便说一句,str(er.args)对我来说根本不会改变任何事情。干杯!! – MacUsers

回答

2

传递的一个参数%是模糊的,所以Python应用于的交代不清的在某些情况下的规则,但大多数情况下,你想要的答案。如果参数不是元组,则将其视为包装在1元组元组中。

所以这样的:

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

...打印str(sts[0])如果它是一个1元的元组,并提出了一个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是一个元组。)


这种困惑也正是为什么人们不断暗示自嘲% -formatting,或改变它,所以它总是将它的参数作为序列等但是因为这么多快速的肮脏目的非常方便,这些建议总是被打败。为了避免混淆自己

一种方法是总是传递,甚至一个参数作为一个元组:print "Print-0\t: %s" % (sts,)。或者只是不要使用%格式。

+0

'.args'是一个元组。 –

+0

@MartijnPieters:是的,这就是为什么'Print-1'将它与其他人区别开来的原因:因为与其他人不同,它打印'str(sts [0])'如果它是一个元组(它是)。但我编辑了答案,使其更清晰。 – abarnert

+0

是的,只是确认'.args' *是一个元组。 –