抽象数据类型 ADT
- 概念:使用对象时,只考虑如何使用,不考虑具体的内部实现。
- 数据类型的操作:构造操作(基于已知信息,产生此类型的新对象),解析操作(从对象取得有用信息),变动操作(修改被操作对象的内部状态)。
- 在oop编程中,一切皆对象,对象归属于类。并且接口和实现分离,先定义类名和需要用到的形参作为接口。
- init:初始化方法,检查参数合法性,设置对象数据属性。 对象名=类名.属性名(形参):实例化。 _函数名:在类的内部使用。 __类:内部私有。 方法名:适用于算术运算符的特殊方法。
- 数据属性直接调用,方法属性需要用self表示调用对象的形参,一般作为第一个参数。
- 声明全局变量、函数:global 和 nonlocal。isinstance(obj,cls):检查对象是否为类的实例。
- @staticmethod:静态方法,就是普通函数,不需要self参数。 @classmethod:类方法,必须有一个表示其调用类的参数,习惯用cls作为参数名。(加在def前一行)
- 继承:class 子类(父类1,父类2···) 子类可以继承父类的属性和方法,也可以重写重载其方法。issubclass(cls1,cls2):检查1是否为2的子类。super().属性:从类的直接基类中查找属性。 虚函数:通过动态约束确定调用关系的函数。
异常
- class 异常类(异常类型) :定义异常接口。
- 异常需要捕捉,通过raise提取,捕捉过程也是先从本类开始,然后往基类延伸。
try:
# 尝试执行的代码
pass
except 错误类型1:
# 针对错误类型1,对应的代码处理
pass
except 错误类型2:
# 针对错误类型2,对应的代码处理
pass
except (错误类型3, 错误类型4):
# 针对错误类型3 和 4,对应的代码处理
pass
except Exception as result:
# 打印错误信息
print(result)
else:
# 没有异常才会执行的代码
pass
finally:
# 无论是否有异常,都会执行的代码
print("无论是否有异常,都会执行的代码")`
人事管理系统
import datetime
class PersonTypeError(TypeError):
pass
class PersonValueError(ValueError):
pass
class Person:
_num=0
def __init__(self,name,sex,birthday,ident):
if not(isinstance(name,str) and
sex in ("女","男")):
raise PersonValueError(name,sex)
try:
birth=datetime.date(*birthday) #生成一个日期对象
except:
raise PersonValueError("wrong date:",birthday)
self._name=name
self._sex=sex
self._birthday=birth
self._id=ident
Person._num += 1 #实例计数
def id(self):
return self._id
def name(self):
return self._name
def sex(self):
return self._sex
def birthday(self):
return self._birthday
def age(self):
return datetime.date.today().year - self._birthday.year
def set_name(self,name): #修改名字
if not isinstance(name,str):
raise PersonValueError("set name:",name)
self._name=name
def __lt__(self, other):
if not isinstance(other,Person):
raise PersonTypeError(other)
return self._id < other._id
@classmethod
def num(cls):
return Person._num
def __str__(self):
return " ".join((self._name,self._sex,
str(self._birthday),self._id))
def details(self):
return ",".join("姓名:"+self._name,
"性别:"+self._sex,
"出生日期:"+str(self._birthday),
"编号:" + self._id)
class Student(Person):
_id_num=0
@classmethod
def _id_gen(cls): #实现学号生成规则
cls._id_num+=1
year=datetime.date.today().year
return "1{:04}{:05}".format(year,cls._id_num)
def __init__(self,name,sex,birthday,department):
Person.__init__(self,name,sex,birthday,Student._id_gen())
self._department=department
self._enroll_date=datetime.date.today()
self._courses={ } #空字典
def set_courses(self,courses_name):
self._courses[courses_name]=None
def set_score(self,course_name,score):
if course_name not in self._courses:
raise PersonValueError("Not this course selected:"+course_name)
self._courses[course_name]=score
def scores(self):
return [(cname,self._courses[cname]) for cname in self._courses] #推导式,cname为键值对,元组内为规定格式输出
def details(self):
return ", ".join((Person.details(self),
"入学日期:"+str(self._enroll_date),
"院系:"+self._department,
"课程记录:"+str(self.scores)))
class Staff(Person):
_id_num=0
@classmethod
def _id_gen(cls,birthday): #实现职工号生成规则
cls._id_num+=1
birth_year=datetime.date(*birthday).year
return "0{:04}{:05}".format(birth_year,cls._id_num)
def __init__(self,name,sex,birthday,entry_date=None):
super().__init__(name,sex,birthday,Staff._id_gen(birthday))
if entry_date:
try:
self._entry_date=datetime.date(*entry_date)
except:
raise PersonValueError("wrong date:",entry_date)
else:
self._entry_date=datetime.date.today()
self._salary=1720 #默认为最低工资,可修改
self._department="未定" #需另行设定
self._position="未定" #需另行设定
def set_salary(self,amount):
if not type(amount) is int:
raise TypeError
self._salary=amount
def set_position(self,position):
self._position=position
def set_department(self,department):
self._department=department
def details(self):
return ", ".join(super().details(),
"入职日期:"+str(self._entry_date),
"院系:"+self._department,
"职位:"+self._position,
"工资:"+str(self._salary))
'''调试demo'''
p1=Staff("张子玉","女",(1974,2,12))
print(p1)