OOP
- 面向对象编程
- 函数式编程,数据和行为是分开的。
- OOP可以将数据和行为融合,成为一个整体。
- 将编程对象抽象成一个类
- 类(Class):用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
- 实例化:创建一个类的实例,类的具体对象。
- 方法:类中定义的函数。
- 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
class Role:
def __init__(self, name, weapon):
# 构造器方法,实例化时自动调用,注意,self不是关键字,可以是任何自定义的变量
# 绑定在实例身上的属性,在类中任意位置可见可用
self.name = name
self.weapon = weapon
def show_me(self):
# 绑定在实例身上的属性,在类中任意位置可见可用
print('我是%s,我擅用%s' % (self.name, self.weapon))
def speak(self, words):
# 没有绑定在实例身上的变量,只是局部变量,只能用在函数中
hh = 'Hahaha'
print(hh)
print(words)
if __name__ == '__main__':
# 实例本身将会自动作为第一个参数传递,本例中是lb
lb = Role('吕布', '方天画戟') # 实例化,创建具体的对象
print(lb.name, lb.weapon)
lb.show_me()
lb.speak('马中赤兔,人中吕布')
组合
- 两个类明显不同,其中一个类是另一个类的组件
class Role:
def __init__(self, name, weapon):
self.name = name
self.weapon = weapon
class Weapon:
def __init__(self, wname, strength):
self.wname = wname
self.strength = strength
if __name__ == '__main__':
ji = Weapon('方天画戟', 100)
print(ji.wname, ji.strength)
lb = Role('吕布', ji)
print(lb.name, lb.weapon.wname, lb.weapon.strength)
派生
- 当类之间有显著的不同,并且较小的类是较大的类所需要的组件时组合表现得很好;但当设计“相同的类但有一些不同的功能”时,派生就是一个更加合理的选择了
- OOP 的更强大方面之一是能够使用一个已经定义好的类,扩展它或者对其进行修,而不会影响系统中使用现存类的其它代码片段
- OOD(面向对象设计)允许类特征在子孙类或子类中进行继承
class Role:
def __init__(self, name, weapon):
# 构造器方法,实例化时自动调用,注意,self不是关键字,可以是任何自定义的变量
# 绑定在实例身上的属性,在类中任意位置可见可用
self.name = name
self.weapon = weapon
def show_me(self):
# 绑定在实例身上的属性,在类中任意位置可见可用
print('我是%s,我擅用%s' % (self.name, self.weapon))
def speak(self, words):
# 没有绑定在实例身上的变量,只是局部变量,只能用在函数中
hh = 'Hahaha'
print(hh)
print(words)
class Warrior(Role): # 括号中的类是该类的父类,也叫基类
# 子类将会直接继承父类所有的方法
def attack(self, target):
print('与%s近身肉搏' % target)
class Mage(Role):
def attack(self, target):
print('远程打击%s' % target)
if __name__ == '__main__':
# 实例本身将会自动作为第一个参数传递,本例中是lb
lb = Role('吕布', '方天画戟') # 实例化,创建具体的对象
print(lb.name, lb.weapon)
lb.show_me()
lb.speak('马中赤兔,人中吕布')
zf = Warrior('张飞', '丈八蛇矛')
zf.show_me()
zf.speak('吾乃燕人张飞张冀德')
zf.attack('吕布')
zgl = Mage('诸葛亮', '羽扇')
zgl.show_me()
zgl.attack('曹操')
- 如果父类和子类拥有相同的方法,子类实例优先执行子类方法
- 如果需要子类中执行父类的方法,可以明确调用
class Role:
def __init__(self, name, weapon, gender, menpai):
self.name = name
self.weapon = weapon
self.gender = gender
self.menpai = menpai
class Warrior(Role):
def __init__(self, name, weapon, gender, menpai, qq):
# Role.__init__(self, name, weapon, gender, menpai)
super(Warrior, self).__init__(name, weapon, gender, menpai)
self.qq = qq
if __name__ == '__main__':
lb = Warrior('lvbu', 'ji', 'male', 'ziji', '23423554')
- 多重继承:子类可以有多个父类。子类继承所有父类的方法。
- 如果有同名方法,查找顺序是自下向上,自左向右。
class A:
def func1(self):
print('A func')
def func4(self):
print('A func4')
class B:
def func2(self):
print('B func')
def func4(self):
print('B func4')
class C(B, A):
def func3(self):
print('C func')
if __name__ == '__main__':
c1 = C()
c1.func1()
c1.func2()
c1.func3()
c1.func4()
- 常用的魔法方法。在oop中,有很多以双下划线开头和结尾的属性,被称作magic。它们一般用于内部功能,了解即可。
# dir函数可以查看对象的方法
>>> type(10)
<class 'int'>
>>> dir(10)
>>> type('a')
<class 'str'>
>>> dir('a')
- 应该记住的有3个magic。
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__':
pybook = Book('Python基础教程(第3版)', 'Magnus Lie Hetland') # 调用__init__
print(pybook) # 调用__str__
pybook() # 调用__call__
re模块
- 将mac地址加冒号
192.168.1.1 00000C291234
192.168.1.2 52A3B2412C09
:%s/\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)$/\1:\2:\3:\4:\5:\6/
- re模块应用
>>> import re
# re.match在字符串food开头匹配f..,匹配到返回匹配对象,否则返回None
>>> re.match('f..', 'food')
<_sre.SRE_Match object; span=(0, 3), match='foo'>
>>> print(re.match('f..', 'seafood'))
None
>>> re.search('f..', 'seafood')
<_sre.SRE_Match object; span=(3, 6), match='foo'>
>>> m = re.search('f..', 'seafood')
>>> m.group() # 匹配对象的group方法返回匹配内容
'foo'
>>> re.findall('f..', 'seafood is food') # 返回所有匹配列表
['foo', 'foo']
>>> 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'
# 切割字符串
>>> s1 = 'how-are-you.tar.gz'
>>> re.split('-|\.', s1)
['how', 'are', 'you', 'tar', 'gz']
# 替换
>>> re.sub('X|Y', 'pet', 'X: cat, Y: dog')
'pet: cat, pet: dog'
- 当有大量内容进行匹配时,把正则模式字符串进行编译,将会有更好的执行效率
>>> patt = re.compile('f..')
>>> m = patt.search('seafood')
>>> m.group()
'foo'
>>> patt.findall('seafood is food')
['foo', 'foo']