2013-05-30 157 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' *是一個元組。 –