﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-Sunshine Alike-随笔分类-Python</title><link>http://www.cppblog.com/sunshinealike/category/13419.html</link><description>半完美主义</description><language>zh-cn</language><lastBuildDate>Sat, 03 Jul 2010 06:15:16 GMT</lastBuildDate><pubDate>Sat, 03 Jul 2010 06:15:16 GMT</pubDate><ttl>60</ttl><item><title>Python编程练习一：StaffSalaryApp</title><link>http://www.cppblog.com/sunshinealike/archive/2010/04/23/113343.html</link><dc:creator>Sunshine Alike</dc:creator><author>Sunshine Alike</author><pubDate>Fri, 23 Apr 2010 08:30:00 GMT</pubDate><guid>http://www.cppblog.com/sunshinealike/archive/2010/04/23/113343.html</guid><wfw:comment>http://www.cppblog.com/sunshinealike/comments/113343.html</wfw:comment><comments>http://www.cppblog.com/sunshinealike/archive/2010/04/23/113343.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunshinealike/comments/commentRss/113343.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunshinealike/services/trackbacks/113343.html</trackback:ping><description><![CDATA[学习了一些Python的基础知识之后，就开始来实践吧。<br />上手非常简单，有过一定编程经验的人大约可以在几个小时之内掌握基本的Python编程方法。<br />正好在学习设计模式课程，会有几次课程作业，就直接拿过来权当Python的一次编程练习了<br />第一次任务简介：<br />实现一个管理雇员薪水的工具，可以打印出员工的薪水信息。<br />雇员分为普通和经理，各自有不同的薪水计算方法。<br /><br />Ok，Let's go！<br />首先复习一下Python里的面向对象相关知识，定义一个雇员的基类EmployeeBase<br />并且在__init__方法里定义了三个成员name, base_salary和overtime_days<br />需要注意的就是所有的类成员方法在声明的时候都需要有一个默认的参数self，这个相当于this指针的东西必须要写上，而且访问类成员或者方法也都要加上这个前缀，不然会出错。<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 128, 128);">1</span> <span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> EmployeeBase():<br /></span><span style="color: rgb(0, 128, 128);">2</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(128, 0, 0);">"""</span><span style="color: rgb(128, 0, 0);">Base class of all staffs</span><span style="color: rgb(128, 0, 0);">"""</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">3</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">__init__</span><span style="color: rgb(0, 0, 0);">(self, name </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">, basesalary </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> 0, overtime </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> 0):<br /></span><span style="color: rgb(0, 128, 128);">4</span> <span style="color: rgb(0, 0, 0);">        self.name </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> name<br /></span><span style="color: rgb(0, 128, 128);">5</span> <span style="color: rgb(0, 0, 0);">        self.base_salary </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> basesalary<br /></span><span style="color: rgb(0, 128, 128);">6</span> <span style="color: rgb(0, 0, 0);">        self.overtime_days </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> overtime<br /></span><span style="color: rgb(0, 128, 128);">7</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> GetName(self):<br /></span><span style="color: rgb(0, 128, 128);">8</span> <span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> self.name</span></div><br />接下来就是普通雇员类Employee，继承的语法：<span style="color: rgb(0, 0, 0);">Employee(EmployeeBase)<br />以及类的__doc__，养成写注释的习惯。<br /></span><b><span style="color: rgb(0, 0, 0);"> Line 6：<br /></span></b><span style="color: rgb(0, 0, 0);">__init__并不是构造函数，并且Python里也没有构造函数这个概念。所以要手动的调用基类的__init__方法</span><b><span style="color: rgb(0, 0, 0);"></span></b><br />GetSalary中计算薪水，普通雇员的加班工资是双倍计算的。<br /><span style="color: rgb(0, 0, 0);"><br /></span><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 128, 128);"> 1</span> <span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> Employee(EmployeeBase):<br /></span><span style="color: rgb(0, 128, 128);"> 2</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(128, 0, 0);">"""</span><span style="color: rgb(128, 0, 0);">Common employee class derived from EmployeeBase.<br /></span><span style="color: rgb(0, 128, 128);"> 3</span> <span style="color: rgb(128, 0, 0);">    A employee can has overtime salary, every overtime work's salary will be doubled<br /></span><span style="color: rgb(0, 128, 128);"> 4</span> <span style="color: rgb(128, 0, 0);">    </span><span style="color: rgb(128, 0, 0);">"""</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 5</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">__init__</span><span style="color: rgb(0, 0, 0);">(self, name</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(128, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">, basesalary</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">0, overtime</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">0):<br /></span><span style="color: rgb(0, 128, 128);"> 6</span> <span style="color: rgb(0, 0, 0);">        EmployeeBase.</span><span style="color: rgb(128, 0, 128);">__init__</span><span style="color: rgb(0, 0, 0);">(self,name,basesalary,overtime)<br /></span><span style="color: rgb(0, 128, 128);"> 7</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> GetStaffType(self):<br /></span><span style="color: rgb(0, 128, 128);"> 8</span> <span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">Employee</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 9</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> GetSalary(self):<br /></span><span style="color: rgb(0, 128, 128);">10</span> <span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> self.base_salary </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> self.base_salary</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">30</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">self.overtime_days<br /></span><span style="color: rgb(0, 128, 128);">11</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> GetSalaryInfo(self):<br /></span><span style="color: rgb(0, 128, 128);">12</span> <span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> self.name </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);"> : </span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> self.GetStaffType()</span><span style="color: rgb(0, 128, 128);"></span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);"> : </span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> str(self.GetSalary())</span></div><br />到这里，雇员类已经完成，下面就是——<b>单元测试</b>。一般我以前写程序都很少写单元测试的，因为很费时，要写很多测试的代码。<br />但是这里我想特别尝试一下，以展现Python里的各种特性和工具。<br />新版本的Python里有一个专门用于测试的unittest模块，导入就可以使用了，下面新建一个Testsalary.py进行单元测试。<br />首先unittest模块里有一个测试用例的基类<b>TestCase</b>，我们只要在TestCase的派生类里定义自己的测试用例方法就可以使用了，这些测试用命方法甚至都不需要自己调用，只要方法<b>名字以test开头</b>，TestCase就会自动的调用它们。<br />在下面的测试代码中，我定义了testNoneEmployee等几个测试方法，主要是使用了TestCase里的<b>assertEqual</b>方法。<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(128, 0, 0);">"""</span><span style="color: rgb(128, 0, 0);">Unit test for salary.py</span><span style="color: rgb(128, 0, 0);">"""</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> unittest<br /></span><span style="color: rgb(0, 0, 255);">from</span><span style="color: rgb(0, 0, 0);"> salary </span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 0);">Employee<br /><br /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> TestEmployee(unittest.TestCase):<br />    </span><span style="color: rgb(128, 0, 0);">"""</span><span style="color: rgb(128, 0, 0);">Unit test for clas Employee</span><span style="color: rgb(128, 0, 0);">"""</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> testNoneEmployee(self):<br />        e </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Employee()<br />        self.assertEqual(</span><span style="color: rgb(128, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">,e.GetName())<br />        self.assertEqual(0,e.GetSalary())<br />        self.assertEqual(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">Employee</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,e.GetStaffType())<br />    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> testBaseSalary(self):<br />        e </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Employee(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">emp</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">300</span><span style="color: rgb(0, 0, 0);">)<br />        self.assertEqual(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">emp</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,e.GetName())<br />        self.assertEqual(</span><span style="color: rgb(0, 0, 0);">300</span><span style="color: rgb(0, 0, 0);">,e.GetSalary())<br />        self.assertEqual(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">Employee</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,e.GetStaffType())<br />    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> testNoOvertime(self):<br />        e </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Employee(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">emp</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">300</span><span style="color: rgb(0, 0, 0);">, 0)<br />        self.assertEqual(</span><span style="color: rgb(0, 0, 0);">300</span><span style="color: rgb(0, 0, 0);">,e.GetSalary())<br />        self.assertEqual(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">emp : Employee : 300</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, e.GetSalaryInfo())<br />    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> testOvertime1(self):<br />        e </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Employee(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">emp</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">300</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">)<br />        self.assertEqual(</span><span style="color: rgb(0, 0, 0);">320</span><span style="color: rgb(0, 0, 0);">,e.GetSalary())<br />        self.assertEqual(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">emp : Employee : 320</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, e.GetSalaryInfo())<br />    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> testOvertime2(self):<br />        e </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Employee(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">emp</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">300</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">)<br />        self.assertEqual(</span><span style="color: rgb(0, 0, 0);">400</span><span style="color: rgb(0, 0, 0);">,e.GetSalary())<br />        self.assertEqual(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">emp : Employee : 400</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, e.GetSalaryInfo())<br />        <br /></span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">__name__</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">__main__</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:<br />    unittest.main()</span></div>运行之，出现结果：<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">----------------------------------------------------------------------</span><span style="color: rgb(0, 0, 0);"><br />Ran </span><span style="color: rgb(0, 0, 0);">5</span><span style="color: rgb(0, 0, 0);"> tests </span><span style="color: rgb(0, 0, 255);">in</span><span style="color: rgb(0, 0, 0);"> 0.007s<br /><br />OK</span></div>全部通过，太没意思了，想着要加点什么好呢。下面我对构造Employee的时候加上参数的检查，不允许不正确的参数输入，例如名字太长，工资和加班天数为负数等。我希望在试图用这些不正确的参数进行创建Employee对象的时候出现异常。<br />在测试代码中加入另两个方法，使用了TestCase里的另一个方法<b>assertRaises</b>，这个方法可以检测被测对象是否按抛出了预期的异常。这个方法接受一个异常类型，和一个会产生这种异常的“对象”，通常是一个函数，以及它们的参数<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> testInvalidName(self):<br />        self.assertRaises(InvalidName, Employee, </span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">name too long</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">)<br />    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> testInvalidInput1(self):<br />        self.assertRaises(InvalidInput, Employee, </span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">emp</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">300</span><span style="color: rgb(0, 0, 0);">)<br />    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> testInvalidInput2(self):<br />        self.assertRaises(InvalidInput, Employee, </span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">emp</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">300</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">)</span></div>两种异常类的名字分别叫InvalidName和InvalidInput，这下测试通不过了。下面就需要修改Employee类，首先提一下Python里的异常处理，使用try...except...处理异常，raise抛出异常，finally可以用来做一些善后处理工作。<br />下面先要定义上面用到的这两种异常，InvalidName和InvalidInput，这里简单的继承一下Python里的Exception类就可以了，然后修改Employee的__init__方法，进行参数的查检，修正后如下：<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);">new type of Expceptions</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> InvalidName(Exception):</span><span style="color: rgb(0, 0, 255);">pass</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> InvalidInput(Exception):</span><span style="color: rgb(0, 0, 255);">pass</span><span style="color: rgb(0, 0, 0);"><br /><br /><br /></span><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);">－－－－－－－－－－－－－－－－－－－－－－</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"><br /><br />    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">__init__</span><span style="color: rgb(0, 0, 0);">(self, name</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(128, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">, basesalary</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">0, overtime</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">0):<br />        </span><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);">raise exceptions if input is invalidate</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> len(name) </span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">8</span><span style="color: rgb(0, 0, 0);">:<br />            </span><span style="color: rgb(0, 0, 255);">raise</span><span style="color: rgb(0, 0, 0);"> InvalidName, </span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">Error: Name too long!</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> basesalary </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);"> 0 </span><span style="color: rgb(0, 0, 255);">or</span><span style="color: rgb(0, 0, 0);"> basesalary </span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">300000</span><span style="color: rgb(0, 0, 0);">:<br />            </span><span style="color: rgb(0, 0, 255);">raise</span><span style="color: rgb(0, 0, 0);"> InvalidInput, </span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">Error: Base salary should between 0~300000!</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);">use int(overtime) != overtime to check if the input is int</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> overtime </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);"> 0 </span><span style="color: rgb(0, 0, 255);">or</span><span style="color: rgb(0, 0, 0);"> overtime  </span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">31</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">or</span><span style="color: rgb(0, 0, 0);"> int(overtime) </span><span style="color: rgb(0, 0, 0);">!=</span><span style="color: rgb(0, 0, 0);"> overtime:<br />            </span><span style="color: rgb(0, 0, 255);">raise</span><span style="color: rgb(0, 0, 0);"> InvalidInput, </span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">Error: Overtime should between 0~31!</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br />        EmployeeBase.</span><span style="color: rgb(128, 0, 128);">__init__</span><span style="color: rgb(0, 0, 0);">(self,name,basesalary,overtime)</span></div>ps：异常类型后面的文字是为了给，异常处理提供信息用的。<br /><br />OK，第一步顺利完成，下面就是经理类。经理的工资由加班工资和绩效组成，加班工资只跟经理的等级有关，它与绩效工资都是一个固定值，基本上没有什么难度。<br /><br /><br /><br /><br /><br /><img src ="http://www.cppblog.com/sunshinealike/aggbug/113343.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunshinealike/" target="_blank">Sunshine Alike</a> 2010-04-23 16:30 <a href="http://www.cppblog.com/sunshinealike/archive/2010/04/23/113343.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Python！Python！！</title><link>http://www.cppblog.com/sunshinealike/archive/2010/03/30/111060.html</link><dc:creator>Sunshine Alike</dc:creator><author>Sunshine Alike</author><pubDate>Tue, 30 Mar 2010 14:34:00 GMT</pubDate><guid>http://www.cppblog.com/sunshinealike/archive/2010/03/30/111060.html</guid><wfw:comment>http://www.cppblog.com/sunshinealike/comments/111060.html</wfw:comment><comments>http://www.cppblog.com/sunshinealike/archive/2010/03/30/111060.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunshinealike/comments/commentRss/111060.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunshinealike/services/trackbacks/111060.html</trackback:ping><description><![CDATA[突然一时兴起找了个Python的Tutorial看了一下下，哈哈，感觉非常好，很小巧很讨喜的语言，比较有特点。第一印象是很简单，语法简洁而又功能强大，准备要尝试学一下。<br /><br />下面贴一点学习的笔记：<br /><br /><font size="5">一、基本知识</font><br />Python同时即是脚本解释器，又是一个可以运行命令行的shell。在shell里可以计算任务Python表达式，甚至包括变量赋值，这些变量在shell打开时一直有效，关闭时丢失数据。<br /><br />函数声明，以def开始，函数名，参数，冒号后面跟函数体。需要注意的是Python里的格式都以缩进的形式来表达，没有类C/C++中的大括号。另外函数
不需要指定返回值类型，实际上，如果函数有return语句，它将返回指定类型值，否则返回None（Python的空值）。<br /><br />Python即是动态语言，它<b>不需要显示数据类型声明</b>，赋值的同时即完成变量声明。又是强类型语言，一个变量一旦获得一个数据类型，它实际上就一直是这个类型的了。<br /><br />Python里的“对象”概念，这里的“对象”不同于以前接触到的OO里的对象，Python里的对象定义更为广泛。一个程序块，一个变量，甚至一个字符串都可以是一个对象。其具体含义还需要根据上下文来判断。<br /><br /><b>三种重要的内置数据类型：Dictionary，List，Tuple：</b><br /><b>Dictionary</b>对应于C++中的map和Java中的hashtable，也就是一个键值对集合。<br /><b>List</b>对应于C++中的vector和java中的ArrayList，一个可以动态自动扩展的数组。<br /><b>Tuple</b>是一个不可变的list，一旦创建就不能以方式改变它，但是好在Python提供了在Tuple和List之间相互转换的函数。<br />需要注意的是List和Tuple是可以存储混合类型的数组的，并且都可以通过索引取值（包括负的索引值，其表示从逆序取值）<br /><b><br />For语句：</b><br />Python里的for语句不同于C/C++中的for，更类似于C#中的<code>foreach</code>循环或者是Java中的<code>for (int i : IntArray)</code>。Python的for语句需要配合一个range函数使用，它有三个参数，并返回一个Tupe数组用于表示索引，三个参数是start,stop,step，例如range（0，5，1）则返回[0，1，2，3，4]；range（5，0，－1）则返回[5，4，3，2，1]。<br /><br /><b>字符串格式化：</b><br />与C中类似%d，%f，%s等等，通过字符串的join函数可以方便的将list的内容合并成字符串。<br /><br /><b>and/or：</b><br />and和or负责执行布尔逻辑运算，但是它们不返回布尔值而是返回它们实际进行比较的值之一。非空的对象被认为是真，空对象则被认为是假。<b>and运算会返回第一个假值，而or运算返回第一个真值，其它部分都不会被计算到</b>。<br /><br /><b>lambda函数：</b><br />一种快速定义的单行最小函数，只有一行，类似于内联的感觉。例如一个例子：<br />ld = lambda i : i*i<br />ld(10) # == 100<br />理论上lambda函数可以有多个参数（包括可选参数）并且隐含的返回单个表达式的值。<br /><p class="programlisting"><b>两种导入（import）方法：</b></p><p class="programlisting">Python中有两种导入模块的方法： import xx / from xx import yy<br /></p>
它们的差别在于，from xx import
yy这种方式，yy被直接导入到了局部命名空间中（<b>类似于C++中的using</b>），在以后使用yy的时候不再需要（<b>不能</b>）加上模块名称限定。也就是说，如果使用import方式导入模块，在使用
它里面的一个变量的时候，你不得不每次都加上前缀xx.来表示使用的是位于xx模块中的变量，而使用from导入时，则不需要加入前缀。<br /><br /><b>异常处理：</b><br />Python中使用<b>try...except</b>来处理异常，使用<b>raise</b>来引发异常。并且，一个except后面可以跟一个else块来表示没有捕获预期异常时的行为。一个try块后面也可以跟一个<b>finally</b>块来保证一些代码总是被执行到，比如打开文件后的关闭操作。<br /><br /><b>注释：<br /></b>Python里使用<b>#</b>来作为单选注释开始符，使用三个冒号作为多行注释"""content"""，<br />需要注意的是后一种形式的注意经常被用来作为函数或者类的"说明",写在这里的内容可以被其使用者当作参考手册来使用，Ptyhon里所有对象都具有一个内置的<b>__doc__属性</b>，通过它可以查看各个对象的说明，应该养成写__doc__的习惯。一般其格式为<b>首行以大写字母开始，句号结尾。第二行是空行，从第三行开始是详细的描述</b>。<br /><br /><b>引号：<br /></b>Python里有单引号，双引号和三引号。其中<b>单引号和双引号都可以用来表示字符串</b>，例如<br />print 'string' == "string" 将会打印出True<br />设置这两种字符串引号的目的是为了简化引号的表示，例如如果字符串里含有引号本身就需要<b>使用\来进行标识</b>，例如：'let\'s go!'，“he said:\"get out!\"”。<br />如果字符串里含有大量这种情况会显得非常麻烦，可以交替使用单引号和双引号来避免这种情况。上面的例子可以改为："let's go!"，'he said:"get out!"'。<br />而三引号就是用来表示一个多行字符串。它们经常被用来定义<b>文档字符串</b>，它的首行以大写字母开始，句号结尾。第二行是空行，从第三行开始是详细的描述。建议从一开始就遵守这个惯例。<br /><br /><p class="programlisting"><font size="5">二、面向对象</font></p><b>类的定义：</b><br />以class开头，pass表示结束（实际上没有特定的u），例如一个简单的类定义为<br />class Person:<br />    pass<br />如果要表示继承关系只需要将基类用括号回到类名后面即可，Python支持多重继续，每个基类中间以逗号隔开。<br />class Student（Person）：<br />  pass<br />这里的pass语句仅表示占位之用，没有特别的含义。<br /><br /><b>类成员定义：</b><br /><b>__init__</b>方法，这个函数的功能很类似于Java或者C++中的构造函数，但是仍存在一点细小的差别，__init__函数的第一个参数一定是self，类似于C++中的this指针。<br />__init__方法的定义并<b>不是必须的</b>，但是一旦你定义了它，就<b>必须显示的</b>调用父类的__init__方法。<br />需要注意的是，所有的类成员方法都必须定义一个<b>参数（self）</b>，<b>但它的名字不是一定的</b>，其作用类似于C++中的<b>this</b>指针。<br /><b>__del__方法</b>，类似于析构函数，在使用del语句的时候被调用。<br /><br /><b>重载：</b><br />Python的类<b>没有任何形式的函数重载</b>，即一个方法名称只能对应一个方法，如果子类中定义的与基类中同名的方法，则会将其覆盖掉。<br /><br /><b>成员属性：</b><br />Python中有两种类型的成员方法：<b>普通类方法和专用类方法</b>。<br />成员也有两种访问级别：<b>公开的和私有的</b>。<br />其中公开和私有成员的表示没有特别的关键字，只是体现的方法名称上，私有成员的名称以两个短小的下划线作为开始例如：<br />class A:<br />  __privatevalue<br />  publicvalue<br />  def __set(self, v):<br />    __privatevalue = v<br />  def get(self):<br />    return publicvalue<br />  pass<br />并且，一个成员是属于类的还是属于对象的，是通过定义这个变量的域来确定的，定义在类体内的变量由所有成员共享，通过self定义的变量则为成员变量。<br />此外，类的成员方法还分为：<b>普通类方法和专用类方法</b>。普通方法的定义与普通函数定义类似，它是公开的，在类外部可以被调用。而类的<b>专用方法</b>，没有特殊的关键字来表示，只是在方法的名称前后各加上两个短的下划线，例如def __getitem__。这种专用方法是由用户显式调用的，它有点<b>操作符重载</b>的意思在里面，但是功能比操作符重载要强大一些。Python允许我们自己定义需要的类专用方法，例如任何定义了__cmp__方法的类就可以用＝＝进行比较，任何定义了__len__方法的类就可以用len(instance)进行取长度。<br /><br /><font size="5">三、标准库<br /><b><font size="4">1.文件操作</font></b><br /></font>Python中有一个内置函数open可以用来打开文件<br />file = open("pictures/dog.bmp","rb")<br />open函数可以接受三个参数：<b>文件名，模式和缓冲区参数</b>，但是只有每一个参数是必须的，文件会默认以文本方式打开。<br />文件的读取和C中类似，tell()返回当前文件位置，seek来移动文件操作的位置。具体的函数使用方法可以使用print seek.__doc__来查看<br /><br />处理I/O错误：<br />try:<br />  file = open(filename, "rb", 0)<br />  try:<br />    file.seek(-128,2)<br />    data = file.read(128)<br />    file.seek(0,2)<br />    file.write("succeeded")<br />    finally:<br />      file.close()<br />  expect IOError:<br />    pass<br /><br />Python提供了一个os.path模块来进行目录操作，具体使用方法就不详细写出来了，用过几次就记住了。<br /><br /><b><font size="4">2.序列化</font></b><br />标准库里有两个模块都提供这个功能，<b>pickle</b>和<b>cPickle</b>，用于将对象存储到文件中而后再读取出来。<br />但是后者是使用C语言写的，速度要比前面的快很多，但是功能都是一样的。<br />使用也很简便主要就是使用dump和load函数<br /><br />－－－－－－－－－－－－－－－－－－待续－－－－－－－－－－－－－－－－<br /><br /><br /><img src ="http://www.cppblog.com/sunshinealike/aggbug/111060.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunshinealike/" target="_blank">Sunshine Alike</a> 2010-03-30 22:34 <a href="http://www.cppblog.com/sunshinealike/archive/2010/03/30/111060.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>