一、简化除法判断

目标:

编写mydiv.py脚本,主要要求如下:

  • 提示用户输入一个数字作为除数
  • 如果用户按下Ctrl+C或Ctrl+D则退出程序
  • 如果用户输入非数字字符,提示用户应该输入数字
  • 如果用户输入0,提示用户0不能作为除数

方案:

使用if语句判断除数是否合适,需要编写多条语句。有了异常处理,可以本着先做,错了再说的逻辑。直接把除法操作放在try语句中执行,根据产生的异常做相应的处理。

另外,Ctrl+C或Ctrl+D只能通过异常捕获。

异常捕获的语法如下:

try:
        A
    except:
        B
    else:
        C
    finally:
        D

把可能发生异常的语句放在A里面执行,如果出现异常则执行B语句,没有异常则执行C语句。不管是否出现异常都会执行D语句。

捕获异常时,可以使用多个except语句,每个except语句捕获一个异常,每个异常给定不同的处理方法。也可以把多个异常放在同一个except语句后面,但是务必注意,多个异常写在相同的一行,一定要注括号括起来,放在元组中。

步骤:

步骤一:编写脚本

#!/usr/bin/env python
    import  sys
    while True:
        try:
            result = 100 / int(raw_input('enter a number: '))
        except (ValueError, ZeroDivisionError), e:   #将异常原因保存在变量e中
            print "invalid input:", e
            continue
        except  (EOFError, KeyboardInterrupt):
            sys.exit(1)
        break
    print  result

步骤二:测试脚本执行

[root@py01 bin]# ./mydiv.py
    enter a number: 0
    invalid input: integer division or modulo by zero
    enter a number: abc
    invalid input: invalid literal for int() with base 10: 'abc'
    enter a number: 3
    33

二、分析apache访问日志

目标:

编写用于分析apache日志的脚本,主要要求如下:

  • 统计每个客户端访问apache服务器的次数
  • 将统计信息通过字典的方式显示出来
  • 分别统计客户端是Firefox和MSIE的访问次数
  • 分别使用函数式编程和面向对象编程的方式实现

方案:

涉及到文本处理时,正则表达式将是一个非常强大的工具。匹配客户端的IP地址,可以使用正则表达式的元字符,匹配字符串可以直接使用字符的表面含义。

入门级程序员的写法,使用顺序的结构,直接编写。这种方法虽然可以得出结果,但是代码难以重用。参考步骤一。

进阶的写法可以采用函数式编程,方便日后再次使用。参考步骤二。

最后,还可以使用OOP的编程方法,先定义一个统计类,该类将正则表达式作为它的数据属性。再定义一个方法,从指定的文件中搜索正则表达式出现的次数,并将其存入到一个字典中。参考步骤三。

步骤:

步骤一:简单实现

[root@py01 bin]# vim countweb.py
    #!/usr/bin/env python
    import re
    logfile = '/var/log/httpd/access_log'
    cDict = {}
    patt_ip = '^\d+\.\d+\.\d+\.\d+'         #定义匹配IP地址的正则表达式
    with open(logfile) as f:
        for eachLine in f:
            m = re.search(patt_ip, eachLine)
            if m is not None:
                ipaddr = m.group()
                #如果IP地址已在字典中,将其值加1,否则初始值设置为1
                cDict[ipaddr] = cDict.get(ipaddr, 0) + 1
    print cDict

步骤二:使用函数式编程实现

[root@py01 bin]# vim countweb2.py
    !/usr/bin/env python
    import re
    def countPatt(patt, fname):   #定义可以在指定文件中搜索指定字符串的函数
        cDict = {}
        with open(fname) as f:
            for eachLine in f:
                m = re.search(patt, eachLine)
                if m is not None:
                    k = m.group()
                    cDict[k] = cDict.get(k, 0) + 1
        return cDict
    def test():
        logfile = '/var/log/httpd/access_log'
        patt_ip = '^\d+\.\d+\.\d+\.\d+'
        print countPatt(patt_ip, logfile)
        patt_br = 'Firefox|MSIE'
        print countPatt(patt_br, logfile)
    if __name__ == '__main__':
        test()

三、扫描存活主机

目标:

编写扫描存活主机的脚本,主要要求如下:

  • 调用系统的ping命令进行扫描
  • 扫描教室环境下所有存活的主机
  • 采用多线程的方式编写
  • 方案

os模块的system()函数可以调用系统命令,其返回值是系统命令退出码,也就是如果系统命令成功执行,返回0,如果没有成功执行,返回非零值。

本例扫描主机,可以调用系统的ping命令,通过退出码来判断是否ping通了该主机。如果顺序执行,每个ping操作需要消耗数秒 钟,全部的254个地址需要10分钟以上。而采用多线程,可以实现对这254个地址同时执行ping操作,并发的结果就是将执行时间缩短到了10秒钟左 右。

步骤:

步骤一:编写脚本

[root@py01 bin]# vim mtping.py
    #!/usr/bin/env python
    import subprocess
    import threading
    import sys
    def ping(ip):
        result = subprocess.call("ping -c2 %s &> /dev/null" % ip, shell=True)
        if result:
            print "%s:down" % ip
        else:
            print "%s:up" % ip
    if __name__ == '__main__':
        if len(sys.argv) != 2:
            print "Usage: %s subnet" % sys.argv[0]
            sys.exit(1)
        net_list = sys.argv[1].split('.')
        net = '.'.join(net_list[:-1])
        ips = ("%s.%s" % (net, i) for i in range(1, 255))
        for ip in ips:
            t = threading.Thread(target=ping, args=(ip,))
            t.start()

步骤二:测试脚本执行

[root@py01 bin]# python mtping.py 172.40.51.0

脚本接受命令行参数,只要给定网段就可以实现对该网段中所有ip地址的ping操作。

四、利用多线程实现ssh并发访问

目标:

编写ssh客户端脚本,主要要求如下:

  • 在文件中取出所有远程主机IP地址
  • 在shell命令行中接受远程服务器IP地址文件、远程服务器密码以及在远程主机上执行的命令
  • 通过多线程实现在所有的远程服务器上并发执行命令
  • 方案

python的paramiko模块可以实现ssh客户端的功能,使用起来也比较简单。但是当服务器非常多的时候,每台服务器上执行完全相同的简单操作,也会花费大量的时间。

通过ssh加上多线程,可以实现并发访问。为了将程序写的灵活性更强,把要执行的命令以位置参数的方式来提供。

步骤:

步骤一:编写脚本

[root@py01 bin]# vim remote_comm.py
    #!/usr/bin/env python
    import paramiko
    import os
    import sys
    import threading
    def remote_comm(host, password, comm):
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(host, username='root', password=password)
        stdin, stdout, stderr = ssh.exec_command(comm)
        out = stdout.read()
        err = stderr.read()
        if out:
            print "[%s:out]: %s" % (host, out),
        if err:
            print "%s:Error: %s", (host, err),
        ssh.close()
    if __name__ == '__main__':
        if len(sys.argv) != 4:
            print "Usage: %s ipfile password 'comm'" % sys.argv[0]
            sys.exit(1)
        ipfile = sys.argv[1]
        if not os.path.isfile(ipfile):
            print "No such file: %s" % ipfile
            sys.exit(2)
        password = sys.argv[2]
        comm = sys.argv[3]
        with open(ipfile) as fobj:
            for line in fobj:
                ip = line.strip()
                t = threading.Thread(target=remote_comm, args=(ip, password, comm))
                t.start()

步骤二:测试脚本执行

[root@py01 bin]# python remote_comm.py ipaddr.txt tedu.cn 'useradd bob'

脚本接受命令行参数,其中ipaddr.txt是存放所有远程主机ip地址的文件,文件中每个ip地址占一行。tedu.cn是远程主机的密码(所有远程主机密码需要是一致的)。最后的命令需要写在引号中。

该示例执行成功后,会在所有远程主机上创建一个名为bob的用户。

补充:

常见的报错信息:
NameError:名字出错
IndexError:索引出错
SyntaxError:语法出错
KeyboardInterrupt:键盘输入了中断,用户中断操作
EOFError:中断,没有内部输入
IOError:输入/输出操作失败

[root@room8pc205 1710]# ./free.py
请输入用户名:Traceback (most recent call last):
  File "./free.py", line 6, in <module>
    x=raw_input("请输入用户名:")
EOFError    //ctrl + D

[root@room8pc205 1710]# ./free.py
请输入用户名:^CTraceback (most recent call last):
  File "./free.py", line 6, in <module>
    x=raw_input("请输入用户名:")
KeyboardInterrupt   //ctrl + C

自定义报错解释:try-except格式解释
#!/usr/bin/env python
#coding:utf-8
try:
    x=raw_input("请输入用户名:")
    print x
except EOFError:
    print "你输入了ctrl+d,错误输入"    //EOFError报错提示这条信息
except KeyboardInterrupt:
    print "你输入了ctrl+c,错误输入"   //KeyboardInterrupt报错提示这条信息
或者:
try:
    x=raw_input("请输入用户名:")
    print x
except
    print “你出错了”    //报错信息全都归结一类

try支持这些格式:(不用全都用上,可以选择)

#!/usr/bin/env python
#coding:utf-8

try:
   x=int(raw_input("请输入一个数字:"))
   print 10/x
except ZeroDivisionError:    //如果出现0报错,输出下面信息
   print "出错了"
else:        //如果正常,输出下面信息
   print "OK"
finally:     //最终不管对错都输出下面信息
   print "GameOver"

自定义一个报错:
#!/usr/bin/env python
#coding:utf-8
try:
    x=int(raw_input('请输入1-100:'))
    if x>100:
        raise ValueError,"你的值超出了范围"     //定义报错输出信息
except ValueError,e:      //将定义的报错信息放入变量e中
    print "Error:",e

类似的还有assert(和raise判断是相反的)
#!/usr/bin/env python
#coding:utf-8
try:
    x=int(raw_input('请输入1-100:'))
    assert x<100,"你输入的数字太大了"    //断定你输入的数值小于100,否则报错“你输入的数字太大了”
except ValueError,e:      //将定义的报错信息放入变量e中
    print "Error:",e

Python基础(三):简化除法判断、分析apache访问日志、扫描存活主机、利用多线程实现ssh并发访问的更多相关文章

  1. Python 基础 三 反射

    Python 基础 三 反射 今天我们先介绍一下反射这个概念,啥是反射?反射就是自己检测自己.在我们Python的面向对象中的反射是啥意思呢?就是通过字符串的形式操作对象相关的属性.python中的一 ...

  2. 进击的Python【第三章】:Python基础(三)

    Python基础(三) 本章内容 集合的概念与操作 文件的操作 函数的特点与用法 参数与局部变量 return返回值的概念 递归的基本含义 函数式编程介绍 高阶函数的概念 一.集合的概念与操作 集合( ...

  3. Python 基础三 文件 函数

    今天回顾一下之前学的文件操作相关知识点,对于文件的操作,主要有一下几部分构成: 一.文件的基础知识 1.文件操作的基本流程 文件操作其实可以分成三大部分: 1.打开文件,获取文件句柄并赋予一个变量 2 ...

  4. python基础-编码_if条件判断

    一.第一句Python代码 在 /home/dev/ 目录下创建 hello.py 文件,内容如下: [root@python-3 scripts]# cat hello.py #!/usr/bin/ ...

  5. Python基础(三)——集合、有序 无序列表、函数、文件操作

    1.Set集合 class set(object): """ set() -> new empty set object set(iterable) -> n ...

  6. Python基础三(选择,循环)

    序 首先我们知道程序的执行有三种结构:顺序.选择.循环三种结构,而为了方便我们书写和多次利用我们就需要把一段代码封装器来,这就是方法.今天我就说的是程序的基本结构的格式和方法. 注:所有的程序都可以通 ...

  7. Python基础(三) 数据类型

    我们首先要看的是几乎任何语言都具有的数据类型,包括字符串.整型.浮点型以及布尔类型.这些基本数据类型组成了基本控制块,从而创建的Python应用程序. 一.基本结构 1.数值: Python支持不同的 ...

  8. python基础三

    多级菜单 多级菜单 可依次选择进入各子菜单 所需新知识点:列表.字典 #!/usr/bin/env python # -*- coding: utf-8 -*- menu = { '北京':{ '海淀 ...

  9. Python基础三. 函数、lambda、filter、map、reduce

    一.概述 函数, 就是用一些语句组织起来实现一组特定的功能, 用来重复调用. 函数的作用及意义:最大化的重用代码和最小化的代码冗余以及对流程的分解. Python中有哪些函数: 内建的函数 第三方模块 ...

随机推荐

  1. mybatis 动态Sql的模糊查询

    where teacher.tname like concat(concat(#{tName}),'%') 2:distinct的使用 下面先来看看例子: table    id name    1 ...

  2. spring-boot的helloWorld详解

    1.运行环境 开发工具:intellij idea JDK版本:1.8 项目管理工具:Maven 3.2.5 2.Maven Plugin管理 pom.xml配置代码: <project xml ...

  3. StatefulWidget 有状态组件

    在 Flutter 中自定义组件其实就是一个类,这个类需要继承 StatelessWidget/StatefulWidget: StatelessWidget 是无状态组件,状态不可变的 widget ...

  4. XenServer(服务器虚拟化平台)

    Citrix Xenserver,思杰基于Xen的虚拟化服务器.Citrix XenServer是一种全面而易于管理的服务器虚拟化平台,基于强大的 Xen Hypervisor 程序之上.Xen技术被 ...

  5. c++primer,自定义一个复数类

    #include<iostream> #include<string> #include<vector> #include<algorithm> #in ...

  6. appium常见问题02_android内嵌H5页(webview)如何定位

    现在大多数app都是由原生页面和内嵌H5(即webview)组成,app原生页面直接定位即可,那内嵌H5页面要如何定位呢. 相信大多数人用appium做自动化时都有遇到这个问题,小编总结了下工作中该问 ...

  7. 嵌入式C语言3.5 关键字---运算符

    1. 算数运算符 + -                    A +/- B 要求A,B数据类型一致 * 乘法   / 除法    %取模 乘法CPU可能需要多个周期,甚至需要利用软件的模拟方法来实 ...

  8. anaconda 安装2个python环境 亲测

    本机环境: anaconda3,pyhon3.7.4 配置第2个python环境,安装python3.6 > conda create --name tensorflow python=3.6 ...

  9. Vue2.0---vuex初理解

    先来一张vuex的帅照 第一眼看到这张图片我内心是万匹草泥马飞过. 简单理解:  vuex:一个可以全局被使用的状态管理的“仓库”:state.js中定义初始状态,通过action去触发mutatio ...

  10. 利用单臂路由实现VLAN间路由(有1个疑问)

    配置PC机: PC1:IP 192.168.1.1 :掩码:255.255.255.0:网关:192.168.1.254  VLAN 10 PC2:IP 192.168.2.1 :掩码:255.255 ...