由汉诺塔想到的

回顾一下Python基础知识,发现自己基础掌握得实在是差,甚至都不敢说自己会用Python了。想想两年也看了不少书,究其原因还是练习太少吧。不每天写写代码是学不会programming的。

进入正题,一个简单的Hanoi Tower递归:

1
2
3
4
5
6
7
def move(n,a='A',b='B',c='C'):
if n == 1:
print(a,"-->",c)
else :
move(n-1,a,c,b)
print(a,"-->",c)
move(n-1,b,a,c)

主要理解分治思想和递归思想的运用吧,这个倒没什么问题,接下来就暴露基础不扎实了:

  • 用命令行执行脚本的程序入口在哪?

    • 可以自己定义一个main函数:
    1
    2
    3
    4
    5
    6
    7
    def move(n,a='A',b='B',c='C'):
    …………
    def main():
    move(3)
    main()
    • 但在很多脚本中常见的是这样:
    1
    2
    3
    4
    5
    def move(n,a='A',b='B',c='C'):
    …………
    if __name__ == '__main__':
    move(3)

    那么if __name__ == '__main__':的作用是什么呢?

    简单来讲就是直接运行脚本时,一个变量 __name__ 被赋值为 __main__ ;而当该脚本作为module被其他程序import时,__name__ 则被赋值为该脚本名称。

    也就是说,在 if __name__ == '__main__':后面的代码,直接运行脚本时会被执行,而当脚本作为module时不会执行。

    Stackoverflow上有一个回答很直观易懂,摘录部分如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    # file one.py
    def func():
    print("func() in one.py")
    print("top-level in one.py")
    if __name__ == "__main__":
    print("one.py is being run directly")
    else:
    print("one.py is being imported into another module")
    # file two.py
    import one
    print("top-level in two.py")
    one.func()
    if __name__ == "__main__":
    print("two.py is being run directly")
    else:
    print("two.py is being imported into another module")
  • 如何读取命令行参数?

    想在命令行中以参数形式输入汉诺塔层数,却发现忘了命令行参数怎么用了……真是羞耻,重新总结一下。

    • 最简单的方法:sys.argv

      sys.argv 就是命令行参数列表了,其中第一个参数argv[0]是脚本名,后面依次是输入的参数。

      1
      2
      3
      4
      import sys
      print '参数个数:', len(sys.argv)
      print '参数列表:', str(sys.argv)
    • 进阶方法:getopt模块

      在使用很多程序时,都遇到过输入类似“-a”、“-h”、“–help”之类的选项来实现不同功能。设置这种命令行选项在Python中可以通过getopt模块来实现。

      getopt模块是专门处理命令行参数的模块,用于获取命令行选项和参数,也就是sys.argv。命令行选项使得程序的参数更加灵活。支持短选项模式(-)和长选项模式(–)。

      该模块提供了两个方法及一个异常处理来解析命令行参数。

      常用的方法是getopt方法:

      1
      getopt.getopt(args, options[, long_options])

      参数说明:

      • args: 要解析的命令行参数列表。
      • options: 以列表的格式定义,options后的冒号(:)表示该选项必须有附加的参数,不带冒号表示该选项不附加参数。
      • long_options: 以字符串的格式定义,long_options 后的等号(=)表示如果设置该选项,必须有附加的参数,否则就不附加参数。
      • 该方法返回值由两个元素组成: 第一个是 (option, value) 元组的列表。 第二个是参数列表,包含那些没有’-‘或’–’的参数。

      先把网上的一个实例贴过来吧,有机会再自己写应用该模块的程序。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      #!/usr/bin/python
      # -*- coding: UTF-8 -*-
      import sys, getopt
      def main(argv):
      inputfile = ''
      outputfile = ''
      try:
      opts, args = getopt.getopt(argv,"hi:o:",["ifile=","ofile="])
      except getopt.GetoptError:
      print 'test.py -i <inputfile> -o <outputfile>'
      sys.exit(2)
      for opt, arg in opts:
      if opt == '-h':
      print 'test.py -i <inputfile> -o <outputfile>'
      sys.exit()
      elif opt in ("-i", "--ifile"):
      inputfile = arg
      elif opt in ("-o", "--ofile"):
      outputfile = arg
      print '输入的文件为:', inputfile
      print '输出的文件为:', outputfile
      if __name__ == "__main__":
      main(sys.argv[1:])

      运行该脚本:

      1
      2
      3
      4
      5
      6
      $ python test.py -h
      usage: test.py -i <inputfile> -o <outputfile>
      $ python test.py -i inputfile -o outputfile
      输入的文件为: inputfile
      输出的文件为: outputfile

还是希望自己要多想多做,脚踏实地,慢慢来。