学习Python,有没有更好的方法来编写它?

时间:2010-07-11 19:50:37

标签: python

我正在学习Python(2.7)并测试到目前为止我学到的东西我写了一个温度转换器,将摄氏温度转换为华氏温度,我想知道我的代码是否可以更好地编写为更快或更多Pythonic。有人可以告诉我if __name__ == '__main__': main()是否有实际名称(出于好奇心)?

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

4 个答案:

答案 0 :(得分: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. 当您应该检查argv时,您正在检查args的长度为2。
  5. to_cto_f函数不需要temp变量,只需返回表达式。
  6. 虽然其他人是正确的,您可以将main()函数放在顶层,但使用if __name__样式是一种很好的形式,这样您就可以导入此模块并使用其他代码中的函数
  7. 字符串格式化比打印语句中的字符串和值混合更好。
  8. args[1]似乎已足够,我为了简洁而将其分配到t
  9. 我更喜欢导入sys,例如使用sys.argv
  10. 我总是将依赖条款放在新行上,而不是if blah: doit()
  11. 修正华氏度的拼写

答案 1 :(得分:4)

if __name__ == '__main__':模式适用于编写要供其他代码使用的模块,但需要在模块中使用一些测试代码。

如果直接运行模块,它会运行if块中的内容。如果从其他地方导入,则不会。

因此,我建议您保留if __name__ == '__main__':阻止,因为您可以执行以下操作:

from temp_conv import c_from_f
print c_from_f(73)
如果您将此temp_conv.py命名为

,则稍后会在另一段代码中

答案 2 :(得分:3)

对奈德答案的一些改进。 在Python2.7中/默认情况下仍会截断结果,因此您需要从division导入__future__,否则(c * 9/5) + 32总是向下舍入,这会导致精度降低。
例如,如果36C是96.8F,那么最好返回97而不是96

convert中不需要返回语句。默认情况下会返回None。如果出现问题,您可以提出异常

现在优先使用"".format()

进一步的改进是使用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:]))

答案 3 :(得分: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是一个非常强大的选项解析器,如果您打算经常编写这些类型的程序,我认为值得学习。