python3:oop、re模块

oop简介

  • OOP:面向对象的编程
    在这里插入图片描述
>>> class Bear:     # 定义类,class是关键字
...   pass
...
>>> b1 = Bear()     # 创建实例
>>> b1.name = '熊大'
>>> b1.size = 'L'
>>> b1.name
'熊大'
>>>> b1.size

绑定示例

在这里插入图片描述
在这里插入图片描述

class Role:
    def __init__(self, name, wuqi):
        '称作构造器方法,创建实例时,自动调用。通常用于将属性绑定到实例。'
        self.name = name
        self.wuqi = wuqi

    def show_me(self):
        # 绑定在实例身上的属性,可以在类中的任意位置使用
        print('我是%s,擅长使用%s' % (self.name, self.wuqi))

    def speak(self, words):
        # 没有绑定到实例的属性,就是函数的局部变量,只能在函数内使用
        print(words)

if __name__ == '__main__':
    lb = Role('吕布', '方天画戟')  # 自动调用__init__方法
    lb.show_me()  # 实例lb自动作为第一个参数传给方法
    lb.speak('马中赤兔,人中吕布')
    zf = Role('张飞', '丈八蛇矛')
    zf.show_me()
    zf.speak('我乃燕人张飞张冀德')

组合与派生

什么是组合

在这里插入图片描述
在这里插入图片描述

class WuQi:
    def __init__(self, wname, wtype, liliang):
        self.wname = wname
        self.wtype = wtype
        self.liliang = liliang

class Role:
    def __init__(self, name, wuqi):
        '称作构造器方法,创建实例时,自动调用。通常用于将属性绑定到实例。'
        self.name = name
        self.wuqi = wuqi

    def show_me(self):
        # 绑定在实例身上的属性,可以在类中的任意位置使用
        print('我是%s,擅长使用%s' % (self.name, self.wuqi))


if __name__ == '__main__':
    ji = WuQi('方天画戟', wtype='物理伤害', liliang=100)
    print(ji.wname, ji.wtype, ji.liliang)
    lb = Role('吕布', ji)  # 自动调用__init__方法
    print(lb.wuqi.wname, lb.wuqi.wtype, lb.wuqi.liliang)

创建子类

在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

class Role:
    def __init__(self, name, wuqi, guojia):
        '称作构造器方法,创建实例时,自动调用。通常用于将属性绑定到实例。'
        self.name = name
        self.wuqi = wuqi
        self.guojia = guojia

    def show_me(self):
        # 绑定在实例身上的属性,可以在类中的任意位置使用
        print('我是%s,擅长使用%s' % (self.name, self.wuqi))

    def speak(self, words):
        # 没有绑定到实例的属性,就是函数的局部变量,只能在函数内使用
        print(words)

class ZhanShi(Role):  # 括号中是父类,也叫基类
    # 子类将会继承父类的所有方法
    def __init__(self, name, wuqi, guojia, zuoji):
        # Role.__init__(self, name, wuqi, guojia)  # 调用父类方法
        super(ZhanShi, self).__init__(name, wuqi, guojia)  # 调用父类方法,与上>一行一样
        self.zuoji = zuoji
    def attack(self, target):
        print('正在近身与%s肉搏' % target)

class FaShi(Role):
    def attack(self, target):
        print('远程打击%s' % target)

if __name__ == '__main__':
    lb = ZhanShi('吕布', '方天画戟', '群雄', '赤兔马')
    lb.show_me()
    lb.speak('马中赤兔,人中吕布')
    lb.attack('张飞')

特殊方法

  • 在class中,为了实现其内部功能,它们拥有很多以双下划线开头和结尾的特殊方法
# dir可以查看对象属性
>>> type(10)   # 10是int的实例
<class 'int'>
>>> dir(10)    # 查看10的属性
>>> dir([])    # 查看列表实例的属性

__init__ 方法

在这里插入图片描述

__str方法

在这里插入图片描述
在这里插入图片描述

  • 实现book出版商脚本
class Book:
    def __init__(self, title, author):
        '创建实例时,自动调用的方法'
        self.title = title
        self.author = author

    def __str__(self):
        '在打印、显示实例时,自动调用'
        return '《%s》' % self.title

    def __call__(self):
        '使实例可以像函数一样调用'
        print('《%s》是%s编写的' % (self.title, self.author))

if __name__ == '__main__':
    py_book = Book('Python基础教程(第3版)', 'Magnus Lie Hetland')  # 调用__init__
    print(py_book)  # 调用__str__方法
    py_book()       # 调用__call__方法

re模块

正则表达式

  • 匹配单个字符
    在这里插入图片描述
  • 匹配一组字符
    在这里插入图片描述
  • 其他元字符
    在这里插入图片描述

给mac码加冒号

192.168.1.1     000C29123456
192.168.1.2     525400A3B8C1

:%s/\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)$/\1:\2:\3:\4:\5:\6/

re核心函数及方法

match函数

在这里插入图片描述

search函数

在这里插入图片描述

group方法

在这里插入图片描述

findall函数

在这里插入图片描述

finditer函数

在这里插入图片描述

compile函数

在这里插入图片描述

split方法

在这里插入图片描述

sub方法

在这里插入图片描述

>>> import re
# match只能从字符串开头匹配
>>> re.match('f..', 'food')  # 在food中匹配f..,匹配到返回匹配对象
<_sre.SRE_Match object; span=(0, 3), match='foo'>
>>> re.match('f..', 'seafood')     # 匹配不到,返回None
>>> print(re.match('f..', 'seafood'))
None
# search应用更多,可以在字符串任意位置匹配
>>> m = re.search('f..', 'seafood')
>>> m.group()   # 通过group方法取出匹配内容
'foo'

# search只匹配到第一个满足条件的字符串,findall匹配到全部,返回列表
>>> re.findall('f..', 'seafood is food')
['foo', 'foo']
# finditer返回所有匹配对象的生成器
>>> re.finditer('f..', 'seafood is food')
<callable_iterator object at 0x7f5764824828>
>>> list(re.finditer('f..', 'seafood is food'))
[<_sre.SRE_Match object; span=(3, 6), match='foo'>, <_sre.SRE_Match object; span=(11, 14), match='foo'>]
>>> for m in re.finditer('f..', 'seafood is food'):
...   m.group()
...
'foo'
'foo'

# 字符串的切割方法,只能指定一个分隔符
>>> s = 'hello-world-ni-hao.tar.gz'
>>> s.split('-')
['hello', 'world', 'ni', 'hao.tar.gz']
>>> s.split('.')
['hello-world-ni-hao', 'tar', 'gz']
# 正则的切割符,可以指定多个
>>> re.split('-|\.', s)
['hello', 'world', 'ni', 'hao', 'tar', 'gz']

# 字符串的替换方法
>>> s.replace('-', '/')
'hello/world/ni/hao.tar.gz'

# 正则表达式的替换
>>> re.sub('-|\.', '/', s)
'hello/world/ni/hao/tar/gz'

# 当有大量匹配时,为了有更好的效率,可以将正则的模式先进行编译
>>> patt = re.compile('f..')
>>> m = patt.search('seafood')
>>> m.group()
'foo'
>>> patt.findall('seafood is food')
['foo', 'foo']

编写apach.py脚本,实现日志分析:

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

  • 脚本实现生ip访问降序排列
    – 列表的sort方法,接受一个名为key的参数
    – key需要是一个函数
    – key函数处理列表的每一项,将处理结果作为排序依据。
    – key函数不改变列表
>>> result = {'172.40.58.150': 10, '172.40.58.124': 6, '172.40.58.101': 10, '127.0.0.1': 121, '192.168.4.254': 103, '192.168.2.254': 110, '201.1.1.254': 173, '201.1.2.254': 119, '172.40.0.54': 391, '172.40.50.116': 244}
>>> list(result.items())
[('172.40.58.150', 10), ('172.40.58.124', 6), ('172.40.58.101', 10), ('127.0.0.1', 121), ('192.168.4.254', 103), ('192.168.2.254', 110), ('201.1.1.254', 173), ('201.1.2.254', 119), ('172.40.0.54', 391), ('172.40.50.116', 244)]
>>> l = list(result.items())
>>> def get_last(seq):   # 接受一个序列对象
...   return seq[-1]     # 返回序列中的最后一项
...
>>> l.sort(key=get_last)
>>> l
[('172.40.58.124', 6), ('172.40.58.150', 10), ('172.40.58.101', 10), ('192.168.4.254', 103), ('192.168.2.254', 110), ('201.1.2.254', 119), ('127.0.0.1', 121), ('201.1.1.254', 173), ('172.40.50.116', 244), ('172.40.0.54', 391)]

# 因为get_last函数非常简单,所以可以不定义它,直接使用匿名函数
>>> l.sort(key=lambda seq: seq[-1], reverse=True)  # 使作匿名函数,并降序排列
import re

def count_patt(fname, patt):
    '用于在文件中统计每个模式字符串出现的次数'
    result = {}  # 定义用于保存结果的变量
    cpatt = re.compile(patt)  # 为了有更高的匹配效率,编译模式

    # 遍历文件,在每一行中匹配模式,匹配到了就更新到字典中
    with open(fname) as fobj:
        for line in fobj:
            m = cpatt.search(line)
            if m:  # 如果匹配到了内容
                k = m.group()
                result[k] = result.get(k, 0) + 1
                # if k not in result:
                #     result[k] = 1
                # else:
                #     result[k] += 1

    return result
if __name__ == '__main__':
    fname = 'access_log'
    ip = '^(\d+\.){3}\d+'  # 1234.56789.10.2  192.168.10.5
    br = 'Firefox|MSIE'
    result1 = count_patt(fname, ip)
    result2 = count_patt(fname, br)
    # print(result1)
    l = list(result1.items())
    l.sort(key=lambda seq: seq[-1], reverse=True)
    print(l)
    print(result2)
  • 使用oop
import re

class CountPatt:
    def count_patt(self, fname, patt):
        '用于在文件中统计每个模式字符串出现的次数'
        result = {}  # 定义用于保存结果的变量
        cpatt = re.compile(patt)  # 为了有更高的匹配效率,编译模式

        # 遍历文件,在每一行中匹配模式,匹配到了就更新到字典中
        with open(fname) as fobj:
            for line in fobj:
                m = cpatt.search(line)
                if m:  # 如果匹配到了内容
                    k = m.group()
                    result[k] = result.get(k, 0) + 1

        return result
if __name__ == '__main__':
    fname = 'access_log'
    ip = '^(\d+\.){3}\d+'  # 1234.56789.10.2  192.168.10.5
    cp1 = CountPatt()  # 创建实例
    result1 = cp1.count_patt(fname, ip)
    print(result1)
  • 使用__init__
import re

class CountPatt:
    def __init__(self, fname):
        self.fname = fname

    def count_patt(self, patt):
        '用于在文件中统计每个模式字符串出现的次数'
        result = {}  # 定义用于保存结果的变量
        cpatt = re.compile(patt)  # 为了有更高的匹配效率,编译模式

        # 遍历文件,在每一行中匹配模式,匹配到了就更新到字典中
        with open(self.fname) as fobj:
            for line in fobj:
                m = cpatt.search(line)
                if m:  # 如果匹配到了内容
                    k = m.group()
                    result[k] = result.get(k, 0) + 1

        return result
        
if __name__ == '__main__':
    fname = 'access_log'
    ip = '^(\d+\.){3}\d+'  # 1234.56789.10.2  192.168.10.5
    br = 'Firefox|MSIE|Chrome'
    cp1 = CountPatt(fname)  # 创建实例
    result1 = cp1.count_patt(ip)
    print(result1)
    result2 = cp1.count_patt(br)
    print(result2)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值