这两天闲来无事,利用python把以前曾经用shell实现过的工具重构了下,本来想加入一些多线程以及锁的处理,但是考虑到入门级的程序,就先不搞了,以后在优化的时候可以增加多线程处理的操作,应该可以有效的提高工具的执行效率! 下面总结下常用的
Python错误异常的处理:
NameError: 尝试访问一个未申明的变量
ZeroDivisionError:
除数为零
SyntaxError: 解释器语法错误
IndexError: 请求的索引超出序列范围
KeyError:
请求一个不存在的字典关键字
IOError: 输入/输出错误
AttributeError: 尝试访问未知的对象属性
ValueError:
值错误
TypeError: 类型错误
SystemExit: 当前python应用程序需要退出
KeyboardInterupt:
用户按下CTRL+C关闭python
这些错误都在抛出异常的时候使用,筛选出来的错误类型。
try语句有两种主要形式:
try-except : 当try出现异常才会处理except函数
try-finally:不管try是否会出现异常 都会处理except函数
一个try语句可以对应一个或多个except子句,但只能对应一个finally子句,或是一个try-except-finally复合语句,例子:
-
try:
-
value = os.environ[key]
-
if key_type == 'boolean':
-
return value.lower() in "true yes".split()
-
elif key_type == 'hex':
-
return int(value, 16)
-
else:
-
return value
-
except KeyError:
-
if default_value is not None:
-
return default_value
-
else:
-
print >> sys.stderr, "Error: environment variable " + key + \
-
" not found"
-
sys.exit(1)
下面是常用的 os 和 shutil 模块常用
os.sep 可以取代操作系统特定的路径分隔符。windows下为 '\\'
os.name 字符串指示你正在使用的平台。比如对于Windows,它是'nt',而对于Linux/Unix用户,它是 'posix'
os.getcwd() 函数得到当前工作目录,即当前Python脚本工作的目录路径
os.getenv() 获取一个环境变量,如果没有返回none
os.putenv(key, value) 设置一个环境变量值
os.listdir(path) 返回指定目录下的所有文件和目录名
os.remove(path) 函数用来删除一个文件
os.system(command) 函数用来运行shell命令
os.linesep 字符串给出当前平台使用的行终止符。例如,Windows使用 '\r\n',Linux使用 '\n' 而Mac使用 '\r'
os.path.split(path) 函数返回一个路径的目录名和文件名
os.path.isfile() 和os.path.isdir()函数分别检验给出的路径是一个文件还是目录
os.path.exists() 函数用来检验给出的路径是否真地存在
os.curdir 返回当前目录 ('.')
os.mkdir(path) 创建一个目录
os.makedirs(path) 递归的创建目录
os.chdir(dirname) 改变工作目录到dirname os.path.getsize(name) 获得文件大小,如果name是目录返回0L
os.path.abspath(name) 获得绝对路径
os.path.normpath(path) 规范path字符串形式
os.path.splitext() 分离文件名与扩展名
os.path.join(path,name) 连接目录与文件名或目录
os.path.basename(path) 返回文件名
os.path.dirname(path) 返回文件路径
os.walk(top,topdown=True,onerror=None) 遍历迭代目录
os.rename(src, dst) 重命名file或者directory src到dst 如果dst是一个存在的directory, 将抛出OSError. 在Unix, 如果dst在存且是一个file, 如果用户有权限的话,它将被安静的替换. 操作将会失败在某些Unix 中如果src和dst在不同的文件系统中. 如果成功, 这命名操作将会是一个原子操作 (这是POSIX 需要). 在 Windows上, 如果dst已经存在, 将抛出OSError,即使它是一个文件. 在unix,Windows中有效。
os.renames(old, new) 递归重命名文件夹或者文件。像rename()
# shutil 模块
shutil.copyfile( src, dst) 从源src复制到dst中去。当然前提是目标地址是具备可写权限。抛出的异常信息为IOException. 如果当前的dst已存在的话就会被覆盖掉
shutil.move( src, dst) 移动文件或重命名
shutil.copymode( src, dst) 只是会复制其权限其他的东西是不会被复制的
shutil.copystat( src, dst) 复制权限、最后访问时间、最后修改时间
shutil.copy( src, dst) 复制一个文件到一个文件或一个目录
shutil.copy2( src, dst) 在copy上的基础上再复制文件最后访问时间与修改时间也复制过来了,类似于cp –p的东西
shutil.copy2( src, dst) 如果两个位置的文件系统是一样的话相当于是rename操作,只是改名;如果是不在相同的文件系统的话就是做move操作
shutil.copytree( olddir, newdir, True/Flase)
把olddir拷贝一份newdir,如果第3个参数是True,则复制目录时将保持文件夹下的符号连接,如果第3个参数是False,则将在复制的目录下生成物理副本来替代符号连接
shutil.rmtree( src ) 递归删除一个目录以及目录内的所有内容
贴出写的代码,菜鸟级别的Python,写完这个可以继续看看Python的书了!
程序设计概念如下先读传入参数以及当前取环境变量
-
if __name__ == '__main__':
-
-
if len(sys.argv) < 2:
-
print >> sys.stderr, "Please Input product Name."
-
sys.exit(1)
-
-
global_init()
-
-
ProName = sys.argv[1].lower()
-
ProConDir = os.path.join(ConfigsDir, ProName + ".txt")
-
if not os.path.exists(ProConDir):
-
print >> sys.stderr, "Don't find %s config file in %s folder." % (ProName, ProConDir)
-
sys.exit(1)
环境变量如下:
-
def global_init():
-
global PlatFormName
-
global ProName
-
global AndroidOut
-
global AndroidTop
-
global ConfigsDir
-
global WorkDir
-
global ReleaseDvPkgName
-
global ReleasePvPkgName
-
global ReleasePvPkgOut
-
global ReleaseDvPkgOut
-
global BuildVersion
-
-
WorkDir = os.getcwd()
-
try:
-
AndroidOut = get_env_options(key='ANDROID_PRODUCT_OUT')
-
AndroidTop = get_env_options(key='ANDROID_BUILD_TOP')
-
PlatFormName = get_env_options(key='TARGET_PRODUCT')
-
BuildVersion = (get_env_options(key='TARGET_BUILD_VARIANT')) + "." + (get_env_options(key='USER'))
-
except KeyError:
-
print >> sys.stderr, "Error: Pleasr set Android ENV."
-
sys.exit(1)
-
-
ConfigsDir = os.path.join(AndroidTop, "vendor/borqs/products")
-
ReleaseDvPkgName = "dv_package"
-
ReleasePvPkgName = "pv_package"
-
ReleaseDvPkgOut = os.path.join(AndroidOut, ReleaseDvPkgName)
-
ReleasePvPkgOut = os.path.join(AndroidOut, ReleasePvPkgName)
有些都是Android标准环境变量哦,哇哈哈
然后就是创建3个需要执行顺序的字典,从参数传进来的文件逐行读取,分别存放在不同执行级别的字典中:
-
ConFb = open(ProConDir, 'r')
-
-
for line in ConFb.readlines():
-
line=line.strip('\n')
-
val = [line.split('=')[0].lower(), line.split('=')[1].lower()]
-
-
if val[1] == '1' and val[0][0:6] == 'stitch':
-
StitchRunFunDict[val[0]]=val[1]
-
elif val[1] == '1' and val[0][0:7] == 'include':
-
IncludeRunFunDict[val[0]]=val[1]
-
elif val[1] == '1' and val[0][0:4] == 'pack':
-
PackRunFunDict[val[0]]=val[1]
-
else:
-
continue
-
-
ConFb.close()
然后按照顺序执行三个循环,执行需要干的工作,这里以后我打算修改成多线程执行,可以大大加快执行速度:
-
for key in StitchRunFunDict.keys():
-
print 'key=%s, value=%s' % (key, StitchRunFunDict[key])
-
try:
-
locals()[key + "_function"](key)
-
except KeyError:
-
print "Dont't have %s_function, Please puls the function." % (key)
-
continue
-
-
for key in IncludeRunFunDict.keys():
-
print 'key=%s, value=%s' % (key, IncludeRunFunDict[key])
-
try:
-
locals()[key + "_function"](key)
-
except KeyError:
-
print "Dont't have %s_function, Please puls the function." % (key)
-
continue
-
-
for key in PackRunFunDict.keys():
-
print 'key=%s, value=%s' % (key, PackRunFunDict[key])
-
try:
-
locals()[key + "_function"](key)
-
except KeyError:
-
print "Dont't have %s_function, Please puls the function." % (key)
-
continue
其中的 locals
()[key
+ "_function"](key
)这句话就是找到相应的执行函数。
这里以后可能要改成,创建不同的对象,然后去执行相应的执行函数。
剩下的执行函数我就不贴出来。
这套设计的方案,主要是方便功能的添加与删除,完全从参数中的配置文件来选择,当然你需要实现这个功能可以!
在贴出来配置文件格式
-
STITCH_BOOT=1
-
STITCH_RECOVERY=1
-
STITCH_DROIDBOOT=1
-
STITCH_DROIDBOOT_IMG_POS=1
-
INCLUDE_SOFTFUSE=0
-
INCLUDE_PV_IFWI=1
-
INCLUDE_DV_IFWI=1
-
PACK_DV=1
-
PACK_PV=1
初次写Python函数,感觉如果不加入对象的思想,感觉和shell很像,但是不加入对象的思想的话,还能叫做Python吗? 哇哈哈,所以我现在写的只不过是一个shell流程的Python工具,以后要继续努力学习Python。
阅读(2303) | 评论(0) | 转发(1) |