一、类属性

1、实例属性

所属于具体的实例对象,不同实例对象之间的实例属性互不影响

2、类属性

所属于类对象,多个实例对象之间共享同一个类属性

类属性可以理解为在类之间定义了一个共享全局变量

1)获取类属性方法:类名.类属性

2)通过实例对象不能够修改类属性

面向对象(下)与异常处理 - 图1

例1:

  1. class Person:
  2. #类属性
  3. sum_num = 0
  4. def __init__(self,new_name):
  5. self.name = new_name
  6. #修改类属性值,每创建以个实例对象,类属性值加1
  7. Person.sum_num += 1
  8. p1 = Person("zhangsan")
  9. print(p1.sum_num,Person.sum_num)
  10. p2 = Person("lisi")
  11. print(p1.sum_num, p2.sum_num, Person.sum_num)

运行结果:

  1. 1 1
  2. 2 2 2

类属性可以用实例对象访问,也可以用类名来访问

例2:

  1. class Person:
  2. #类属性
  3. sum_num = 0
  4. def __init__(self,new_name):
  5. self.name = new_name
  6. p1 = Person("zhangsan")
  7. p2 = Person("lisi")
  8. # 通过实例对象不能够修改类属性值,如果修改的属性在实例中不存在,则动态添加实例属性
  9. p1.sum_num = 100
  10. print(p1.sum_num, p2.sum_num, Person.sum_num)

运行结果:

  1. 100 0 0

通过实例对象不能修改类属性,如果修改的属性在实例中不存在,则会动态的添加实例属性

Python是一个动态的编程语言

例3:

  1. class Person:
  2. #类属性
  3. sum_num = 0
  4. def __init__(self,new_name,new_num):
  5. self.name = new_name
  6. #定义一个与类属性同名的实例属性
  7. self.sum_num = new_num
  8. Person.sum_num += 1
  9. p1 = Person("zhangsan",10)
  10. print(p1.sum_num,Person.sum_num)

运行结果:

  1. 10 1

若实例属性与类属性同名时,实例对象只会调用实例属性,不会调用类属性

二、类方法

所属于类对象,使用@classmethod修饰的方法

定义类方法的第一个参数通常以“cls”参数作为类对象被传入

调用方式:

  1. 类名.类方法

或者

  1. 实例对象.类方法 #(不推荐这种方式)

例:

  1. class Person:
  2. #类属性
  3. sum_num = 0
  4. def __init__(self,new_name):
  5. self.name = new_name
  6. # 类方法
  7. @classmethod
  8. def add_sum_num(cls):
  9. cls.sum_num += 1
  10. print(cls.sum_num)
  11. #类方法调用
  12. #方法1:类名.类方法
  13. Person.add_sum_num()
  14. print("------------------------")
  15. #方法2:实例对象.类方法(不推荐)
  16. p = Person("zhangsan")
  17. p.add_sum_num()

运行结果:

  1. 1
  2. ------------------------
  3. 2

三、静态方法

使用@staticmethod修饰的方法,不需要默认传递任何参数

调用方式:

  1. 类名.静态方法

或者

  1. 实例对象.静态方法

例:

  1. class Person:
  2. sum_num = 0
  3. def __init__(self,new_name):
  4. self.name = new_name
  5. #静态方法
  6. @staticmethod
  7. def static_test():
  8. print("------静态方法------")
  9. Person.sum_num += 1
  10. print(Person.sum_num)
  11. #静态方法调用
  12. Person.static_test()
  13. print("------------------------")
  14. p = Person("zhangsan")
  15. p.static_test()

运行结果:

  1. ------静态方法------
  2. 1
  3. ------------------------
  4. ------静态方法------
  5. 2

四、单例类

1、new(cls)

超类object类内置的方法,用户创建对象,返回创建对象的引用

必须要提供cls参数,代表类对象

必须要有返回值,返回创建对象的引用

  1. class DataBaseObj(object):
  2. def __init__(self,new_name):#对象初始化
  3. print("---init构造方法----")
  4. self.name = new_name
  5. print(self.name)
  6. def __new__(cls,name):#创建对象
  7. print("cls_id:",id(cls))
  8. return object.__new__(cls)#必须有返回值,返回的是创建的对象的引用
  9. print(id(DataBaseObj))
  10. db = DataBaseObj("mysql")
  11. print(db)

运行结果:

  1. 36275480
  2. cls_id: 36275480
  3. ---init构造方法----
  4. mysql
  5. <__main__.DataBaseObj object at 0x0000000001DBBE48>

2、单例类

在整个程序系统中确保某一个类只有一个实例对象

  1. class SingleInstance:
  2. __instance = None
  3. def __init__(self):
  4. print("-----init-----")
  5. def __new__(cls):
  6. if cls.__instance == None:
  7. cls.__instance = object.__new__(cls)
  8. return cls.__instance
  9. s1 = SingleInstance()
  10. print(id(s1))
  11. s2 = SingleInstance()
  12. print(id(s2))

运行结果:

  1. -----init-----
  2. 31309272
  3. -----init-----
  4. 31309272

五、异常处理

1、捕获异常

  1. try
  2. 逻辑代码块
  3. except ExceptionType as err:
  4. 异常处理方法

例:

  1. try:
  2. open("test.txt", "r")
  3. except FileNotFoundError as err:
  4. print("捕获到了异常!文件不存在",err)
  5. print("哈哈哈哈哈")

运行结果:

  1. 捕获到了异常!文件不存在 [Errno 2] No such file or directory: 'test.txt'
  2. 哈哈哈哈哈

2、捕获多个异常

  1. try:
  2. 逻辑代码块
  3. except (ExceptionType1,ExceptionType2,...) as err:
  4. 异常处理方法

例:

  1. try:
  2. print(num)
  3. print("==============")
  4. open("test.txt", "r")
  5. except (FileNotFoundError,NameError) as err:
  6. print("捕获到了异常!",err)
  7. print("哈哈哈哈哈")

运行结果:

  1. 捕获到了异常! name 'num' is not defined
  2. 哈哈哈哈哈

按try里面的代码执行顺序捕获异常。

3、捕获所有可能发生的异常

  1. try:
  2. 逻辑代码块
  3. except (ExceptionType1,ExceptionType2,...) as err:
  4. 异常处理方法
  5. except ExceptionType as err:
  6. 异常处理方法

例:

  1. try:
  2. open("test.txt", "r")
  3. except NameError as err1:
  4. print("捕获到了异常!",err1)
  5. except Exception as err2:
  6. print("捕获所有可能的异常",err2)
  7. print("哈哈哈哈哈")

运行结果:

  1. 捕获所有可能的异常 [Errno 2] No such file or directory: 'test.txt'
  2. 哈哈哈哈哈

4、finally的用法

  1. try:
  2. 逻辑代码块
  3. except (ExceptionType1,ExceptionType2,...) as err:
  4. 异常处理方法
  5. except ExceptionType as err:
  6. 异常处理方法
  7. finally
  8. 无论是否有异常产生,都会执行这里的代码块

例:

  1. f = None
  2. try:
  3. f = open("test.txt","r")
  4. print("打印文件内容")
  5. except FileNotFoundError as error:
  6. print("捕获到了异常",error)
  7. finally:
  8. print("关闭文件")
  9. if f != None:
  10. print("正在关闭文件")
  11. f.close()

运行结果:

  1. 捕获到了异常 [Errno 2] No such file or directory: 'test.txt'
  2. 关闭文件

5、函数嵌套异常传递

  1. def test1():
  2. print("------test1-1--------")
  3. print(num) #打印一个不存在的变量
  4. print("------test1-2--------")
  5. def test2():
  6. try:
  7. print("------test2-1--------")
  8. test1()
  9. print("------test2-2--------")
  10. except Exception as error:
  11. print("捕获到异常",error)
  12. print("------test2-3--------")
  13. test2()

运行结果:

  1. ------test2-1--------
  2. ------test1-1--------
  3. 捕获到异常 name 'num' is not defined
  4. ------test2-3--------

try语句按照如下方式工作:

1)首先,执行try子句(在关键字try和关键字except之间的语句)

2)如果没有异常发生,忽略except子句,try子句执行后结束。

3)如果在执行try子句的过程中发生了异常,那么try子句余下的部分将被忽略。如果异常的类型和 except 之后的名称相符,那么对应的except子句将被执行。最后执行 try 语句之后的代码。

4)如果一个异常没有与任何的except匹配,那么这个异常将会传递给上层的try中。

六、包和模块

1)Python项目结构:
一个项目可以包含多个包,一个包可以包含多个模块,一个模块就是一个以.py结尾的文件,一个模块内可以定义变量、函数、类等

面向对象(下)与异常处理 - 图2

面向对象(下)与异常处理 - 图3

2)模块的名字:.py文件的名字

3)包下可以包含子包

4)不同包下可以有相同的模块名称,使用“包名.模块名”的方式区分

5)引入模块的方式

引入单个模块:import model_name

引入多个模块:import model_name1,model_name2,…

引入模块中的指定函数:from model_name import func1,func2,…

面向对象(下)与异常处理 - 图4

面向对象(下)与异常处理 - 图5

6)包中必须包含一个默认的init文件

用于标识一个包,而不是普通的文件夹

会在包或者该包下的模块被引入时自动调用

常用于设置包和模块的一些初始化操作