Python第十天 print >> f,和fd.write()的区别 stdout的buffer 标准输入 标准输出 从控制台重定向到文件 标准错误 重定向 输出流和输入流 捕获sys.exit()调用 optparse argparse
目录
输出流和输入流
cat 12.rpm |ssh 192.168.2.6 "cat - >/tmp/12.rpm"
函数名:如果由多个单词组成,第二个单词的首字母应该大写
类名:如果由多个单词组成,每个单词的首字母应该大写
变量名:全部小写或者单词之间用下划线
#!/usr/bin/python和#!/usr/bin/env python的区别
/usr/bin/env表示到$PATH环境变量去找python执行文件,如果当前系统有两套python,那么不需要更改脚本内容
如果使用/usr/bin/python 绝对路径,就需要更改脚本
bash也有这种用法:#!/bin/bash和#!/usr/bin/env bash
Python如何处理管道输入输出
Python处理命令行参数
OS.path对文件路径的处理
逐步实现python版的wc命令
示例 1
#!/usr/bin/env python#-*- coding:utf-8 -*-#__author__="huazai"
"""pycharm 使用指南
Date:2016.08.12"""
importsys#sys.stdin 就是一个文件类,Linux里一切皆文件#input = sys.stdin input保存为文件描述符对象,相当于一个类sys.stdin实例化为一个对象input#读取input时候按ctrl+d终止输入
input=sys.stdindeflineCount(f):
n=0for i inf:
n+= 1
returnnprint lineCount(input)
从标准输入读取
示例 2
#!/usr/bin/env python#-*- coding:utf-8 -*-#__author__="huazai"
"""pycharm 使用指南
Date:2016.08.12"""
importsys
fd=sys.stdin
data=fd.read()
sys.stdout.write(data+"\n")print "你好"
文件对象的方法:
f.read() 按ctrl+d终止输入 ,f.read(10) 读取文件的10个字符,再运行第二次读取后10个字符,再运行第三次读取后10个字符,以此类推
f.readline() //用while遍历每一行
f.readlines() 与[i for i in f] //对文件每一行进行遍历
f.write()
f.close()
输出
#!/usr/bin/env python#-*- coding:utf-8 -*-#__author__="huazai"
"""pycharm 使用指南
Date:2016.08.12"""
importosimportsysimportstringimportgcimportsysprint "hello world"sys.stdout.write("Hello world"+'\n')
sys.stderr.write("Hello Error")
标准输出和标准错误输出
sys.stdout.write(str) :参数是字符串
sys.stderr.write(str):参数是字符串
print和stdout的区别
print通常是调用一个stdout对象的write方法
print会先进行格式转换
print会在最后加上换行符,要加逗号才能屏蔽换行符,等价于sys.stdout.write('hello'+'\n')
从控制台重定向到文件
在当前文件下新生成一个文件out.log,文件内容为hello
import sys
f_handler=codecs.open('out.log','w')
sys.stdout=f_handler
print 'hello'
捕获sys.exit()调用
执行到程序末尾,解释器自动退出,但是如果退出程序前执行某些操作,可以调用
sys.exit函数,带有一个可选整数参数返回给调用他的程序,表示你可以在主程序中捕获对sys.exit的调用,0是正常退出,其他为异常
def exitfunc():
print 'hello'
if __name__ == '__main__':
sys.exitfunc = exitfunc() # 设置捕获时调用的函数
print 'aaaaaa'
sys.exit(1) # 退出前调用exitfunc()函数,然后退出
print 'there' # 这句不会执行
print >> f,和fd.write()的区别
fd.write()只能输入字符串,输入数字要先用str()函数转换为字符串或者或者格式化("%d\n" % i)
print >> fd,可以直接输入int
print >> fd,"Hello world, I'm writting to file",11,200,300,400,500
fd = codecs.open('tmp','w')
fd.write('123')
示例
#!/usr/bin/env python#-*- coding:utf-8 -*-#__author__="huazai"
"""pycharm 使用指南
Date:2016.08.12"""
importosimportsys
with open('F:\ a.txt', 'a') as f: #以写的方式打开
print >> f, "Hello world, I'm writting to file", 11 #用print往文件描述符里写内容,可以输入数字
#等价于
f.write("Hello world, I'm writting to file:"+str(11)) #用write不能输入数字要先str函数转换为字符串或者格式化("%d\n" % i)
print >> sys.stderr, "Hello world, I'm writting to file", 11 #向标准错误输入内容
stderr和重定向
#!/usr/bin/env python
importsysprint >> sys.stderr, "I am going to stderr"sys.stdout.write("I am standard output\n")
python print2stderr.py2> /dev/null
#写入到标准错误
print >> sys.stderr ,"Hello world, I'm writting to file",11,200,300,400,500python xx.py2>/dev/null 可以重定向
------------------------------------------------------
stdout的buffer
python命令的-u 选项
文件对象的.flush() 方法
#!/usr/bin/env python#-*- coding:utf-8 -*-#__author__="huazai"
"""pycharm 使用指南
Date:2016.08.12"""
importosimportsysimporttimefor i in range(1,10):
sys.stdout.write("str:%d\n" %i)
time.sleep(1)
sys.stdout.flush()#
#python buffer.py | cat -#python -u buffer.py | cat -#-u表示不需要buffer
--------------------------------------------------
简单的word count
day04:包名
wc:模块名
wordCount:函数名
from day04 import wc
#!/usr/bin/env python#-*- coding:utf-8 -*-#__author__="huazai"
"""pycharm 使用指南
Date:2016.08.12"""
from sys importstdin
data=stdin.read()
chars=len(data)
words=len(data.split())
lines= data.count('\n')print "%(lines)s %(words)s %(chars)s" %locals()
或者print "%(lines)s %(words)s %(chars)s" % {'lines':lines,'words':words,'chars':chars}#可以用管道符进行调用cat /etc/hosts |python wc.py
locals()返回一个字典对象,代表当前的变量情况
#!/usr/bin/python
import sys
data = sys.stdin.read()
chars = len(data)
words = len(data.split())
lines = data.count('\n')
print "%(lines)s %(words)s %(chars)s" % locals()
locals()返回一个字典对象,代表当前的变量情况
下面两种方法都可以
print "%s %s %s " %(chars,words,lines)
print "%(lines)s %(words)s %(chars)s" % locals()
#!/usr/bin/env python#-*- coding:utf-8 -*-#__author__="huazai"
"""从标准输入或参数读取文件内容
Date:2016.08.12"""
#!/usr/bin/python
importsysimportosif len(sys.argv) < 2:
data=sys.stdin.read()else:try:
fn= sys.argv[1]exceptIndexError:print "please follow a argument at %s" % __file__ #__file__内置变量表示脚本名
sys.exit()if notos.path.exists(fn):print "%s is not exists" %fn
sys.exit()
with open(fn) as fd:
data=fd.read()
chars=len(data)
words=len(data.split())
lines= data.count('\n')print "%(lines)s %(words)s %(chars)s" %locals()#print sys.argv 返回一个列表 ,argv本身是一个属性
--------------------------------------------------------
optparse
(2.7版本后将被移除)
真正的命令行参数,代替sys.argv[],比如 ls /etc/passwd -l,sys.argv[]只能获取到参数的索引位置,但是准确位置无法获取,
比如获取-l参数,-l可以写在前面又可以写在后面
ls /etc/passwd -l ,ls -l /etc/passwd
OptionParser是一个类
-c、--chars:命令行选项
dest:为选项定义变量名,值characters就是’-c’选项的名字,同理,words就是‘-w’选项的名字,lines就是‘-l’选项的名字,每个选项就是一个变量,选项的值就是变量的值
default=False:characters的默认值False,意思是默认情况下命令不带-c选项
help:选项的解释说明部分
改写wc程序
支持 -l -w -l选项
支持文件参数和管道输入
多文件计算总行数
程序中使用函数
示例1#!/usr/bin/env python#-*- coding:utf-8 -*-#__author__="huazai"
"""从标准输入或参数读取文件内容
Date:2016.08.12"""
from optparse importOptionParserimportsys, os#parser = OptionParser()
parser = OptionParser("Usage: %prog [file1] [file2]...")
parser.add_option("-c","--chars",
dest="characters",
action="store_true",
default=False,
help="only count characters", )
parser.add_option("-w","--words",
dest="words",
action="store_true",
default=False,
help="only count words", )
parser.add_option("-l","--lines",
dest="lines",
action="store_true",
default=False,
help="only count lines", )
options, args= parser.parse_args() #返回选项字典 options是一个类 可以直接调用选项(options.words)和参数列表
printoptions, args,if not (options.characters or options.words oroptions.lines):
options.characters, options.words, options.lines=True, True, True
data=sys.stdin.read()
chars=len(data)
words=len(data.split())
lines= data.count('\n')ifoptions.lines:printlines,ifoptions.words:printwords,ifoptions.characters:printchars,
调用方式:cat/etc/passwd |python wc.py
示例2#!/usr/bin/env python#-*- coding:utf-8 -*-#__author__="huazai"
"""pycharm 使用指南
Date:2016.08.12"""
importsysimportosfrom optparse importOptionParserdefopt():
parser= OptionParser("Usage: %prog [option] [file1] [file2]")
parser.add_option("-c", "--char",
dest="chars",
action="store_true",
default=False,
help="only count chars")
parser.add_option("-w", "--word",
dest="words",
action="store_true",
default=False,
help="only count words")
parser.add_option("-l", "--line",
dest="lines",
action="store_true",
default=False,
help="only count lines")
options, args=parser.parse_args()returnoptions, argsdefget_count(data):
chars=len(data)
words=len(data.split())
lines= data.count('\n')returnlines, words, charsdefprint_wc(options, lines, words, chars, fn):ifoptions.lines:printlines,ifoptions.words:printwords,ifoptions.chars:printchars,printfndefmain():
options, args=opt()if not (options.lines or options.words oroptions.chars):
options.lines, options.words, options.chars=True, True, Trueifargs:
total_lines, total_words, total_chars=0, 0, 0for fn inargs:ifos.path.isfile(fn):
with open(fn) as fd:
data=fd.read()
lines, words, chars=get_count(data)
print_wc(options, lines, words, chars, fn)
total_lines+=lines
total_words+=words
total_chars+=charselifos.path.isdir(fn):print >> sys.stderr, "%s: is a directory" %fnelse:
sys.stderr.write("%s: No such file or direcotry\n" %fn)if len(args) > 1:
print_wc(options, total_lines, total_words, total_chars,'total')else:
data=sys.stdin.read()
fn= ''lines, words, chars=get_count(data)
print_wc(options, lines, words, chars, fn)if __name__ == '__main__':
main()#main()函数不想让其他模块调用,不加if __name__ == '__main__':,那么import wc这个模块的时候就会自动执行main()这个函数
注意:OptionParser不能使用-h选项,因为他内置了一个帮助选项,就是-h
parser.add_option("-h", "--host", # 改为-H ,‘--Host’
dest="host",
action="store",
default='127.0.0.1',
help="host address")
print "%s -h" % __file__
sys.exit(1)
不然会报错,参数冲突:optparse.OptionConflictError: option -h/--host: conflicting option string(s): -h
系统中的wc命令用C语言写
argparse
替代过时的optparse
使用argparse 解析命令行参数时,首先需要创建一个解析器,创建方式如下所示:
import argparse
parser = argparse.ArgumentParser()
class ArgumentParser(prog=None, usage=None, description=None, epilog=None, parents=[], formatter_class=argparse.HelpFormatter, prefix_chars='-', fromfile_prefix_chars=None, argument_default=None, conflict_handler='error', add_help=True)
prog :文件名,默认为sys.argv[0],用来在help信息中描述程序的名称。
usage :描述程序用途的字符串
description :help信息前显示的信息
epilog :help信息之后显示的信息
parents :由ArgumentParser对象组成的列表,它们的arguments选项会被包含到新ArgumentParser对象中。(类似于继承)
formatter_class :help信息输出的格式,为了美观…
prefix_chars :参数前缀,默认为'-'(最好不要修改)
fromfile_prefix_chars :前缀字符,放在文件名之前,当参数过多时,可以将参数放到文件中读取,例子中parser.parse_args([‘-f’, ‘foo’, ‘@args.txt’])解析时会从文件args.txt读取,相当于 [‘-f’, ‘foo’, ‘-f’, ‘bar’]
conflict_handler :解决冲突的策略,默认情况下冲突会发生错误,(最好不要修改)
add_help :是否增加-h/-help选项 (默认为True),一般help信息都是必须的。设为False时,help信息里面不再显示-h –help信息
argument_default: - (default: None)设置一个全局的选项的缺省值,一般每个选项单独设置,基本没用
ArgumentParser的一些方法
ArgumentParser.add_subparsers([title][, description][, prog][, parser_class][, action][, option_string][, dest][, help][, metavar])
ArgumentParser.add_argument_group(title=None, description=None)
ArgumentParser.add_mutually_exclusive_group(required=False) 互斥选项
ArgumentParser.set_defaults(**kwargs)
ArgumentParser.parse_known_args(args=None, namespace=None)
ArgumentParser.convert_arg_line_to_args(arg_line)
为应用程序添加参数选项需要用ArgumentParser 对象的add_argument 方法,该方法原型如下:
ArgumentParser.add_argument(name or flags...[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])
各个参数的含义如下:
name/flags :参数名字,参数有两种,可选参数和位置参数
添加可选参数
parser.add_argument('-f', '--foo')
添加位置参数
parser.add_argument('bar')
action : 遇到参数时的动作,默认值是store
help: 参数的帮助信息
version:参数版本
metaver:在usage 说明中的参数名称
nargs: 参数的个数,可以是具体的数字,或者是'+' 号与'*' 号。其中,'*'号表示0 或多个参数,'+'号表示l 或多个参数
const :保存一个常量
default :不指定参数时的默认值
type :参数的类型,默认为str
required :该选项是否必选,默认为True
dest :解析后的参数名称,argparse默认的变量名是--或-后面的字符串,但是你也可以通过dest=xxx来设置参数的变量名,然后在代码中用args.xxx来获取参数的值
choices :设置参数值的范围,如果choices中的类型不是字符串,记得指定type
parser.add_argument('x', type=int, choices=range(1, 4))
解析参数
解析参数需要用ArgumentParser 对象的parse_args 方法,该方法返回一个Namespace对象。
获取对象以后,参数值通过属性的方式进行访问
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('x')
>>> a = parser.parse_args(['1'])
>>> a
Namespace(x='1')
>>> type(a)
>>> a.x
'1'
示例1
importargparsedef_argparse():
parser= argparse.ArgumentParser (description='This is descript')
parser.add_argument('--host', action='store',dest='server', required=True ,default='localhost', help='connect to host')
parser.add_argument ('-t', action='store_true',default=False , dest ='boolean_switch', help= 'set a switch to true')
parser.add_argument('--thread_size', action='store', dest='thread_size',default=5, type=int, help='how much connection for database usage')
parser.add_argument('-v','--version' , action='version', version='%(prog)s 0.1')returnparser.parse_args()defmain():
parser=_argparse()print(parser)print ('host =',parser.server)print ('boolean_switch=',parser.boolean_switch)if __name__ == 'main':
main()
示例2
#!/usr/bin/python#-*- coding: utf-8 -*-
importsysimportargparsedefcmd():
args= argparse.ArgumentParser(description = 'Personal Information',epilog = 'Information end')#必写属性,第一位
args.add_argument("name", type = str, help = "Your name")#必写属性,第二位
args.add_argument("birth", type = str, help = "birthday")#可选属性,默认为None
args.add_argument("-r",'--race', type = str, dest = "race", help = u"民族")#可选属性,默认为0,范围必须在0~150
args.add_argument("-a", "--age", type = int, dest = "age", help = "Your age", default = 0, choices=range(150))#可选属性,默认为male
args.add_argument('-g',"--gender", type = str, dest = "gender", help = 'Your gender', default = 'male', choices=['male', 'female'])#可选属性,默认为None,-p后可接多个参数
args.add_argument("-p","--parent",type = str, dest = 'parent', help = "Your parent", default = "None", nargs = '*')#可选属性,默认为None,-o后可接多个参数
args.add_argument("-o","--other", type = str, dest = 'other', help = "other Information",required = False,nargs = '*')
args= args.parse_args()#返回一个命名空间,如果想要使用变量,可用args.attr
print "argparse.args=",args,type(args)print 'name = %s'%args.name
d= args.__dict__
for key,value ind.iteritems():print '%s = %s'%(key,value)if __name__=="__main__":
cmd()
示例3
#命令行参数
defopt():
parser= argparse.ArgumentParser(description='insatll MongoDB')
parser.add_argument('--disktype', '-dt',
dest="disktype",
metavar='',
required=True,
choices=['hdd', 'ssd'],
default='hdd',
help='mongodb install directory disk type, only hdd or ssd, default: hdd')
parser.add_argument('--port',
dest="port",
metavar='',
required=True,
type=int,
default='27017',
help='mongodb port number, default: 27017')
parser.add_argument('--version', '-v',
dest="version",
metavar='',
required=True,
choices=['3.4', '3.6', '4.0'],
default='4.0',
help='mongodb version, only support 3.4 or 3.6 or 4.0, default: 4.0')
parser.add_argument('--password', '-p',
dest="password",
metavar='',
required=True,
default='123456',
help='mongodb adminuser password, default: 123456')
parser.add_argument('--role', '-r',
dest="role",
metavar='',
required=True,
choices=['master', 'slave'],
default='slave',
help='mongodb install role, only master or slave, default: slave')
parser.add_argument('--installenv', '-e',
dest="installenv",
metavar='',
required=True,
choices=['production', 'test'],
default='test',
help='install environment, only production or test, default: test')
args=parser.parse_args()returnargsif __name__ == '__main__':
args=opt()if (args.disktype and args.disktype.upper() in ['HDD', 'SSD']) \and\
(args.portandstr.isdigit(args.port)) \and\
(args.versionand args.version in ['3.4', '3.6', '4.0']) \and\
(args.password) \and\
(args.roleand args.role.upper() in ['MASTER', 'SLAVE']) \and\
(args.installenvand args.installenv.upper() in ['PRODUCTION', 'TEST']):
disktype=args.disktype.upper()
mongoport=args.port
mongoversion=args.version
mongopwd=args.password
mongoip=get_host_ip()
mongorole=args.role.upper()
installenv= args.installenv.upper()
optparse模块和argparse模块比较
https://docs.python.org/2/library/argparse.html#argparse.ArgumentParser.add_subparsers
optparse.OptionParser.add_option() 替换为 ArgumentParser.add_argument()
(options, args) = parser.parse_args() 替换为 args = parser.parse_args()
optparse.OptionError optparse.OptionValueError 替换为 ArgumentError异常
OptionParser constructor version 参数 替换为 parser.add_argument('--version', action='version', version='')
python bb.py --version
3
f