• 分享
  • 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)

练习题

  1. 实现自己的 len() 应考虑传入的是否可以迭代
  2. 实现自己的 max() 应考虑是否可以比出大小
  3. 实现自己的 sum()
  4. 实现自己的 sorted(iterable, reverse=False) 可以选择目前所学的排序算法(实际上是元素少的情况下插入排序, 元素多的情况下快速排序)
  5. 实现自己的 abs() 返回绝对值, 挑战为不使用 if else
  6. 实现自己的 split(str, sep = None, maxsplit = -1) 可以实现普通的函数,而不是类的方法

后面的文字都是属于挑战内容,实际上真的很难达到编写标准函数的水平,可以不挑战,试图去思考一下,其实标准函数的内部实现比我们想的要复杂很多,正是因为如此,我们编写python代码、使用python函数才会如此轻松。

0 条评论

目前还没有评论...