成员和异常

二十 成员和异常

20.1 成员

成员:类中 属性和方法

20.1 类属性和实例属性

class Dog:
    # 类属性是直接写的,不用特定写到某个方法中
    count = 0  # 记录当前类,已经被创建多少次
    type_set = set() # 记录所有狗的种类


    def __init__(self, name, age, master,type):
        # 实例属性
        self.name = name 
        self.age = age
        self.master = master
        self.type = type
        Dog.count += 1 # 每增加一狗,加一
        Dog.type_set.add(type)


dog1 = Dog("小红",5,'翠果','哈士奇')

print(Dog.count)
dog2 = Dog('小黑',1,'清越','金毛')
print(Dog.count)


print(dog1.count)
print(dog2.count)

dog3 = Dog('小白',1,'晶晶','金毛')
print(dog3.count)
print(dog1.count)
print(dog2.count)


print(dog3.type_set)
dog3 = Dog('小白',1,'晶晶','萨摩耶')
print(dog1.type_set)

区别总结

  1. 定义位置
    • 实例属性:在 __init__ 方法中使用self.xxx 定义
    • 类:直接在类体内定义,不需要self关键字
  2. 作用范围
    • 实例属性:每个实例自己独立的区间,实例之间不共享
    • 类属性:所有的实例都可以访问,都共享这个变量,它是存储在类中。修改一个类属性,其他的实例都会受到影响
  3. 使用场景
    • 实例属性:适用于需要在每个实例中存储不同数据的情况
    • 类属性:适用于需要在所有实例中共享数据的情况

20.2 实例方法

  • 这种方法是带self为参数的方法,主要也是区分每个对象的功能
class A:
    # 类属性
    count = 0


    # init方法中定义实例属性
    def __init__(self,name):
        self.name = name

    # 实例方法: 第一个参数是self
    def speak(self):
        print(f"my name is {self.name}")


a = A('彬彬')
# a.speak()   本质上是  A.speak(a)

20.3 类方法

类方法特点和 类属性是意义。

定义类方法需要在方法头部上使用一个 内置装饰器

  • @classmethod

类方法和普通方法的区别

  • 类方法中只能访问类属性,不能访问实例属性

    class A:
        # 类属性
        count = 0
    
        # init方法中定义实例属性
        def __init__(self, name):
            self.name = name
    
        # 实例方法: 第一个参数是self
        def speak(self):
            print(f"my name is {self.name}")
    
        @classmethod
        def add_count(cls):
            cls.count +=1
        @classmethod
        def clear(cls):
            cls.count = 0  # 修改类属性
    
    
    
    print(A.count)
    A.add_count()
    A.add_count()
    A.add_count()
    A.add_count()
    print(A.count)
    A.clear()
    print(A.count)
    
  • 注意语法区别

    • 第一个参数不同
      • 实例方法:self 表示对象区间
      • 类方法:cls 表示类
  • 类方法,对象和类都可以直接访问

class A:
    # 类属性
    count = 0

    # init方法中定义实例属性
    def __init__(self, name):
        self.name = name

    # 实例方法: 第一个参数是self
    def speak(self):
        print(f"my name is {self.name}")

    @classmethod
    def add_count(cls):
        cls.count +=1
    @classmethod
    def clear(cls):
        cls.count = 0  # 修改类属性



print(A.count)
A.add_count()
A.add_count()
A.add_count()
A.add_count()
print(A.count)
A.clear()
print(A.count)

bb = A(name="Bob")
bb.clear()
bb.add_count()
print(bb.count)

20.4 静态方法


# 工具类, 就是存储和数学相关的功能而已
class Math:
    @staticmethod
    def sin():
        print("求正玄")
    @staticmethod
    def cos():
        print('求余玄')

    @staticmethod
    def pow(a,b):
        # 求a的b次方
        print(a**b)

静态方法总结

  • 静态方法本质上和类没多大关系,只是一个管理模式。严格意义上可以不算方法,就是一个函数也行

  • 既不能访问类中的属性,也不能访问对象的属性

  • 更多只是作为一个工具来使用

20.5 魔法方法(特殊方法)

长相(外貌): 双下划线开头和结尾的方法。 比如 __init__

魔法方法主要从object来,这种方法一般情况是不需要自己去用的,都是在特殊情况被调用

20.5.1 基本的
__str__(self)
	默认情况下直接打印对象,打印的是一串地址
	- 作用:返回对象的字符串表示, 在print()str()函数中起作用
    - 调用时机:printstr
    
class Dog:
    def __init__(self,name,age,master):
        self.name = name
        self.age = age
        self.master =master

    def __str__(self):
        return f"名字和年龄 : {self.name}  {self.age}  主人是 {self.master}"
dog1 = Dog("大王",1,'不凡')
print(dog1)

__len__(self)
	- 作用:返回对象长度
    - 调用时机:len()

class Dog:
    count = 0

    def __init__(self,name,age,master):
        self.name = name
        self.age = age
        self.master =master
        Dog.count += 1

    def __str__(self):
        return f"名字和年龄 : {self.name}  {self.age}  主人是 {self.master}"

    def __len__(self):
        return Dog.count


dog1 = Dog("大王",1,'不凡')
dog1 = Dog("大王",1,'不凡')
dog1 = Dog("大王",1,'不凡')

# 求狗的数量
print(len(dog1))

20.5.2 比较的

这些魔法方法,都是在运算符中生效

方法名说明
__add__加法
__sub__减法
__mul__乘法
__truediv__除法
__floodiv__地板除
__mod__求余
__pow__
__iadd__+=
__isub__-=
__imul__*=
__itruediv__/=
__ifloodiv__//=
__imod__%=
__ipow__**=
__lt__小于
__le__小于等于
__gt__大于
__ge__大于等于
__eq__等于
__ne__不等于

比较方法特点

# 等于操作
def __eq__(self,ohter): #other表示被比较的对象
    return 布尔值
# class Dog:
#     count = 0
#
#     def __init__(self,name,age,master):
#         self.name = name
#         self.age = age
#         self.master =master
#         Dog.count += 1
#
#     def __str__(self):
#         return f"名字和年龄 : {self.name}  {self.age}  主人是 {self.master}"
#
#     def __len__(self):
#         return Dog.count



# 日期类

class Date:
    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day


    # 等于
    def __eq__(self,other):
        # self 表示比较对象,other 表示被比较对象
        return self.year == other.year and self.month == other.month and self.day == other.day

    # 大于号操作
    def __gt__(self,other):
        # self>other
        return self.year > other.year
        

x = Date(2025,12,30)
y = Date(2024,12,31)

# 默认比的是否是同一个对象
print(x==y)
print(x>y)


print(x== y)

20.2 异常

异常:程序运行中一些不可避免的错误

  • 使用未定义的变量
  • 超出序列下标使用
  • 除以0

20.2.1 捕获异常结构

语法

try:
    代码块(可能出错的语句)
except:
    代码块(出错后的处理方式)
else:
    代码块(没出错的时候才执行的语句)

结构类似于分支结构




print("异常发生之前的代码")
try:
    # 可能出错的代码块
    print(a)
    b = 10
except:
    # 只有出错了,才会执行
    print('出错了,哈哈')
else:
    # 必须要try走完,才有用的代码
    print(b)
print("异常发生之后的代码")



20.2.2 异常对象

  • 我们在python中遇到的所有error,都是异常

  • 实际上这些异常也是对象,都统一来源于Exception

  • NameError 名称错误异常

  • ZeroDivisionError 除0错误

  • IndexError 索引错误, 超出下标了

在Python中一切皆对象,包括异常也是对象

只要类继承了Excetion,就是一个异常类

对专门的异常进行捕获


try:
    print(a)
# 指定异常类型进行捕获
except ZeroDivisionError:
    print('处理nameerror')
except NameError:
    print('nameError')
... 可以去多个指定 抓门的异常对象来做专门的处理

捕获一切异常

try:
    print(a)
# 啥异常都能捕获
except Exception:
    print('处理nameerror')

Exception能不能看错误


a = [1,2]


try:
    print(a[5])
# 啥异常都能捕获
except Exception as e:
    print(e)
  1. 捕获所有
  2. 捕获指定
    • 一个一个写,更好排查
  • 最终结点
try:
    代码块(可能出错的语句)
except:
    代码块(出错后的处理方式)
else:
    代码块(没出错的时候才执行的语句)
finally:
    代码块(无论是否出现异常,都会执行)

20.2.3 raise

语法

raise 异常对象
  • 为什么要用raise设置异常提示

    1.维护性强
    

20.2.4 自定义异常

可以去继承Exception,做一些异常扩展


class my_erroy(Exception):
    pass

20.2.5 assert断言

assert 一种调试工具,基于某种 布尔值 来进行报错

用于在程序中检查某个条件是否为真,如果条件为假,assert会引发一个AssertionError

raise 简洁版


assert 条件表达式,错误提示语句

用处

  • 调试用途

    • 接口输入验证
  • 提前报错,避免副作用

    开发产品只要2个阶段
    
    1.开发调式阶段
    	敲代码,实现需求。 
        
        特点:代码频繁变动,需求不断修改和完善
        
    
    
    2.生产阶段
    	重点:提供稳定服务,确保可靠性和性能
        真实的场景,面对的高并发,处理实际用户的操作
        
    
        
    assert更适合的 开发调试阶段,简洁捕捉,但是提供的错误信息简单
    raise更适合 生产阶段
    目的都是为了 让程序崩溃,避免因为错误而导致一些副作用
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值