博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
OOP基础 OOP进阶
阅读量:3943 次
发布时间:2019-05-24

本文共 11055 字,大约阅读时间需要 36 分钟。

OOP基础

OOP简介

基本概念

• 类(Class):用来描述具有相同的属性和方法的对象的 集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。 • 实例化:创建一个类的实例,类的具体对象。 • 方法:类中定义的函数。 • 对象:通过类定义的数据结构实例。对象包括两个数 据成员(类变量和实例变量)和方法。

创建类

• 使用 class 语句来创建一个新类,class 之后为类的名称并以冒号结尾 • 类名建议使用驼峰形式class BearToy:	pass# 练习lvbu = {
'name': '吕布', 'weapon': '方天画戟', 'sex': '男'}def walk(): passdef attack(): pass

创建实例

• 类是蓝图,实例是根据蓝图创建出来的具体对象tidy = BearToy()

绑定方法

构造器方法

• 当实例化类的对象是,构造器方法默认自动调用 • 实例本身作为第一个参数,传递给selfclass BearToy:	def __init__(self, size, color):		self.size =	size		slef.color = color        if __name__=='__main__':    tidy = BearToy('small', 'orange')

其他绑定方法

• 类中定义的方法需要绑定在具体的实例,由实例调用 • 实例方法需要明确调用class BearToy:	def __init__(self, size, color):		self.size =	size		self.color = color            def speak(self):    	print('hahaha')        if __name__ ==	'__main__':    tidy = BearToy('small',	'orange')    tidy.speak()# 练习• OOP的思想,是将现实世界的物体抽象成一个类class,这个类中有属性和行为,将数据和行为融合到一起。相当于创建了一个蓝图,然后再根据蓝图创建出具体的实例。class GameCharacter:    def __init__(self, name, weapon):        self.name = name        self.weapon = weapon    def speak(self, word):        print('我是%s, %s' % (self.name, word))>>> lvbu = GameCharacter('吕布', '方天画戟')>>> lvbu.name'吕布'>>> lvbu.weapon'方天画戟'>>> lvbu.speak('人在塔在')我是吕布, 人在塔在>>> guanyu = GameCharacter('关羽', '青龙偃月刀')>>> guanyu.name'关羽'>>> guanyu.weapon'青龙偃月刀'>>> guanyu.speak('呵呵')我是关羽, 呵呵# 练习class GameCharacter:    def __init__(self, name, weapon):        self.name = name        self.weapon = weapon    def speak(self, word):        print('我是%s, %s' % (self.name, word))    def walk(self):        print('我有%s,我能走' % self.weapon)if __name__ == '__main__':    lvbu = GameCharacter('吕布', '方天画戟')    print(lvbu.name)    print(lvbu.weapon)    lvbu.speak('人在塔在')    lvbu.walk()    guanyu = GameCharacter('关羽', '青龙偃月刀')    print(guanyu.name)    print(guanyu.weapon)    guanyu.speak('呵呵')# 练习class Weapon:    def __init__(self, wname, strength, type):        self.name = wname        self.strength = strength        self.type = typeclass GameCharacter:    def __init__(self, name, weapon):        self.name = name        self.weapon = weapon    def speak(self, word):        print('我是%s, %s' % (self.name, word))if __name__ == '__main__':    ji = Weapon('方天画戟', 100, '物理攻击')    lvbu = GameCharacter('吕布', ji)    print(lvbu.weapon.name)    print(lvbu.weapon.type)# 练习class GameCharacter:    def __init__(self, name, weapon):        self.name = name        self.weapon = weapon    def speak(self, word):        print('我是%s, %s' % (self.name, word))class Warrior(GameCharacter):  # 括号中指定父类(基类)    def attack(self):        print('近身肉搏')class Mage(GameCharacter):    def attack(self):        print('远程攻击')if __name__ == '__main__':    gl = Warrior('盖伦', '大刀')    tm = Mage('提莫', '蘑菇')    gl.speak('人在塔在')    gl.attack()    tm.speak('我去前面用脸探探路')    tm.attack()

__init__方法一般用于为实例对象绑定属性。当创建实例的时候,__init__方法自动调用,实例(lvbu)会作为第一个参数传递。self不是关键字,java用this,但是都不是必须的名字,可以随意更换。一旦创建了实例,实例就会自动拥有类中定义的属性和方法(函数)。

self.属性 是绑定到某个实例上的属性,该属性在所有方法中均可见可用。没有绑定到对象上的,只是局部变量。

编写游戏人物

1. 创建游戏角色类2. 游戏人物角色拥有名字、武器等属性3. 游戏人物具有攻击和行走的方法4. 武器通过武器类实现

OOP进阶

组合和派生

什么是组合

• 类被定义后,目标就是要把它当成一个模块来使用,并把这些对象嵌入到你的代码中去 • 组合就是让不同的类混合并加入到其它类中来增加功能和代码重用性 • 可以在一个大点的类中创建其它类的实例,实现一些其它属性和方法来增强对原来的类对象• 当两个类完全不同,其中一个类是另一个类的组件时,使用组合

组合应用

• 两个类明显不同 • 一个类是另一个类的组件class Manufacture:	def __init__ (self, phone, email):        self.phone = phone        self.email = email

创建子类

• 当类之间有显著的不同,并且较小的类是较大的类所 需要的组件时组合表现得很好;但当设计“相同的类但有一些不同的功能”时,派生就是一个更加合理的选择了 • OOP 的更强大方面之一是能够使用一个已经定义好的类,扩展它或者对其进行修改,而不会影响系统中使用现存类的其它代码片段 • OOD(面向对象设计)允许类特征在子孙类或子类中进行继承

创建子类(续1)

• 创建子类只需要在圆括号中写明从哪个父类继承即可class BearToy:def __init__ (self, size, color):    self.size =	size    self.color = color

继承

• 继承描述了基类的属性如何“遗传”给派生类 • 子类可以继承它的基类的任何属性,不管是数据属性还是方法class BearToy:def __init__ (self, size, color):    self.size =	size    self.color = color    class NewBearToy(BearToy):	passif __name__	== '__main__':    tidy = NewBearToy('small', 'orange')    tidy.speak()• 当两个类有很多相似之处,只有一部分不同,使用继承。• 子类可以有多个父类。当多个类有同名方法的时候,查找的顺序是自下向上,自左向右。

通过继承覆盖方法

• 如果子类中有和父类同名的方法,父类方法将被覆盖 • 如果需要访问父类的方法,则要调用一个未绑定的父类方法,明确给出子类的实例class BearToy:    def __init__ (self, size, color, phone,	email):        self.size =	size        self.color = color        self.vendor = Manufacture(phone, email)        class NewBearToy(BearToy):def __init__ (self,	size, color, phone,	email, date):    super(NewBearToy, self).__init__(size, color,phone, email)    self.date =	date

多重继承

• python允许多重继承,即一个类可以是多个父类的 子类,子类可以拥有所有父类的属性>>>	class A:    def foo(self):    	print('foo	method’)>>>	class B:    def bar(self):    	print('bar method’)>>>	class C(A, B):	pass>>>	c =	C()>>>	c.foo()foo	method>>>	c.bar()bar	method

特殊方法

__ init __方法

• 实例化类实例时默认会调用的方法class BearToy:    __init__(self, size, color):        self.size =	size        slef.color = color        if __name__	== '__main__':	tidy = BearToy('small', 'orange')

__ str __方法

• 打印/显示实例时调用方法 • 返回字符串class BearToy:    def	__init__(self, size, color):        self.size =	size        slef.color = color            def __str__(self):    	return '
' % (self.size, self.color) if __name__ == '__main__': tidy = BearToy('small', 'orange') print(tidy)

__ call __方法

• 用于创建可调用的实例class BearToy:    def __init__(self, size, color):        self.size =	size        slef.color = color    def __call__(self):        print('I am a %s bear' % self.size)    if __name__ == '__main__':    tidy = BearToy('small',	'orange')    print(tidy)

出版商程序

1. 为出版商编写一个Book类2. Book类有书名、作者、页数等属性3. 打印实例时,输出书名4. 调用实例时,显示该书由哪个作者编写

re模块

正则表达式

例:为mac地址加冒号

​ 1.定位到mac地址

​ 2.每2个mac地址分一组

​ 3.在组之间加冒号

192.168.1.1     00525412A3B4192.168.1.2     000C29123456:%s/\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)$/\1:\2:\3:\4:\5:\6/

匹配单个字符

记号 说 明
. 匹配任意字符(换行符除外)
[…x-y…] 匹配字符组里的任意字符
[^…x-y…] 匹配不在字符组里的任意字符
\d 匹配任意数字,与[0-9]同义
\w 匹配任意数字字母字符,与[0-9a-zA-Z_]同义
\s 匹配空白字符,与[ \r\v\f\t\n]同义

匹配一组字符

记号 说 明
literal 匹配字符串的值
re1|re2 匹配正则表达式re1或re2
* 匹配前面出现的正则表达式零次或多次
+ 匹配前面出现的正则表达式一次或多次
? 匹配前面出现的正则表达式零次或一次
{M, N} 匹配前面出现的正则表达式至少M次最多N次

其他元字符

记号 说 明
^ 匹配字符串的开始
$ 匹配字符串的结尾
\b 匹配单词的边界
() 对正则表达式分组
\nn 匹配已保存的子组

核心函数和方法

match函数

• 尝试用正则表达式模式从字符串的开头匹配,如果匹配成功,则返回一个匹配对象;否则返回None>>>	import re>>>	m = re.match('foo', 'food')	 #成功匹配>>>	print(m)<_sre.SRE_Match object;	span=(0, 3), match='foo'>>>>	>>>	m =	re.match(‘foo’,	‘seafood’) #未能匹配>>>	print(m)None# 练习>>> import re# 在进行匹配的时候,如果匹配到了,返回匹配对象,否则返回None>>> re.match('f..', 'food')<_sre.SRE_Match object; span=(0, 3), match='foo'>>>> re.match('f..', 'seafood')>>> print(re.match('f..', 'seafood'))None

search函数

• 在字符串中查找正则表达式模式的第一次出现,如果匹配成功,则返回一个匹配对象;否则返回None>>>	import re>>>	m =	re.search('foo', 'food')>>>	print(m)<_sre.SRE_Match object;	span=(0, 3), match='foo'> >>>	>>>	m =	re.search(‘foo’, ‘seafood’) #可以匹配在字符中间的模式>>>	print(m)<_sre.SRE_Match object;	span=(3, 6), match='foo'># 练习>>> re.search('f..', 'food')<_sre.SRE_Match object; span=(0, 3), match='foo'>>>> re.search('f..', 'seafood')<_sre.SRE_Match object; span=(3, 6), match='foo'>>>> m = re.search('f..', 'seafood')>>> m.group()   # 返回匹配到的内容'foo'>>> re.search('f..', 'food')<_sre.SRE_Match object; span=(0, 3), match='foo'>>>> re.search('f..', 'seafood')<_sre.SRE_Match object; span=(3, 6), match='foo'>>>> m = re.search('f..', 'seafood')>>> m.group()   # 返回匹配到的内容'foo'

group方法

>>>	import re>>>	m =	re.match('foo',	'food')>>>	print(m.group())foo>>>	m =	re.search('foo', 'seafood')>>>	m.group()'foo'

findall函数

• 在字符串中查找正则表达式模式的所有(非重复)出现;返回一个匹配对象的列表>>>	import re>>>	m =	re.search('foo', 'seafood is food')>>>	print(m.group()) #search只匹配模式的第一次出现foo>>>	>>>	m =	re.findall(‘foo’, ‘seafood is food’) #获得全部的匹配项>>>	print(m)['foo',	'foo']

finditer函数

• 和findall()函数有相同的功能,但返回的不是列表而是迭代器;对于每个匹配,该迭代器返回一个匹配对象>>>	import re>>>	m =	re.finditer('foo', 'seafood	is food')>>>	for	item in m:...	print(item.group())...	foofoo# 练习>>> 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'):...     print(m.group())... foofoo

split方法

• 根据正则表达式中的分隔符把字符分割为一个列表,并返回成功匹配的列表 • 字符串也有类似的方法,但是正则表达式更加灵活>>>	import re #使用 . 和 - 作为字符串的分隔符>>>	mylist = re.split('\.|-', 'hello-world.data')>>>	print(mylist)['hello', 'world', 'data']# 练习>>> re.split('-|\.', 'hello-world.tar.gz')['hello', 'world', 'tar', 'gz']

sub方法

• 把字符串中所有匹配正则表达式的地方替换成新的字符串>>>	import re>>>	m =	re.sub('X',	'Mr. Smith', 'attn:	X\nDear X')>>>	print(m)attn: Mr. SmithDear Mr. Smith# 练习>>> re.sub('X', 'tom', 'Hi X. Nice to meet you X.')'Hi tom. Nice to meet you tom.'

compile函数

• 对正则表达式模式进行编译,返回一个正则表达式对象• 不是必须要用这种方式,但是在大量匹配的情况下,可以提升效率>>>	import re>>>	patt = re.compile('foo')>>>	m = patt.match('food')>>>	print(m.group())foo# 练习# 当有大量内容需要匹配的时候,先把正则表达式的模式编译一下,将会有更好的执行效率>>> patt = re.compile('f..')>>> patt.search('seafood')<_sre.SRE_Match object; span=(3, 6), match='foo'>>>> patt.findall('seafood is food')['foo', 'foo']

分析apache访问日志

• 编写一个apche日志分析脚本    1. 统计每个客户端访问apache服务器的次数    2. 将统计信息通过字典的方式显示出来    3. 分别统计客户端是Firefox和MSIE的访问次数    4. 分别使用函数式编程和面向对象编程的方式实现
def coun_patt(fname, patt):if __name__ == '__main__':    fname = 'access_log'    ip = '^(\d+\.){3}\d+'  # 192.168.199.23, 12345.67890.1.132234354    br = 'Firefox|MSIE|Chrome'    print(coun_patt(fname, ip))    print(coun_patt(fname, br))

Counter对象

>>> from collections import Counter>>> c = Counter()>>> c.update('1.1.1.1')>>> cCounter({
'1': 4, '.': 3})>>> c1 = Counter()>>> c1.update(['1.1.1.1'])>>> c1Counter({
'1.1.1.1': 1})>>> c1.update(['1.1.1.1'])>>> c1.update(['1.1.1.1'])>>> c1.update(['1.1.1.1'])>>> c1.update(['1.1.1.2'])>>> c1.update(['1.1.1.2'])>>> c1.update(['1.1.1.2'])>>> c1.update(['1.1.1.3'])>>> c1.update(['1.1.1.3'])>>> c1Counter({
'1.1.1.1': 4, '1.1.1.2': 3, '1.1.1.3': 2})>>> c1.most_common(2)[('1.1.1.1', 4), ('1.1.1.2', 3)]
import refrom collections import Counterdef count_patt(fname, patt):    cpatt = re.compile(patt)  # 先编译模式    c = Counter()  # 用于保存结果    # 打开文件,从每一行中匹配,将匹配结果更新到c中    with open(fname) as fobj:        for line in fobj:            m = cpatt.search(line)            if m:  # 如果匹配到内容,才是真;None是False                c.update([m.group()])    return cif __name__ == '__main__':    fname = 'access_log'    ip = '^(\d+\.){3}\d+'  # 192.168.199.23, 12345.67890.1.132234354    br = 'Firefox|MSIE|Chrome'    ips = count_patt(fname, ip)    print(ips)    print(ips.most_common(5))    print(count_patt(fname, br))

2

import refrom collections import Counterclass CountPatt:    def __init__(self, fname):        self.fname = fname    def count_patt(self, patt):        cpatt = re.compile(patt)  # 先编译模式        c = Counter()  # 用于保存结果        # 打开文件,从每一行中匹配,将匹配结果更新到c中        with open(self.fname) as fobj:            for line in fobj:                m = cpatt.search(line)                if m:  # 如果匹配到内容,才是真;None是False                    c.update([m.group()])        return cif __name__ == '__main__':    ip = '^(\d+\.){3}\d+'  # 192.168.199.123, 12345.67890.1.132234354    cp = CountPatt('access_log')    result = cp.count_patt(ip)    print(result)    print(result.most_common(5))    cp2 = CountPatt('/etc/passwd')    shell = 'bash$|nologin$'    print(cp2.count_patt(shell))

转载地址:http://xhnwi.baihongyu.com/

你可能感兴趣的文章
postgres多边形存储--解决 Points of LinearRing do not form a closed linestring
查看>>
postgresql+postgis空间数据库总结
查看>>
spring 之 Http Cache 和 Etag(转)
查看>>
基于Lucene查询原理分析Elasticsearch的性能(转)
查看>>
HttpClient请求外部服务器NoHttpResponseException
查看>>
springCloud升级到Finchley.RELEASE,SpringBoot升级到2.0.4
查看>>
Spring boot + Arthas
查看>>
omitted for duplicate jar包冲突排查
查看>>
如何保证缓存与数据库的双写一致性?
查看>>
java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy排查
查看>>
深浅拷贝,深浅克隆clone
查看>>
Java基础零散技术(笔记)
查看>>
Mysql优化sql排查EXPLAIN EXTENDED
查看>>
线程之间数据传递ThreadLocal,InheritableThreadLocal,TransmittableThreadLocal
查看>>
spring循环依赖,解决beans in the application context form a cycle
查看>>
分布式锁的实现
查看>>
解决POJO的属性首字母为大写,但是赋值不了的问题
查看>>
服务器运维整理(笔记)
查看>>
redis分布式锁在MySQL事务代码中使用,没控制好并发原因
查看>>
centos7中的网卡一致性命名规则、网卡重命名方法
查看>>