概述:
上一节主要介绍了面向对象的一些基本概念:类,类的组成元素“方法和属性”,类的特性“继承,多态和封装”。这一节课分为三部分:
(一)类属性、类方法及调用、静态方法及调用和单例类
(二)异常处理
(三)包和模块
第一部分:类方法、静态方法和单例类
类属性
(1)类属性区别于实例的属性,类属性属于类对象,被实例对象所共享
(2)查找属性规则:先实例对象的实例属性;后类对象的类(?)属性
(3)通过实例对象不能修改类属性的值;如果修改的属性在实例中不存在,则动态添加实例属性
class Person:
sum_num = 0
def __init__(self):
Person.sum_num += 1 #修改类属性值,每创建一个实例对象,类属性值加1
#实例对象p1和类对象的类属性值一致
p1 = Person("zhangsan")
print(p1.sum_num, Person.sum_num)
#通过实例对象不能修改类属性值,如果修改的属性在实例总不存在,则动态添加实例属性
p1.sum_num = 100
print(p1.sum_num, Person.sum_num)
类方法及调用
(1)使用@classmethod修饰的方法,第一个参数是cls
(2)类方法操作类属性;实例方法操作实例对象属性
(3)调用方式:类名.类方法();实例对象.类方法() #不推荐用此方法调用类方法
class Date(object):
def __init__(self, day=0, month=0, year=0):
self.day = day
self.month = month
self.year = year
#类方法
@classmethod
def from_string(cls, date_as_string):
day, month, year = map(int, date_as_string.split('-'))
date1 = cls(day, month, year)
return date1
静态方法及调用
(1)使用@staticmethod修饰的方法,不需要传入任何参数
(2)应用在跟类和对象没有关系的一些功能上。尽量少用静态方法。
#静态方法
@staticmethod
def is_date_valid(date_as_string):
day, month, year = map(int, date_as_string.split('-'))
return day <= 31 and month <= 12 and year <= 3999
单例类
(1)new(cls)是超类object类内置的方法。参数cls是类对象
(2)用户创建对象,返回创建对象的引用。
#通过id(cls)可以查看类对象以及实例对象的地址
class DataBaseObj(object):
def __init__(self): #对象初始化
print("-------init 构造函数-------")
def __new__(cls): #构造对象
print("cls_id:" id(cls))
return object.__new__(cls) #返回对象的引用
(2)在整个程序系统中,只有一个实例对象。概念等同设计模式中的singleton模式。
class SingleInstance:
__instance = None
def __init__(self):
print("-----init-----")
def __new__(cls):
if cls.__instance == None:
cls.__instance = object.__new__(cls)
return cls.__instance
s1 = SingleInstance()
print(id(s1))
s2 = SingleInstance()
print(id(s2))
第二部分:异常处理
(1)捕获异常
try:
逻辑代码
except ExceptionType as err:
异常处理
(2)捕获多个异常
try:
逻辑代码
except (ExceptionType1, ExceptionType2, ...) as err:
异常处理
(3)捕获所有可能发生的异常
try:
逻辑代码
except Exception as err:
异常处理
(4)finally
try:
逻辑代码
except Exception as err:
异常处理
finally:
代码块 (无论是否有异常发生,代码都会执行到这里)
(4)异常处理的意义:
- 防止某个业务产生异常而影响到整个程序中的其他业务
- 异常处理的本质不是解决异常,而是将出现异常时的不良影响降到最低
第三部分:包和模块
Python项目结构:
(1)1个项目:n个包
(2)一个包:n个模块
(3)模块的名字:以.py为扩展名命名的文件
引入模块的方法:
(1)导入一个模块:import model_name 或者 import module_name.model_name
(2)导入多个模块:import model_name1, model_name2, ...
(3)导入某个模块中的函数:from model_name import fun1, fun2
import model_name Vs from model_name import fun
(1)前者是导入一模块,如果想引用模块的内容(class, method,variables...)必须用全名,即 [module_name].[attr_name]。
(2)后者是导入某一指定对象(class, 其它对象...), 然后就可以直接用这些对象,不需要加上[module_name], 即[attr_name]。
特别用法:
(1)如果你只想导入一个包里面的某个模块被其他包所使用,你可以在init.py文件里添加一句:all = ["model_name"]
(2)批量导入:from package import *;(1)对(2)起约束作用。