2010-07-11 114 views
4

我正在學習Python(2.7)並測試我迄今爲止學到的東西,我寫了一個溫度轉換器,將攝氏溫度轉換爲華氏溫度,我想知道我的代碼是否可以寫得更好,以便更快或更加Pythonic。有人能告訴我是否有if __name__ == '__main__': main()(出於好奇)的實際名稱?學習Python,有沒有更好的方式來寫這個?

from sys import argv, exit # import argv and exit functions 

def to_f(c): # Convert celsius to ferinheight 
    temp = (c * 9/5) + 32 
    return temp 

def to_c(f): # Convert ferinheight to celsius 
    temp = (f - 32) * 5/9 
    return temp 

def main(): 
    args = argv[1:] # Creates an argument list omitting the omitting the [0] element 
    if len(argv) < 2: exit(1) # If less than two arguments 
    if args[0] == '-f': # If the first argument is -f 
     print args[1], 'ferinheight is', str(to_c(int(args[1]))), 'celsius' 
    elif args[0] == '-c': # If the first argument is -c 
     print args[1], 'celsius is', str(to_f(int(args[1]))), 'ferinheight' 
    else: exit(1) 

if __name__ == '__main__': 
    main() 

http://pastebin.com/rjeNikDt

回答

11
import sys 

def to_f(c): # Convert celsius to fahrenheit 
    return (c * 9/5) + 32 

def to_c(f): # Convert fahrenheit to celsius 
    return (f - 32) * 5/9 

def convert(args): 
    if len(args) < 2: 
     return 1 # If less than two arguments 
    t = args[1] 
    if args[0] == '-f': # If the first argument is -f 
     print "%s Fahrenheit is %s Celsius" % (t, to_c(int(t))) 
     return 0 
    elif args[0] == '-c': # If the first argument is -c 
     print "%s Celsius is %s Fahrenheit" % (t, to_f(int(t))) 
     return 0 
    else: 
     return 1 

if __name__ == '__main__': 
    sys.exit(convert(sys.argv[1:])) 

我所做的:

  1. 改變的main()名稱convert()
  2. 傳遞參數給convert()明確
  3. 更改來電exit()以回報,主要子句中調用exit()
  4. 當您應該檢查args時,您正在檢查長度爲2的argv
  5. to_cto_f函數不需要temp變量,只是返回表達式。
  6. 儘管其他人可以將main()函數放在頂層,但使用if __name__樣式是一種很好的方式,因此您可以導入此模塊並在其他代碼中使用函數。
  7. 字符串格式比混合字符串和打印語句中的值更好。
  8. args[1]看起來不夠多,爲了簡潔起見,我將它分配到了t
  9. 我比較喜歡導入sys,並使用sys.argv
  10. 我總是把相關的條款上新的生產線,從來沒有if blah: doit()
  11. 修復華氏
+0

你先生剛剛贏得了你自己的答案,謝謝!感謝Fahrenheit拼寫修正,我在拼寫和Chrome,Google,Komodo Edit和截止日期之後(Chrome高級拼寫檢查器擴展)都會告訴我這是拼錯的,但他們都不知道我想要的是什麼詞拼寫。 – 2010-07-11 20:21:12

+0

你能解釋一下'sys.exit(convert(sys.argv [1:]))'的作用嗎?它會在它退出之前這樣做,因爲沒有別的東西可以執行了? – 2010-07-11 20:28:45

+0

convert()需要一個參數列表,我使用sys.argv [1:]提供。 convert()然後返回一個狀態碼,將其傳遞給sys.exit,該狀態碼用該狀態碼退出進程。 – 2010-07-11 20:34:38

4

if __name__ == '__main__':模式是當你寫意圖由其他代碼使用的模塊,但你想要的模塊中的一些測試代碼。

如果您直接運行該模塊,它將運行該if塊中的內容。如果從其他地方導入,則不會。

所以,我會建議保持該if __name__ == '__main__':塊,因爲你可以這樣做:

from temp_conv import c_from_f 
print c_from_f(73) 

在另一段代碼後,如果您命名此temp_conv.py。

+0

謝謝,他讓我困惑了一下,因爲我清楚地記得讀過那是如果陳述是有用的。 – 2010-07-11 20:17:56

3

一對夫婦對斯內德的回答改進的拼寫。 在Python2.7 /默認情況下仍會截斷結果,因此您需要從__future__導入division,否則(c * 9/5) + 32總是舍入,導致準確性降低。
例如,如果36C是96.8F最好返回97比96

你不需要convert中的return語句。默認情況下,返回None。如果有問題,你可以提出一個例外

而且使用"".format()是nowdays首選

進一步的改進是使用optparse或類似的處理命令參數,但可能是矯枉過正這樣一個簡單的程序

from __future__ import division 
import sys 

def to_f(c): # Convert celsius to fahrenheit 
    return (c * 9/5) + 32 

def to_c(f): # Convert fahrenheit to celsius 
    return (f - 32) * 5/9 

def convert(args): 
    if len(args) != 2: 
     raise RuntimeError("List of two elememts required") 
    t = int(args[1]) 
    if args[0] == '-f': # If the first argument is -f 
     print "{0} Fahrenheit is {1} Celsius".format(t, round(to_c(t))) 
    elif args[0] == '-c': # If the first argument is -c 
     print "{0} Celsius is {1} Fahrenheit".format(t, round(to_f(t))) 
    else: 
     raise RuntimeError("First element should be -c or -f") 

if __name__ == '__main__': 
    sys.exit(convert(sys.argv[1:])) 
+0

感謝與該部門的解決方案,我確實注意到它有點關閉。 – 2010-07-12 00:35:59

+0

對於未來可能正在閱讀的用戶,您無需導入除法模塊,只需「(c * 9.0/5.0)」和「(f-32)* 5.0/9.0' – 2010-07-12 01:46:27

+1

@ Drralisk博士,當'/'在Python3中的行爲發生變化時,從'__future__'導入除法仍然是一個好主意。如果你想確保在Python3運行代碼時使用'//'運算符來進行整數除法。然後,代碼在Python2和Python3中的工作方式會相同。 – 2010-07-12 06:19:49

1
import sys 
from getopt import getopt, GetoptError 

def to_f(c): 
    return (c*9/5) + 32 

def to_c(f): 
    return (f-32) * 5/9 

def usage(): 
    print "usage:\n\tconvert [-f|-c] temp" 

def convert(args): 
    opts = None 
    try: 
    opts, args = getopt(args, "f:c:") 
    except GetoptError as e: 
    print e 

    if not opts or len(opts) != 1: 
    usage() 
    return 1 

    converters = { 
    '-f': (to_c, '{0} Fahrenheit is {1} Celsius'), 
    '-c': (to_f, '{0} Celsius is {1} Fahrenheit') 
    } 

    # opts will be [('-f', '123')] or [('-c', '123')] 
    scale, temp = opts[0][0], int(opts[0][1]) 
    converter = converters[scale][0] 
    output = converters[scale][1] 

    print output.format(temp, converter(temp)) 
    return 0 

if __name__ == '__main__': 
    sys.exit(convert(sys.argv[1:])) 

我以前getopt清理你的論點和錯誤處理。一旦確定了這個選項,我也會鞏固對給定選項採取行動的邏輯。 Getopt是一個非常強大的選項解析器,我認爲如果您經常編寫這些類型的程序,這是值得學習的。

+0

看起來比它需要更復雜,我的頭很疼。 – 2010-07-12 00:33:22

+0

真的嗎?哪一部分?如果你沒有使用getopt,我想這可能會令人困惑。 – 2010-07-12 01:08:10

相關問題