Python学习笔记#10 面向对象的应用(异常处理、文件备份)

1.装饰器(1) 用于拓展原来函数功能的一种函数(2) 返回函数的函数(3) 在不用更改原函数代码的前提下给函数增加新的功能例:def log(func): """记录函数执行的日志""" def wrapper(): print('开始执行') func() print('执行完毕') return wrapper...
摘要由CSDN通过智能技术生成

1.装饰器
(1) 用于拓展原来函数功能的一种函数
(2) 返回函数的函数
(3) 在不用更改原函数代码的前提下给函数增加新的功能
例:

def log(func):
    """记录函数执行的日志"""
    def wrapper():
        print('开始执行')
        func()
        print('执行完毕')
    return wrapper

@log
def hello():
    """简单功能模拟"""
    print("Hello PyCharm")

if __name__ == '__main__':
    hello()

输出 -->

开始执行
Hello PyCharm
执行完毕

2.带参数的装饰器
(1)

def log(name = None):

    def decorator(func):
        def wrapper():
            print('{0}开始执行'.format(name))
            func()
            print('{0}执行完毕'.format(name))
        return wrapper
    return decorator

@log('装饰器函数')
def hello():
    """简单功能模拟"""
    print("Hello PyCharm")

if __name__ == '__main__':
    hello()

输出 -->

装饰器函数开始执行
Hello PyCharm
装饰器函数执行完毕

(2) 带魔法参数的装饰器 :
PS: 当函数的参数不确定时,可以使用*args 和**kwargs。
*args:表示的就是将实参中按照位置传值,多出来的值都给args,且以元组的方式呈现
**kwargs:表示的就是形参中按照关键字传值把多余的传值以字典的方式呈现

def log(name=None):

    def decorator(func):
        def wrapper(*args, **kwargs):
            print('{0}开始执行'.format(name))
            print(args, kwargs)
            func(*args, **kwargs)
            print('{0}执行完毕'.format(name))
        return wrapper
    return decorator

@log('from add')
def add(a, b):
    return a + b

if __name__ == '__main__':
    add(5, 6)

输出 -->

from add开始执行
(5, 6) {}
from add执行完毕

(3) @wraps
当装饰器装饰一个函数时,实际上就是将被装饰的函数作为一个参数传入装饰器函数,返回一个闭包,而闭包内部调用这个函数,再另外多做一些事情。然后再由我们的函数名字去接收那个返回值的闭包的引用,达到了我们装饰的目的,所以此时,我们的函数的__name__等属性其实已经改变,变成了我们闭包的私有属性。
functools.wraps()这个函数,作为一个装饰器去装饰闭包,并且给这个装饰器传入一个参数,这个参数是闭包外的装饰器装饰的那个外部的被装饰函数,此时,外部我们的自定义的函数的私有属性如_name__、_doc__等还是为我们自定义的函数本身的私有属性,而不会变成闭包的私有属性。
@wraps 可以确保我们调用文档、查看帮助时, 查找到的是我们原函数的属性, 而非所用装饰器的属性

(4) 类的装饰器

def eat(cls):
    """吃东西装饰器"""
    cls.eat = lambda self: print("{0}:我要吃东西".format(self.name))
    return cls

@eat
class Cat(object):
    """猫类"""
    def __init__(self, name):
        self.name = name

if __name__ == '__main__':
    cat = Cat('小黑')
    cat.eat()

输出 -->

小黑:我要吃东西

3.迭代器与生成器
(1) 迭代器
1 实现了__iter__的对象是可迭代的, 而实现了方法__next__的对象是迭代器
2 调用方法__next__( 或next() )时, 迭代器返回下一个值
3 如果迭代器没有可供返回的值, 触发Stoplteration异常
(2) 生成器
1 生成器是一种使用普通函数语法定义的迭代器
2 包含yield语句的函数都被称为生成器
每次使用yield生成一个值后, 函数都将冻结, 即在此停止执行;
被重新唤醒后, 函数将从停止的地方开始继续执行。
3 不使用return返回一个值, 而是可以生成多个值, 每次一个

4.文件备份

import os
import os.path

class FileBackup(object):
    """
    文本文件备份
    """
    def __init__(self, src, dist):
        """
        构造方法
        :param src: 目录 需要备份的文件目录
        :param dist: 目录 备份后的目录
        """
        self.src = src
        self.dist = dist

    def read_files(self):
        """读取src目录下的所有文件"""
        ls = os.listdir(self.src)
        print("ls:{0}".format(ls))
        for l in ls:
            # 循环处理每一个文件/文件夹
            self.backup_file(l)

    def backup_file(self, file_name):
        """
        处理备份
        :param file_name: 文件/文件夹目录
        """
        # 1 判断dist是否存在. 若不存在, 则创建该目录
        if not os.path.exists(self.dist):
            os.makedirs(self.dist)
            print('指定的目录不存在, 创建完成')
        # 2 判断文件是否为我们要备份的文件
        # 拼接文件的完整路径
        full_src_path = os.path.join(self.src, file_name)
        full_dist_path = os.path.join(self.dist, file_name)

        # 首先要判断是否为文件夹, 然后可以借助文件的后缀名进行判断
        if os.path.isfile(full_src_path) and os.path.splitext(file_name)[-1].lower() == '.txt':
            print("full_src_path:{0}".format(full_src_path))
            # 3 读取文件内容
            with open(full_dist_path, 'w', encoding='utf-8') as f_dist:
                print(">>开始备份【{0}】".format(file_name))
                with open(full_src_path, 'r', encoding='utf-8') as f_src:
                    while True:
                        rest = f_src.read(100)
                        if not rest:
                            break
                        # 4 把读取到的文件内容写入到新的文件中
                        f_dist.write(rest)
                    f_dist.flush()
                print(">>>备份完成【{0}】".format(file_name))
        else:
            print("文件类型不符合备份要求, 跳过>>")

if __name__ == '__main__':
    # 要备份的文件目录地址
    # src_path = 'E:\\PyCharmWP\\src'
    # 备份后的目录地址
    # dist_path = 'E:\\PyCharmWP\\dict'

    base_path = os.path.dirname(os.path.abspath(__file__))
    print("base_path:{0}".format(base_path))
    # 要备份的文件目录地址
    src_path = os.path.join(base_path, 'src')
    print("src_path:{0}".format(src_path))
    # 备份后的目录地址
    dist_path = os.path.join(base_path, 'dist')
    print("dist_path:{0}".format(dist_path))

    bak = FileBackup(src_path, dist_path)
    bak.read_files()

5.异常处理
内置的异常类
自定义异常:

class ApiException(Exception):
    """我的自定义异常"""
    err_code = ''
    err_msg = ''

    def __init__(self, err_code=None, err_msg=None):

        self.err_code = self.err_code if self.err_code else err_code
        self.err_msg = self.err_msg if self.err_msg else err_msg

    def __str__(self):
        return 'Error: {0} - {1}'.format(self.err_code, self.err_msg)


class BadPramsException(ApiException):
    """参数不正确"""
    err_code = '400002'
    err_msg = '两个参数都必须是整数'


def divide(num1, num2):
    # 两个数必须为整数
    if not isinstance(num1, int) or not isinstance(num2, int):
        raise BadPramsException()
    # 除数不能为0
    if num2 == 0:
        raise ApiException('400000', '除数不能为0')
    return num1 / num2


if __name__ == '__main__':
    try:
        rest = divide(5, 's')
        print(rest)
    except BadPramsException as e:
        print("----------")
        print(e)
    except ApiException as err:
        print("出错了")
        print(err)

输出:Error: 400002 - 两个参数都必须是整数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于计算机专业的学生而言,参加各类比赛能够带来多方面的益处,具体包括但不限于以下几点: 技能提升: 参与比赛促使学生深入学习和掌握计算机领域的专业知识与技能,如编程语言、算法设计、软件工程、网络安全等。 比赛通常涉及实际问题的解决,有助于将理论知识应用于实践中,增强问题解决能力。 实践经验: 大多数比赛都要求参赛者设计并实现解决方案,这提供了宝贵的动手操作机会,有助于积累项目经验。 实践经验对于计算机专业的学生尤为重要,因为雇主往往更青睐有实际项目背景的候选人。 团队合作: 许多比赛鼓励团队协作,这有助于培养学生的团队精神、沟通技巧和领导能力。 团队合作还能促进学生之间的知识共享和思维碰撞,有助于形成更全面的解决方案。 职业发展: 获奖经历可以显著增强简历的吸引力,为求职或继续深造提供有力支持。 某些比赛可能直接与企业合作,提供实习、工作机会或奖学金,为学生的职业生涯打开更多门路。 网络拓展: 比赛是结识同行业人才的好机会,可以帮助学生建立行业联系,这对于未来的职业发展非常重要。 奖金与荣誉: 许多比赛提供奖金或奖品,这不仅能给予学生经济上的奖励,还能增强其成就感和自信心。 荣誉证书或奖状可以证明学生的成就,对个人品牌建设有积极作用。 创新与研究: 参加比赛可以激发学生的创新思维,推动科研项目的开展,有时甚至能促成学术论文的发表。 个人成长: 在准备和参加比赛的过程中,学生将面临压力与挑战,这有助于培养良好的心理素质和抗压能力。 自我挑战和克服困难的经历对个人成长有着深远的影响。 综上所述,参加计算机领域的比赛对于学生来说是一个全面发展的平台,不仅可以提升专业技能,还能增强团队协作、沟通、解决问题的能力,并为未来的职业生涯奠定坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值