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
"""


import sys


#sys.stdin 就是一个文件类,Linux里一切皆文件
#input = sys.stdin  input保存为文件描述符对象,相当于一个类sys.stdin实例化为一个对象input
#读取input时候按ctrl+d终止输入


input = sys.stdin

def lineCount(f):
     n = 0
     for i in f:
         n += 1
         return n

print lineCount(input)



 

 

从标准输入读取



示例 2
#!/usr/bin/env python
# -*- coding:utf-8 -*-
#__author__="huazai"
"""
pycharm 使用指南
Date:2016.08.12
"""

import sys

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
"""

import os
import sys
import string
import gc

 

import sys

print "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
"""

import os
import sys






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

import sys
print >> sys.stderr, "I am going to stderr"
sys.stdout.write("I am standard output\n")
python print2stderr.py 2> /dev/null



 

 

#写入到标准错误



print >> sys.stderr ,"Hello world, I'm writting to file",11,200,300,400,500
python xx.py 2>/dev/null 可以重定向



 

------------------------------------------------------
stdout的buffer 

python命令的-u 选项
文件对象的.flush() 方法

 



#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __author__="huazai"
"""
pycharm 使用指南
Date:2016.08.12
"""

import os
import sys
import  time






for 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 import stdin

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

import sys
import os


if len(sys.argv) < 2:
    data = sys.stdin.read()
else :
    try:
        fn = sys.argv[1]
    except IndexError:
        print "please follow a argument at %s" % __file__  # __file__内置变量表示脚本名
        sys.exit()

    if not os.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 import OptionParser
import sys, 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)和参数列表
print options, args,
if not (options.characters or options.words or options.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')


if options.lines:
    print lines,
if options.words:
    print words,
if options.characters:
    print chars,

调用方式:cat /etc/passwd |python wc.py 




示例2
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __author__="huazai"
"""
pycharm 使用指南
Date:2016.08.12
"""



import sys
import os
from optparse import OptionParser

def opt():
    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()
    return options, args

def get_count(data):
    chars = len(data)
    words = len(data.split())
    lines = data.count('\n')
    return lines, words, chars

def print_wc(options, lines, words, chars, fn):
    if options.lines:
        print lines,
    if options.words:
        print words,
    if options.chars:
        print chars,
    print fn

def main():
    options, args = opt()
    if not (options.lines or options.words or options.chars):
        options.lines, options.words, options.chars = True, True, True
    if args:
        total_lines, total_words, total_chars = 0, 0, 0
        for fn in args:
            if os.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 += chars
            elif os.path.isdir(fn):
                print >> sys.stderr, "%s: is a directory" % fn
            else:
                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 :解析后的参数名称
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)
<class 'argparse.Namespace'>
>>> a.x
'1'

 

示例1



import argparse

def _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')
    return parser.parse_args()

def main():
    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 -*-
import sys
import argparse

def cmd():
    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 in d.iteritems():
        print '%s = %s'%(key,value)

if __name__=="__main__":
    cmd()



 

 

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='<the version>')
python bb.py --version
3 f