内容补充-异常

"""
异常
用于处理报错信息的方法,可以自定义报错信息
语法:
try:
    代码体
except:
    代码体
    
程序会先运行try中的代码,如果出现报错,那么则执行except下的代码内容
"""
# 创建一个生成器对象,里面的内容为1-3
iter1 = (i for i in range(1,4))
# 进行异常测试
try:
    print(next(iter1))
    print(next(iter1))
    print(next(iter1))
    print(next(iter1))  # 生成器中只有三个数字,如果执行这一行则会报错
except:
    print('生成器已经结束')  # try中的代码遇到错误,则执行这一行代替错误信息
​
​
try:
    with open('D:\softData\PycharmProjects\ChengQuEdu\\textfile.txt','r')as f:
        print(f.read())
except Exception as e:  # 可以使用Exception调出报错信息进行输出
    print(e)
    print('你所查询的文件不存在')
else:  # 也可以与else连用
    print('已查询到这个文件的所有内容')
finally:  # 以上的代码运行完成后,运行finally的内容
    print('查询完成')
​
    
# raise 手动抛出异常,可以自己修改报错后的提示内容
def division(x,y):
    if y == 0:
        raise ZeroDivisionError('除数不能为零')
    else:
        return x / y
division(10,0)
    
"""
断言
assert
用于布尔类型判断,如果是True则不做任何操作
"""
a = 5
b = 10
assert a < b

类的定义与调用

​
"""
类的创建方法
class 类名称:
    类的属性
​
    类的行为
​
class是关键字,表示要开始定义类了
类的属性 -> 定义在类中的变量(成员变量)
类的行为 -> 定义在类中的函数(成员方法)
​
创建类的对象的语法:
对象 = 类名称()
​
类中定义成员方法和定义函数基本一致,但有细微区别
def 方法名(self,形参1,....,形参n):
    方法体
​
self关键字:
    成员方法定义时,必须填写的(通常会自己补全)
它用来表示类对象自身的意思
当我们使用类对象调用方法时,self会自动被python传入
*在方法内部,想要访问类的成员变量,必须使用self访问
"""
# 定义一个类
class Student:
    # 设计表格的内容
    name = None
    # 创建类的行为/方法:本意为在类中创建所有对象使用的函数
    def success(self):
        print(f'{self.name}同学已成功在老师这里报名')
    def say_hi(self):  #  self关键字是在方法中必须出现的一个关键字,当然也可以忽略它,但是必须要存在
        print('同学们好,老师好')
    def say_hi2(self, msg):
        print(f'大家好,我是{self.name},{msg}')
# 基于类创建对象
stu1 = Student()
stu1.name = "小明"
stu1.success()
stu1.say_hi()
​
stu2 = Student()
stu2.name = '周杰轮'
stu2.say_hi2('哎哟不错哦')
​
# 以上属性赋值需要依次进行,略显繁琐,有没有更加高效的方式,能够一行代码就完成呢?

构造方法

"""
python类中可以使用: __init__()方法,称之为构造方法
可以实现:
    在创建类对象(构造类)的时候,会自动执行
    在创建类对象(构造类)的时候,将传入的参数自动传递给__init__方法使用
"""
​
"""
类的构造方法
"""
# 使用构造方法对成员变量进行赋值
# 构造方法的名称:__init__
class Student:
    def __init__(self, name, age, tel):  # 使用构造方法无需额外定义变量属性
        self.name = name
        self.age = age
        self.tel = tel
        # 验证构造方法是否会自动运行起来
        print('Student类创建了一个类对象')
stu1 = Student('周杰轮',31,'19266668888')
print(stu1.name)
print(stu1.age)
print(stu1.tel)

基于对象使用的函数

​
"""
基于对象使用,访问对象内成员变量的函数
hasattr    判断属性是否存在
getattr    得到属性值,没有则报错
setattr    设置属性值,有则改无则增
delattr    删除属性
"""
​
# 创造一个学生类
class Student:
    def __init__(self,name,age,sex):
        self.name = name
        self.age =age
        self.sex = sex
    def sport(self):
        print(f'{self.name}同学是一个{self.sex}生,现在准备去操场运动')
​
    def sing(self):
        print(f'{self.name}同学今年{self.age}岁了,现在准备高歌一曲')
​
stu = Student('张三', 29, '男')
print(stu.name)
# print(stu.hobby)  # 不存在这个成员变量,报错
​
# getattr函数,平常打印输出对象中的成员变量一样,不存在则报错
print(getattr(stu, 'name'))
# print(getattr(stu, 'hobby'))
​
​
# hasattr函数,判断是否存在,结果为布尔值
print(hasattr(stu, 'hobby'))  # False
print(hasattr(stu, 'name'))  # True
​
# setattr函数,设置属性值
setattr(stu,'sex','女')
setattr(stu,'hobby', '跳舞')
print(stu.sex)
print(stu.hobby)
​
# delattr函数,删除存在的成员变量
delattr(stu,'hobbby')
# print(stu.hobby)  # 删除之后就不存在了
​
# 1.使用条件判断成员变量的值是否存在
# 存在则输出
if hasattr(stu,'height'):  # 判断成员变量 身高
    print(getattr(stu, 'height'))
# 不存在则设置新成员变量
else:
    setattr(stu,'height','180')
print(stu.height)

判断对象关系的方法

"""
is         判断对象是否属于该类,不考虑继承关系
isinstance 判断对象是否是后面的类的实例化对象,考虑继承关系
issubclass 判断第一个类继承于后面类,考虑继承关系
type也可以判断,但是只能判断单个类
​
"""
​
​
class common_phone:
    pass
class smart_phone(common_phone):
    pass
# 实例化对象
nokia = common_phone()
Huawei = smart_phone()
# 判断Huawei 是否属于普通手机类
print(Huawei is common_phone)  # False
​
# type可以判断,仅限单个类判断
print(type(Huawei) == smart_phone)
​
# 判断对象是否是后面的类的实例化对象,考虑继承关系
print(isinstance(Huawei,common_phone)) # True
​
# 判断前面类是否继承了后面类
print(issubclass(smart_phone,common_phone))

装饰器

"""
装饰器:
    在不破坏目标函数原有的代码和功能的前提下,为目标函数增加新功能
用法:
    创建一个闭包函数,在闭包函数内调用目标函数
    将装饰函数作为参数,使用 @装饰函数 放在需要增加功能的函数上面
"""
​
# 装饰器的一般写法  装饰函数里面写入形参,形参()就相当于添加的功能函数
def outer(func):
    def inner():
        print('我睡觉了')
        func()
        print('我起床了')
    return inner
@outer
def sleep():
    import random
    import time
    print('睡眠中......')
    time.sleep(random.randint(1, 5))
# fn = outer(sleep)
# fn()
sleep()
​
# 带参数装饰器
def compute(func):
    def data(*args,**kwargs):  # 使用不定长参数代替原函数中的参数
        import time
        print('正在计算中......')
        time.sleep(2)
        func(*args, **kwargs)
        print('计算完成')
    return data
​
@compute
def plus(a, b):
    print(a + b)
plus(1,10)
​
# 带返回值的装饰器
def compute1(func):
    def data1(*args,**kwargs):  # 使用不定长参数代替原函数中的参数
        import time
        print('正在计算中......')
        time.sleep(2)
        return func(*args, **kwargs) # 同样这里也要加上retrun返回值
    return data1
​
@compute1
def plus(a, b):
    return a + b
​
print('计算结果为:', plus(1, 10))

内置装饰器

"""
内置装饰器
property
classmethod
staticmethod
"""
class person:
    name = '小明'  # 成员变量
    def __init__(self,name,gender):
        self.name = name
        self.gender = gender
    @property  # 将方法变为只读,不再需要传参,直接使用访问属性的方法进行访问
    def eat(self):
        return f'{self.name}准备吃饭'
​
    @classmethod  # 将此方法变成类方法,默认参数从self变成cls,无需实例化就可访问内置的成员变量和该方法
    def sleep(cls):
        print(f'{cls.name}准备睡觉')
    @staticmethod  # @staticmethod 在定义方法时无需写入默认self参数
    def play():  # 不再自动传入参数
        print('打豆豆')
​
zs = person('张三','男')
zs.eat  # 使用 property 装饰器后,直接使用调用属性的方法进行调用,里面输出为属性的默认值 
​
person.sleep()  # @classmethod  直接使用类名调用方法,里面输出为属性的默认值 
​
zs.play()  # @staticmethod 在定义方法时无需写入默认self参数