2010-07-11 120 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

相关问题