生成器、面向对象、构造函数、正则表达式 (regular exp
-
昨天回顾
-
异常
- try 语句
- raise 语句
-
bytes 和 bytearray
-
文件的操作
-
按输入和输出分为:
- 读
'r'
- 写
'w'
- 读
-
按读写方式分为:
- 文本方式(以字符串的方式进行读写)
'wt', 'rt'
- 二进制方式(以字节串的方式进行读写)
'wb', 'rb'
- 文本方式(以字符串的方式进行读写)
-
函数和方法
fr = open('文件路径名', 'rb') fr.read(1) # fr.read() # 读取全部 fr.readline() fr.readlines() fr.close() fw = open('文件路径名', 'wb') fr.write(b'ABCD') fr.close(0) fr = open('文件路径名', 'rb') fr.seek(5, 0) pos = fr.tell() print(pos) # 5 fr.read() fr.close()
-
-
模块
os模块
sys模块
os.path模块
shutil模块
-
语句
- with 语句
-
生成器
生成器是在程序运行时生成数据,与容器不同,它通常不会再内存中保留大量的数据,而是现用现生成。
生成器可以用算法动态的生成数据
生成器有两种
- 生成器函数
- 生成器表达式
生成器函数
含有yield 语句的函数 是生成器函数,此函数调用回返回一个生成器对象,生成器也是可迭代对象
yield 语句的语法
yield 表达式
生成器函数示例:
# 定义一个生成器函数, 有 yield 的函数调用后回返回生成器对象
def myrange(stop):
i = 0
while i < stop:
yield i # 为 遍历次生产器的for 语句提供数据
i += 1
for x in myrange(5):
print('x=', x)
生成器表达式
- 语法:
( 表达式 for 变量 in 可迭代对象 [if 真值表达式])
[] 内容代表可以省略
-
作用
用推导式的形式创建一个生成器
-
示例
>>> [x ** 2 for x in range(1, 5)] # 列表解析(列表推导式) [1, 4, 9, 16] >>> (x ** 2 for x in range(1, 5)) # 生成器表达式 <generator object <genexpr> at 0x7f41dcd30a40> >>> for y in (x ** 2 for x in range(1, 5)): ... print(y) ... 1 4 9 16
面向对象编程 Object-Oriented Programming(OOP)
程序 = 数据 + 算法(操作数据的方式可方法)
-
数据
数字
字符串
容器
-
算法
函数
-
模块
数据 + 函数 + 类
函数式编程, 数据和行为(函数) 是分开的
Person1 = {
'name': 'weimingze',
'age': 35
}
Person2 = {
'name': 'xiaozhang',
'age': 18
}
def update_age(person):
person['age'] += 1
update_age(Person1)
update_age(Person2)
-
对象
是指现实世界的物体
-
什么是面向对象
把一切看成对象(实例), 用各个对象的关系来描述事物
-
对象的特征
- 对象有很多属性(名词,形容词,...), 数据
- 姓名, 年龄,性别....
- 对象有很多行为(动作,动词), 方法(属于某个对象的函数)
- 学习,吃饭, 踢球,工作
- 对象有很多属性(名词,形容词,...), 数据
-
类
拥有相同属性和行为的对象分为一组,即为一个类
/-------> BYD E6(京A.88888) 实例(也叫对象)
车(类)
\-------> BWM X5(京B.66666) 实例(也叫对象)
/-------> 100 (对象)
int(类)
\-------> 200 (对象)
/---> True
bool(类)
\---> False
int float dict list tuple
class 语句
-
语法
class 类名 (继承列表):
语句 -
作用
创建一个类
类用于描述对象的行为和属性
类可以创建一个或多个对象
-
示例
class Car: pass
构造函数
-
调用表达式
类名(实参)
-
作用
创建这个类的实例对象
-
示例
car1 = Car() # 创建 第一个Car 类型的对象 car2 = Car() # 创建 另一个Car 类型的对象 # L1 = list() # 创建 第一个 list 类型的列表 L2 = list() # 创建 另一个 list 类型的列表
实例属性
每个对象可以有自己的变量,称之为实例属性
属性的使用语法
实例.属性名
遵循变量的赋值规则
-
示例
car1.color = '红色' # 颜色 为 car1 创建属性 color 绑定 '红色' car1.brand = '比亚迪' # brand 品牌 car1.plate = '京A.88888' # 牌照 car2.color = '白色' car2.brand = '宝马' car2.plate = '京B.66666'
删除属性用 del 语句
# 如
del car1.color
实例方法(instance method)
-
定义的语法
class 类名[继承列表]: def 实例方法名(self, 形参名1, 形参名2, 形参名3, ....): 语句块
-
作用
用于描述一个对象的行为,让此类型的全部对象都有相同的行为
-
说明
实例方法的实质是一个函数,他是定义在类内的函数
实例方法至少有一个形参,第一个形参绑定调用这个方法的实例,一般命名为 self
-
调用语法
实例.实例方法名(实参列表)
# 或
类名.实例方法名(实例,实参列表) -
示例
# 类的定义 class Car: # 实例object方法 def run(self, km): print(self.color, '的', self.brand, self.plate, '正在以', km, '公里/小时的速度行使') .... 此处省略了创建对象的和添加属性的代码 # 调用方法 car1.run(110) car2.run(180) # 方法2 # Car.run(car1, 120) # Car.run(car2, 160)
初始化方法(也叫构造器方法)
-
作用
对新创建的对象添加属性
-
语法格式
class 类名:
def _init_(self [,形参列表]):
语句块 -
说明
- 初始化方法名 必须为
__init__
- 初始化方法会在类创建实例时自动调用,且将实例对象通过第一个参数传入
__init__
方法 - 构造函数的实参将通过
__init__
的参数列表传入到__init__
方法中 - 初始化方法内如果需要用return 语句返回,则必须返回None
- 初始化方法名 必须为
-
练习
# 写一个小狗类
class Dog:
def __init__(self, ...):
pass
dog1 = Dog('白色', '藏獒')
dog1.eat(1, '羊肉') # 白色 的 藏獒 吃了 1 斤 羊肉,
dog2 = Dog('灰色', '导盲犬')
dog2.eat(2, '狗粮') # 灰色 的 导盲犬 吃了 2 斤 狗粮,
dog1.eat(2, '牛肉') # 白色 的 藏獒 吃了 2 斤 牛肉,
dog1.info() # 白色 的 藏獒 吃过 ['羊肉', '牛肉']
dog2.info() # 灰色 的 导盲犬 吃过 ['狗粮']
答案
# 写一个小狗类
class Dog:
def __init__(self, color, kind):
self.color = color
self.kind = kind
self.foods = [] # 用来记录吃过的食物
def eat(self, weight, food):
print(self.color, '的', self.kind, '吃了', weight, '斤', food)
self.foods.append(food) # 追加到 foods 列表里
def info(self):
print(self.color, '的', self.kind, '吃过', self.foods)
dog1 = Dog('白色', '藏獒')
dog1.eat(1, '羊肉') # 白色 的 藏獒 吃了 1 斤 羊肉,
dog2 = Dog('灰色', '导盲犬')
dog2.eat(2, '狗粮') # 灰色 的 导盲犬 吃了 2 斤 狗粮,
dog1.eat(2, '牛肉') # 白色 的 藏獒 吃了 2 斤 牛肉,
dog1.info() # 白色 的 藏獒 吃过 ['羊肉', '牛肉']
dog2.info() # 灰色 的 导盲犬 吃过 ['狗粮']
继承(inheritance)和派生(derived)
继承是从已经有的类中派生出新类,新类具有父类的属性和行为,并能扩展新的能力
派生是从已经有的类中衍生出新类,在新类的基础上可以添加属性和行为
-
作用
- 用继承派生机制,可以将一些共有的功能加在基类(也叫父类)中,实现代码共享
- 在不改变基类代码的基础上,改变原有的功能。
-
语法
class 类名(基类名):
语句块 -
示例1
# 继承的示例
# Human 类派生出 Student 类
class Human: # 定义一个人类
def say(self, what):
'说'
print("说:", what)
def walk(self, distance):
'走路'
print('走了', distance, '公里')
class Student(Human): # 定义一个学生了
def study(self, subject):
print('学习', subject)
class Teacher(Human):
def teach(self, language):
print('教', language)
h1 = Human()
h1.say('天气真好')
h1.walk(5)
s1 = Student()
s1.walk(4)
s1.say('有点累')
s1.study('面向对象')
t1 = Teacher()
t1.teach('Python')
t1.say('今天周四')
t1.walk(6)
-
显式调用基类的初始化方法 super 函数
super() # 返回父类对象
覆盖
覆盖是指在有继承关系的类中,子类中实现了与父类中同名的方法,在子类实例调用该方法时,实际调用的是子类中的覆盖版本,这种现象叫覆盖
组合
class MyList:
def __init__(self):
self.data = []
def append(self, n):
self.data.append(n)
def insert_head(self, n):
self.data.insert(0, n)
L1 = MyList() # MyList 类型的对象中包含一个 list 类型的对象,这种叫组合
L1.append(100)
L1.insert_head(0)
继承
class MyList(list):
def insert_head(self, n):
self.insert(0, n)
L1 = MyList() # MyList 类型的对象中包含一个 list 类型的对象,这种叫组合
L1.append(100)
L1.insert_head(0)
print(L1)
多继承
多继承是指一个子类由两个或两个以上的父类(基类)
- 语法
class 类名(基类1,基类2, ...):
语句块
-
示例
class Plane: def fly(self, height): print("飞机以海拔", height,'米的高度飞行') class Car: def run(self, speed): print("汽车以", speed, '公里/小时的速度行驶') class PlaneCar(Plane, Car): pass pc = PlaneCar() pc.run(120) pc.fly(10000)
多继承可能会带来程序运行的不确定性,谨慎使用
>>> class A:
... def m(self):
... print('A')
...
>>> class B:
... def m(self):
... print("B")
...
>>> class C(A, B):
... pass
...
>>> c = C()
>>> c.m()
A
>>> class D(B, A):
... pass
...
>>> d = D()
>>> d.m()
B
-
常用魔法方法, 在类定义中,很多以 双下划线开头和结尾的方法被称为魔法方法,是python 定义特殊功能的方法,
用dir函数可以查看对象的全部方法
>>> dir(list)
...
三个魔法方法
class Book:
def __init__(self, title, author):
'''初始化方法,在实例化时自动调用'''
self.title = title # 标题
self.author = author # 作者
def __str__(self): # 课间休息: 17:10 回来
'''将对象转成字符的时候会调用'''
return "《%s》" % self.title
def __call__(self):
'''将实例当成函数来调用,执行此函数内的代码'''
print('《%s》是%s 编著的' % (self.title, self.author))
if __name__ == '__main__':
b1 = Book('Linux 运维之道', '丁明一')
print(b1)
b1()
正则表达式 (regular express)
正则表达式是表示 文字的排列规则的一个字符串, 使用来匹配文字的匹配模式.
-
作用
用于文字的定位,搜索和内容的提取
元字符
类别 | 元字符 |
---|---|
匹配字符 |
. [...] [^...] \d \D \w \W \s \S |
匹配重复 |
* + ? {n} {m,n}
|
匹配位置 | ^ $ \b \B |
其他 | ` |
-
普通字符
ab' # 普通字符 只匹配'ab'</pre> >>> import re # 导入正则表表达式模块 >>> s = 'abcdeabca' >>> re.findall('ab', s) ['ab', 'ab']
-
或关系
| 匹配两侧任意的正则表达式
>>> import re # 导入正则表表达式模块 >>> s = 'abcdeabca' >>> re.findall('ab|de', s) ['ab', 'de', 'ab']
-
匹配单个字符串
. 匹配除换行符 以外的任意的一个字符 >>> import re >>> re.findall('张.丰', '张三丰,张四丰,张老师') ['张三丰','张四丰']
-
匹配字符集
[字符集] 匹配其中的一个字符
>>> import re >>> s = 'How are you!' >>> re.findall('[aeiou]', s) ['o', 'a', 'e', 'o', 'u'] >>> re.findall('[0-9A-Za-z]', 'A$%^^%b!#$@!#$0') ['A', 'b','0']
^ 匹配目标字符的开始位置
$ 匹配目标字符的结束位置>>> re.findall('^hello', 'hello world') ['hello'] >>> re.findall('^hello', 'a hello world') [] >>> re.findall('world/pre>, 'hello world') ['world']
* 匹配前面的字符出现 0 或多次
+ 匹配前面的字符出现 1 或多次
? 匹配前面的字符出现 0 或1次>>> re.findall('wo*', 'wooooooo~~w! woo') ['wooooooo', 'woo'] >>> re.findall('[A-Z][a-z]+', 'Hello World abcd') ['Hello','World'] >>> re.findall('-?[0-9]+', 'name: Jame, age: 18, money:-100') ['18', '-100']
{n} # 前面的字符出现n 次
{m,n} # 前面的字符出现m到n次>>> re.findall('[0-9]{3}', '888 9999 1000000') ['888', '999', '100', '000'] >>> re.findall('[0-9]{4,10}', '888 9999 1000000') ['9999', '1000000']
\d 匹配任意的数字 [0-9]
\D 匹配任意的非数字>>> re.findall('\d{1,5}', 'MySql: 3306, http:80') ['3306', '80']
\w 匹配普通字符
\W 匹配非普通字符
普通字符是指 数字,字母,下划线,汉字>>> re.findall('\w+', 'MySql: 3306, http:80') ['MySql', '3306', 'http', '80']
\s 匹配空字符
\S 匹配非空字符
空字符是指 '\r' '\n' '\t' '\v' '\f'>>> re.findall('\w+\s+\w+', 'hello world') ['hello world']
\b 表示单词的边界
\B 表示非单词的边界>>> re.findall(r'\bis\b', 'This is a test') ['is']
>>> s = '''SERVER = 192.168.9.102 PORT = 80 SERVERNAME = GAME1 REMOTE = 188.3.69.888 ''' >>> server_re = r'SERVER\s*=\s*[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' server_ip = re.findall(server_re, s) >>> server_re = r'SERVER\s*=\s*[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' >>> server_ip = re.findall(server_re, s) >>> server_ip
['SERVER = 192.168.9.102'] >>> ip_list = re.findall(r'[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}', server_ip[0]) print("SERVER=", ip_list[0])
- 课后练习1
算出 100 ~ 999 的水仙花数
水仙花数是 指百位的3次方 + 十位的3次方 + 各位的3次方 等于原数的数
打印出所有的 水仙花数
例如:
- 课后练习2
打印 九九 乘法表
1x1=1
1x2=2 2x2=4
1x3=3 2x3=6 3x3=9
....
1x9=9 ........ 9x9=81