我试图找出为什么我看到这个。这是代码片段:
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 有任何关系。我在这里错过了什么?谢谢!
答案 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,)
。或者只是不要使用%
- 格式化。