上手非常单,有过一定编E经验的人大U可以在几个时之内掌握基本的Python~程Ҏ?br />正好在学习设计模式课E,会有几次评作业Q就直接拿过来权当Python的一ơ编E练习了
W一ơQ务简介:
实现一个管理雇员薪水的工具Q可以打印出员工的薪水信息?br />雇员分ؓ普通和l理Q各自有不同的薪水计方法?br />
OkQLet's goQ?br />首先复习一下Python里的面向对象相关知识Q定义一个雇员的基类EmployeeBase
q且在__init__Ҏ里定义了三个成员name, base_salary和overtime_days
需要注意的是所有的cL员方法在声明的时候都需要有一个默认的参数selfQ这个相当于this指针的东西必要写上Q而且讉KcL员或者方法也都要加上q个前缀Q不然会出错?br />1 class EmployeeBase():
2 """Base class of all staffs"""
3 def __init__(self, name = "", basesalary = 0, overtime = 0):
4 self.name = name
5 self.base_salary = basesalary
6 self.overtime_days = overtime
7 def GetName(self):
8 return self.name
接下来就是普通雇员类EmployeeQ承的语法Q?span style="color: rgb(0, 0, 0);">Employee(EmployeeBase)
以及cȝ__doc__Q养成写注释的习惯?br /> Line 6Q?br />__init__q不是构造函敎ͼq且Python里也没有构造函数这个概c所以要手动的调用基cȝ__init__Ҏ
GetSalary中计薪_普通雇员的加班工资是双倍计的?br />
1 class Employee(EmployeeBase):
2 """Common employee class derived from EmployeeBase.
3 A employee can has overtime salary, every overtime work's salary will be doubled
4 """
5 def __init__(self, name="", basesalary=0, overtime=0):
6 EmployeeBase.__init__(self,name,basesalary,overtime)
7 def GetStaffType(self):
8 return "Employee"
9 def GetSalary(self):
10 return self.base_salary + self.base_salary/30*2*self.overtime_days
11 def GetSalaryInfo(self):
12 return self.name + " : " + self.GetStaffType()+ " : " + str(self.GetSalary())
到这里,雇员cdl完成,下面是—?b>单元试。一般我以前写程序都很少写单元测试的Q因为很ҎQ要写很多测试的代码?br />但是q里我想特别试一下,以展现Python里的各种Ҏ和工具?br />新版本的Python里有一个专门用于测试的unittest模块Q导入就可以使用了,下面新徏一个Testsalary.pyq行单元试?br />首先unittest模块里有一个测试用例的基类TestCaseQ我们只要在TestCase的派生类里定义自q试用例Ҏ可以用了Q这些测试用命方法甚至都不需要自p用,只要Ҏ名字以test开?/b>QTestCase׃自动的调用它们?br />在下面的试代码中,我定义了testNoneEmployee{几个测试方法,主要是用了TestCase里的assertEqualҎ?br />"""Unit test for salary.py"""
import unittest
from salary importEmployee
class TestEmployee(unittest.TestCase):
"""Unit test for clas Employee"""
def testNoneEmployee(self):
e = Employee()
self.assertEqual("",e.GetName())
self.assertEqual(0,e.GetSalary())
self.assertEqual("Employee",e.GetStaffType())
def testBaseSalary(self):
e = Employee("emp", 300)
self.assertEqual("emp",e.GetName())
self.assertEqual(300,e.GetSalary())
self.assertEqual("Employee",e.GetStaffType())
def testNoOvertime(self):
e = Employee("emp", 300, 0)
self.assertEqual(300,e.GetSalary())
self.assertEqual("emp : Employee : 300", e.GetSalaryInfo())
def testOvertime1(self):
e = Employee("emp", 300, 1)
self.assertEqual(320,e.GetSalary())
self.assertEqual("emp : Employee : 320", e.GetSalaryInfo())
def testOvertime2(self):
e = Employee("emp", 300, 5)
self.assertEqual(400,e.GetSalary())
self.assertEqual("emp : Employee : 400", e.GetSalaryInfo())
if __name__ == "__main__":
unittest.main()
q行之,出现l果Q?br />----------------------------------------------------------------------
Ran 5 tests in 0.007s
OK
全部通过Q太没意思了Q想着要加点什么好呢。下面我Ҏ造Employee的时候加上参数的查,不允怸正确的参数输入,例如名字太长Q工资和加班天数数等。我希望在试囄q些不正的参数q行创徏Employee对象的时候出现异常?br />在测试代码中加入另两个方法,使用了TestCase里的另一个方?b>assertRaisesQ这个方法可以检被对象是否按抛出了预期的异常。这个方法接受一个异常类型,和一个会产生q种异常的“对象”,通常是一个函敎ͼ以及它们的参?br /> def testInvalidName(self):
self.assertRaises(InvalidName, Employee, "name too long")
def testInvalidInput1(self):
self.assertRaises(InvalidInput, Employee, "emp", -300)
def testInvalidInput2(self):
self.assertRaises(InvalidInput, Employee, "emp", 300, -5)
两种异常cȝ名字分别叫InvalidName和InvalidInputQ这下测试通不q了。下面就需要修改Employeec,首先提一下Python里的异常处理Q用try...except...处理异常Qraise抛出异常Qfinally可以用来做一些善后处理工作?br />下面先要定义上面用到的这两种异常QInvalidName和InvalidInputQ这里简单的l承一下Python里的Exceptioncd可以了,然后修改Employee的__init__ҎQ进行参数的查检Q修正后如下Q?br />#new type of Expceptions
class InvalidName(Exception):pass
class InvalidInput(Exception):pass
#Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-
def __init__(self, name="", basesalary=0, overtime=0):
#raise exceptions if input is invalidate
if len(name) > 8:
raise InvalidName, "Error: Name too long!"
if basesalary < 0 or basesalary > 300000:
raise InvalidInput, "Error: Base salary should between 0~300000!"
#use int(overtime) != overtime to check if the input is int
if overtime < 0 or overtime > 31 or int(overtime) != overtime:
raise InvalidInput, "Error: Overtime should between 0~31!"
EmployeeBase.__init__(self,name,basesalary,overtime)
psQ异常类型后面的文字是ؓ了给Q异常处理提供信息用的?br />
OKQ第一步顺利完成,下面是l理cR经理的工资由加班工资和l效l成Q加班工资只跟经理的{有关Q它与W效工资都是一个固定|基本上没有什么难度?br />

]]>