python之CWD与命令行参数

一些变量

  • 当前工作路径(CWD)
    os.getcwd可以获取脚本启动目录, 许多文件工具隐式地使用该变量。
  • 命令行参数
    sys,argv可以获取在命令行键入的启动参数,将其作为脚本的输入。
  • shell变量
    os.environ可以获取运行他的shell(或父程序)中命名的变量,并传给脚本。
  • 标准流
    sys.stdin,stdout和stderr是三个核心的命令行shell工具,负责输入\输出流,他们可以被脚本以如下方式使用
    print,os.popen调用,subprocess,io.StringIO类等

这些工具可以用作输入脚本,配置参数等。

当前工作路径

  • 除非指定了绝对路径,否则当脚本处理文件时将始终默认他们存在于CWD,脚本可以使用os.getcwd获取明确的cwd路径
    使用os.chdir可以改变他的cwd。
  • 没有完整目录路径的文件名将被映射到cwd路径,和你的PYTHONPATH设置无关
  • 一个脚本总是启动于cwd,而非他所在的目录。反之import 永远首先先搜索文件所在目录,而非CWD(除非脚本刚好在cwd目录)

cwd、文件和import路径

在shell命令行中python dir1\dir2\file.py运行该脚本时,cwd是你键入该命令时所处的路径,而非dir1\dir2。另一方面python自动
将脚本所在目录添加到模块搜索路径的最前面。因而无论从哪里运行,file.py总是可以导入dir1\dir2中的其他文件。

C:…\Mybook_python_programming\test_3\whereami.py

	import os, sys
	print('my os.getcwd =>', os.getcwd())                       # 输出cwd执行目录
	print('my sys.path  =>', sys.path[:1])                      # 输出第一个导入路径

CWD会如预期打印出当前工作路径,同时该路径将会被加载到模块搜索器的最前端

	my os.getcwd => C:\...\Mybook_python_programming\test_3
	my sys.path  => ['C:\\...\\Mybook_python_programming\\test_3']

但是如果我们在别的路径下运行该脚本,cwd会随之改变(及我们输入命令的路径),并且python会把所在路径添加到模块搜索路径的最前面
从而使得脚本能看到它所在的所有文件。比如当从上一级目录(…)运行时,添加与sys.path最前面的system将会是whereami.py搜索导入
模块的第一个目录,从而将导入指回脚本所在目录。当没有提供完整路径的文件名时,将会被映射到CWD而不是system目录

	(environment) C:\..\Mybook_python_programming>cd test_1
	(environment) C:\..\Mybook_python_programming\test_1>python ..\test_3\whereami.py
	my os.getcwd => C:\..\Mybook_python_programming\test_1
	my sys.path  => ['C:\\..\\Mybook_python_programming\\test_3']

避免以下两个陷阱

  • 如果不确定脚本的执行路径,最好使用完整的目录路径限定的文件名。
  • 命令行运行脚本不能总是依赖于CWD来导入不存在他所处目录的文件,而应使用PYTHONPATH的设置和包导入路径来访问其他目录中的模块。

CWD和命令行

CWD和导入搜索路径的区别

	C:\temp> pyhton c:\...\PP4E\TOOLs\cleanpyc.py 						process cwd

虽然脚本在TOOLs中,但他在C:\temp上启动,所以它将处理C:\temp中的文件(CWD,非文件所在目录)。要使脚本处理别的文件可以简单的cd到
所要处理的文件目录来改变CWD

	C:\temp> cd C:\PP4thEd\Examples
	C:\PP4thEd\Examples> python c:\...\PP4E\TOOLs\cleanpyc.py         	process cwd

由于CWD通常是隐含的,与在python脚本后传递参数的方式相比,cd命令更加清晰,可以指定脚本处理那个目录

	C:\...\PP4E\TOOls> python find.py "*.py" C:\temp    				process name dir
  • 以TOOLs为CWD,使用find.py文件处理temp下的.py文件

  • 在该命令行中, CWD是find.py所处的路径,但在命令行中已经明确指定了要处理的脚本路径(C:\temp), 因此与CWD无关。如果我们想要用一个路径
    的文件去处理另一个路径下的文件,只需要将下面的路径传给两者:

      C:\temp>python c:\...\PP4E\TOOLs\find.py  "*.cxx"  C:\PP4thEd\Examples
    

以temp为CWD,调用TOOLs中的find.py文件处理Examples中的.cxx文件,命令与CWD无关

  • 在命令行中的CWD 即是最开始的 X:…>

##命令行参数
pyhton可以通过sys模块获取脚本启动时命令行输入的信息,通常他们被称为命令行参数,以内置字符串列表的形式存于sys.argv中,与C的argv数组很类似
交互命令行方式启动的python没有命令行参数被传入,所以argv是空串。

	>>> import sys
	>>> sys.argv
	['']

想要看到参数,我们得从shell命令行启动脚本。

文件:C:/…/Mybook_python_programming/test_3/testargv.py

	import sys
	print(sys.argv)

该脚本将打印出命令行参数列表,无论以什么方式启动,列表的第一项均为所执行脚本的名字。

	(environment) C:\...\Mybook_python_programming>cd test_3

	(environment) C:\...\Mybook_python_programming\test_3>python testargv.py
	['testargv.py']

	(environment) C:\...\Mybook_python_programming\test_3>python testargv.py spam eggs chees
	['testargv.py', 'spam', 'eggs', 'chees']

	(environment) C:\...\Mybook_python_programming\test_3>python testargv.py -i data.txt -o results.text
	['testargv.py', '-i', 'data.txt', '-o', 'results.text']

上述最后一个命令为一种惯例,类似于function参数,,命令行参数通过位置或使用“-name value”词语组来传递。

如同函数参数的作用,命令行参数扮演着同样重要的角色,它们都为程序传递可变信息。由于不需要硬编码,它们使脚本更通用。

解析命令行参数

一旦使用命令行参数, 你会发现直接操作参数列表是不容易的。程序在启动的时候会将它们转换为更易用的结构。如下示例的脚本是扫描argv列表
查询 -optionname optionvalue值对,并以optionname为键值保存到字典结构中方便使用。

文件:C:/…/Mybook_python_programming/test_3/testargv2.py

	"collect command-line options in a dictionary"

	# 根据传入的命令行参数,返回一个名行参数键值对的字典
	def getopts(argv):
	    opts = {}
	    # 直到列表为空
	    while argv:
	        # 如果列表的第一个元素的第一个符号为'-',说明这是一个键
	        if(argv[0][0] == '-'):
	            # 将第一个元素设置为键,将紧跟的第二个元素设为该键的值
	            opts[argv[0]] = argv[1]
	            # 更新参数列表将前两个元素切掉
	            argv = argv[2:]
	        # 如果不是一个键,直接将该元素切掉
	        else:
	            argv=argv[1:]
	    return opts

	if __name__ == '__main__':
	    from sys import argv
	    myargs = getopts(argv)
	    if '-i' in myargs:
	        print(myargs['-i'])
	    print(myargs)

你可能感兴趣的:(x系统编程)