- 分享
25.1.17 集训 —— 劳老师: 字符串方法 / 面向对象 / 异常捕获
- 2025-1-16 15:45:20 @
字符串方法
字符串实现了所有一般序列的操作
(s = "hello")
- 索引
s[1]
- 切片
s[1:3]
- 成员运算符
'e' in s
'l' not in s
- 拼接运算
s + 'python'
- 重复运算
s * 5
- 长度函数
len(s)
- 最值函数
max(s)
min(s)
- 查询方法
s.index('e')
- 计数方法
s.count('l')
其他方法, 可以查询官方文档
需要着重掌握的方法
s.join(iterable)
: 返回将字符 s
加入到 iterable
中拼接得到字符串。
lst = [1, 2, 3, 4, 5]
print(' '.join([str(x) for x in lst]))
# 输出得到:1 2 3 4 5
s.capitalize()
: 返回一个首字符大写其余小写的字符串副本。
s.find(obj)
: 返回第一个 obj
出现的索引。类似于 s.index(obj)
但是找不到元素时不会触发 ValueError
。类似的方法: s.rfind(obj)
从右往左查找。
判别
s.isalnum()
s.isalpha()
s.isdigit()
s.isidentifier()
s.islower()
s.isupper()
s.isspace()
转换大小写
s.upper()
s.lower()
s.title()
: 每个单词首字符大写
去除两端特定字符
s.lstrip([chars])
: 去除左侧的 chars
, 注意 chars
中的字符会尽可能被删除。
sites = ['www.baidu.com', 'www.sina.com', 'cc.google.com']
for site in sites:
print(site.lstrip('wc.'))
'''
输出:
baidu.com
sina.com
google.com
'''
类似的方法: s.rstrip([chars])
s.strip([chars])
分别用于删除右侧和两侧。
去除前缀
前面的方法存在一个问题, 如果想保留的元素也出现在了 chars
中,可能会由于删除特定字符而被误删,如果想精准删除前缀应该使用下面的方法。
s.removeprefix(str)
author = 'Author: Shen Lehao'
name = author.removeprefixc('Author: ')
类似的方法: s.removesuffix(str)
用于删除尾缀。
sites = '''
https://www.epicgames.com/
https://www.wegame.com.cn/
https://www.ali213.net/
https://www.3dmgame.com/
https://www.iqiyi.com/
https://www.youku.com/
https://www.mgtv.com/
https://www.douyu.com/
https://www.huya.com/
https://www.zhihu.com/
https://www.taobao.com/
https://www.jd.com/
'''
for site in sites.splitlines():
print('0.0.0.0', site.removeprefix('https://www.').removesuffix('/'))
print('0.0.0.0', site.removeprefix('https://').removesuffix('/'))
print()
替换
s.replace(old, new, count = -1) 将
old字符串替换为
new字符串, 替换前
count个, 当
count=-1` 时全部替换。
分隔
s.split(sep = None, maxsplit = -1)
默认的 sep
会让以任何空格作为分隔符并且会忽略前导和后缀空格, maxsplit
指定最多分隔次数, 用于一些题目特殊需求, 只切分输入进来的前几个数。
类似的方法: s.rsplit()
区别在于 maxsplit
指定后, 从后往前分隔。
面向对象
第一个示例 MyList
class MyList:
def __init__(self, data = []):
self.data = data
def __getitem__(self, index):
if 0 <= index < len(self.data):
return self.data[index]
def __repr__(self):
return '[' + ', '.join([str(x) for x in self.data]) + ']'
def append(self, obj):
self.data.append(obj)
def __eq__(self, others):
return self.data == others
if __name__ == '__main__':
lst = MyList([1, 2, 3])
lst.append(4)
print(lst[0], lst[1], lst[2], lst[3])
print(lst) # __repr__()
print(str(lst)) # __str__()
# print(lst == {1, 2, 3}) # __eq__() print(lst == [1, 2, 3, 4])
第二个示例 point
class Point:
def __init__(self, x = 0, y = 0):
self.x = x
self.y = y
def __repr__(self):
return f'Point({self.x}, {self.y})'
def __eq__(self, __value):
return self.x == __value.x and self.y == __value.y
# 也可以按照自己的逻辑实现一些其他运算
def upper(self, others):
return self.x > others.x
def uppereq(self, others):
return self.x >= others.x
def lower(self, others):
return self.x < others.x
def lowereq(self, others):
return self.x <= others.x
def toleft(self, dis):
self.x -= dis
def toright(self, dis):
self.x += dis
def toup(self, dis):
self.y += dis
def todown(self, dis):
self.y -= dis
if __name__ == '__main__':
p1 = Point(1, 2)
p2 = Point(0, 2)
p3 = Point(0, 3)
print(p1.upper(p2))
print(p2.uppereq(p3))
print(p1.toleft(15))
print(p1)
第三个示例 Hero
class wuqi:
def __init__(self, name, atk):
self.name = name
self.atk = 150
class hero:
def __init__(self, name, hp, atk):
self.wuqi = None
self.name = name
self.hp = hp
self.atk = atk
self.dfs = 10
self.alive = True
def __repr__(self):
if self.alive == True:
if self.wuqi != None:
return f'\n英雄{self.name} 目前血量:{self.hp} 目前攻击力:{self.atk} 目前防御力:{self.dfs} 目前装备:{self.wuqi.name}'
else:
return f'\n英雄{self.name} 目前血量:{self.hp} 目前攻击力:{self.atk} 目前防御力:{self.dfs}'
else:
return f'\n英雄{self.name}已阵亡'
def zhuangbei(self, wuqi):
print(f'\n英雄{self.name}装备了{wuqi.name}')
self.atk += wuqi.atk
self.wuqi = wuqi
def attack(self, other):
'''other: 必须传入也是 hero 的实例 或 的对象'''
print(f'攻击方:{self.name} 防守方:{other.name}')
other.hp -= (self.atk - other.dfs)
if other.hp <= 0:
other.hp = 0
other.alive = False
return None
self.hp -= (other.atk - self.dfs)
if self.hp <= 0:
self.hp = 0
self.alive = False
return None
if __name__ == '__main__':
lbqh = hero('鲁班七号', 100, 20)
cyj = hero('程咬金', 150, 14)
print(lbqh, cyj)
lbqh.attack(cyj)
print(lbqh, cyj)
cyj.zhuangbei(wuqi('破伤风之刃', 200))
cyj.attack(lbqh)
print(lbqh, cyj)
异常与捕获
异常捕获结构
try:
expression
except:
expression
运行流程: 当且仅当 try
中的语句块出现异常, 程序转而执行 except
中的语句块。
常见异常
IndexError
KeyError
NameError
SyntaxError
TypeError
ValueError
ZeroDivisionError
# IndexError
# print([1,2,3][3])
# KeyError
# print({1:10, 2:20}[3])
# NameError
# print(a)
# SyntaxError
# print()1
# TypeError
# [1, 2, 3] + (1, 2, 3)
# ValueError 值错误
# int('1.5')
# ZeroDivisionError
# 10/0
定义异常
原理: 继承python内的 Exception
类
class MyError(Exception):
def __init__(self, message):
self.message = message
def __str__(self):
return f'MyError: {self.message}'
if __name__ == '__main__':
raise(MyError('错误测试'))
报错:
Traceback (most recent call last):
File "/Users/laozhenyu/PycharmProjects/StudentsLearningFace/pythonProject/main.py", line 9, in <module>
raise(MyError('错误测试'))
MyError: MyError: 错误测试
多异常场景
class MyError(Exception):
def __init__(self, message = '我的错误原因'):
self.message = message
def __str__(self):
return f'MyError: {self.message}'
if __name__ == '__main__':
n = int(input())
try:
if n == 1:
raise(ValueError())
elif n == 2:
raise(IndexError('index out of range'))
elif n == 3:
raise(MyError())
except ValueError as v:
print('请你调整数据值')
except IndexError as i:
print(i)
except MyError as m:
print(m)
class MyIndexError(Exception):
def __init__(self, message = ''):
self.message = message
def __repr__(self):
return f'MyIndexError: {self.message}'
class MyList:
def __init__(self, data = []):
self.data = data
def __getitem__(self, index):
if 0 <= index < len(self.data):
return self.data[index]
else:
raise MyIndexError('myindex out of range')
def __repr__(self):
return '[' + ', '.join([str(x) for x in self.data]) + ']'
def append(self, obj):
self.data.append(obj)
def __eq__(self, others):
if type(others) not in {type([]), type((1, )), type(""), type(MyList())}:
raise ValueError('无法进行比较')
return self.data == others
if __name__ == '__main__':
lst = MyList([1, 2, 3])
lst.append(4)
print(lst[0], lst[1], lst[2], lst[3])
print(lst) # __repr__()
print(str(lst)) # __str__()
# print(lst == {1, 2, 3}) # __eq__() print(lst == [1, 2, 3, 4])
class Point:
def __init__(self, x = 0, y = 0):
self.x = x
self.y = y
def __repr__(self):
return f'Point({self.x}, {self.y})'
def __eq__(self, __value):
return self.x == __value.x and self.y == __value.y
# 也可以按照自己的逻辑实现一些其他运算
def upper(self, others):
return self.x > others.x
def uppereq(self, others):
return self.x >= others.x
def lower(self, others):
return self.x < others.x
def lowereq(self, others):
return self.x <= others.x
def toleft(self, dis):
# 可以加上异常捕获, 检测 dis 是否可以和 self.x 运算
try:
self.x -= dis
except:
raise TypeError(f'type {str(type(dis)).split()[1].replace('\'', '').replace('>', '')} can not add to Point.x')
def toright(self, dis):
self.x += dis
def toup(self, dis):
self.y += dis
def todown(self, dis):
self.y -= dis
if __name__ == '__main__':
p1 = Point(1, 2)
p2 = Point(0, 2)
p3 = Point(0, 3)
print(p1.upper(p2))
print(p2.uppereq(p3))
print(p1.toleft([1, 2, 3]))
print(p1)
练习题
- 实现自己的
len()
应考虑传入的是否可以迭代 - 实现自己的
max()
应考虑是否可以比出大小 - 实现自己的
sum()
- 实现自己的
sorted(iterable, reverse=False)
可以选择目前所学的排序算法(实际上是元素少的情况下插入排序, 元素多的情况下快速排序) - 实现自己的
abs()
返回绝对值, 挑战为不使用if else
- 实现自己的
split(str, sep = None, maxsplit = -1)
可以实现普通的函数,而不是类的方法
后面的文字都是属于挑战内容,实际上真的很难达到编写标准函数的水平,可以不挑战,试图去思考一下,其实标准函数的内部实现比我们想的要复杂很多,正是因为如此,我们编写python代码、使用python函数才会如此轻松。