Python面向对象编程
面向过程:根据业务逻辑从上到下写代码
面向对象:将数据与函数绑定到一起,进行封装,这样能够更快速的开发程序,减少了重复代码的重写过程
面向对象编程的2个非常重要的概念:类和对象
对象是面向对象编程的核心,在使用对象的过程中,为了将具有共同特征和行为的一组对象抽象定义,提出了另外一个新的概念——类
类就相当于制造飞机时的图纸,用它来进行创建的飞机就相当于对象
类(Class) 由3个部分构成:
类的名称:类名
类的属性:一组数据
类的方法:允许对进行操作的方法 (行为)
对象 = 属性 + 方法
13.2.创建对象
通过上一节课程,定义了一个Car类;就好比有车一个张图纸,那么接下来就应该把图纸交给生成工人们去生成了
python中,可以根据已经定义的类去创建出一个个对象
创建对象的格式为:
对象名 = 类名()
创建对象demo:
总结:
BMW = Car(),这样就产生了一个Car的实例对象,此时也可以通过实例对象BMW来访问属性或者方法
第一次使用BMW.color = '黑色'表示给BMW这个对象添加属性,如果后面再次出现BMW.color = xxx表示对属性进行修改
BMW是一个对象,它拥有属性(数据)和方法(函数)
当创建一个对象时,就是用一个模子,来制造一个实物
Python中创建实例属性
虽然可以通过Person类创建出xiaoming、xiaohong等实例,但是这些实例看上除了地址不同外,没有什么其他不同。在现实世界中,区分xiaoming、xiaohong要依靠他们各自的名字、性别、生日等属性。
Python中初始化实例属性
在定义 Person 类时,可以为Person类添加一个特殊的init()方法,当创建实例时,init()方法被自动调用,我们就能在此为每个实例都统一加上以下属性:
init()方法,在创建一个对象时默认被调用,不需要手动调用init(self)中,默认有1个参数名字为self,如果在创建对象时传递了2个实参,那么init(self)中出了self作为第一个形参外还需要2个形参,例如init(self,x,y)
init(self)中的self参数,不需要开发者传递,python解释器会自动把当前的对象引用传递进去
Python中访问限制
我们可以给一个实例绑定很多属性,如果有些属性不希望被外部访问到怎么办?
Python对属性权限的控制是通过属性名来实现的,如果一个属性由双下划线开头(__),该属性就无法被外部访问
classPerson(object):def__init__(self,name,score):self.name=nameself.__score=scorep=Person('Bob',59)print(p.name,p._score);
但是,如果一个属性以"xxx"的形式定义,那它又可以被外部访问了,以"xxx"定义的属性在Python的类中被称为特殊属性,有很多预定义的特殊属性可以使用,通常我们不要把普通属性用"xxx"定义。
python中定义实例方法
一个实例的私有属性就是以__开头的属性,无法被外部访问,那这些属性定义有什么用?
虽然私有属性无法从外部访问,但是,从类的内部是可以访问的。除了可以定义实例的属性外,还可以定义实例的方法。
实例的方法就是在类中定义的函数,它的第一个参数永远是 self,指向调用该方法的实例本身,其他参数和一个普通函数是完全一样的:
classPerson:def__init__(self,name,age):self.__name=nameself.age=agedefgetName(self):returnself.__name;person1=Person("张三",19)print(person1.getName())
13.7. python中创建类属性
类是模板,而实例则是根据类创建的对象。
绑定在一个实例上的属性不会影响其他实例,
但是,类本身也是一个对象,如果在类上绑定一个属性,则所有实例都可以访问类的属性,并且,所有实例访问的类属性都是同一个!
也就是说,实例属性每个实例各自拥有,互相独立,而类属性有且只有一份。
classPerson:#声明address地址address="earth"def__init__(self,name,age):self.name=nameself.age=ageperson1=Person('zhangsan',19)print(person1.address)#earthprint(Person.address)#earth
13.8. python中定义类方法
和属性类似,方法也分实例方法和类方法。
在class中定义的全部是实例方法,实例方法第一个参数 self 是实例本身。
Python中继承
继承概念
面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。
通过继承创建的新类称为子类或派生类,被继承的类称为基类、父类或超类。
为什么要继承
新类不必从头编写,代码的重用
新类从现有类继承,就自动拥有了现有类的所有功能
新类只需要编写现有类缺少的新功能
在程序中,继承描述的是事物之间的所属关系,例如猫和狗都属于动物.
继承特点以及单继承
子类在继承的时候,在定义类时,小括号()中为父类的名字
父类的属性、方法,会被继承给子类
类属性和对象属性
类属性就是类(类对象)所拥有的属性。它被类和所有对象所拥有。
对于共有类属性,在类外可以通过类对象和实例对象访问。
14.8.python中多态(了解)
类具有继承关系,并且子类类型可以向上转型看做父类类型,如果我们从 Person 派生出 Student和Teacher ,并都写了一个 whoAmI() 方法,在一个函数中,如果我们接收一个变量 x,则无论该 x 是 Person、Student还是 Teacher,都可以正确打印出结果:这种行为称为多态。
方法调用将作用在 x 的实际类型上。s 是Student类型,它实际上拥有自己的 whoAmI()方法以及从 Person继承的 whoAmI方法,但调用 s.whoAmI()总是先查找它自身的定义,如果没有定义,则顺着继承链向上查找,直到在某个父类中找到为止。
Python中异常
什么是异常?
异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。
一般情况下,在Python无法正常处理程序时就会发生一个异常。
异常是Python对象,表示一个错误。
当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。
#演示各种异常情况#第一个异常,数学异常# ZeroDivisionError: division by zero <
异常处理
捕捉异常可以使用try/except语句。
try/except语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理。
如果你不想在异常发生时结束你的程序,只需在try里捕获它。
try的工作原理是,当开始一个try语句后,python就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try子句先执行,接下来会发生什么依赖于执行时是否出现异常。
如果当try后的语句执行时发生异常,python就跳回到try并执行第一个匹配该异常的except子句,异常处理完毕,控制流就通过整个try语句(除非在处理异常时又引发新的异常)。
如果在try后的语句里发生了异常,却没有匹配的except子句,异常将被递交到上层的try,或者到程序的最上层(这样将结束程序,并打印缺省的出错信息)。
如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else的话),然后控制流通过整个try语句。
Try-finally 语句
try:i=1/0except:print("出现错误")else:print("一切正常")finally:print("无论如何都会执行")
主动触发异常
我们可以使用raise语句自己触发异常
raise语法格式如下
i=1;ifi<10:raiseException("数字i不能小于10")#异常触发后,后边代码就不会执行#抛出异常classPerson(object):def__init__(self,name,age):self.name=name self.__age=agedefsetAge(self,age):ifage<0orage>150:raiseException("年龄非法")else:self.__age=agedefgetAge(self):returnself.__agetry:p=Person("张三",18)p.setAge(190)exceptExceptionasresult:print(result)
Python单元测试
单元测试框架Unittest介绍
TestCase:一个测试用例,或是一个完整的测试流程,包括测试前准备环境的搭建(setUp),执行测试代码(run)以及测试后环境的还原(tearDown)。
单元测试(unittest)的本质也就在这里,一个测试用例是一个完整的测试单元,通过运行这个测试单元,可以对某一个问题进行验证。
TestSuite:多个测试用例TestCase集合在一起,就是TestSuite,而且TestSuite也可以嵌套TestSuite。
TestLoader:用来加载TestCase到TestSuite中的,其中有几个loadTestsFrom__()方法,就是从各个地方寻找TestCase,创建它们的实例,然后add到TestSuite中,再返回一个TestSuite实例。
TextTestRunner:是来执行测试用例的,其中的run(test)会执行TestSuite/TestCase中的run(result)方法。测试的结果会保存到TextTestResult实例中,包括运行了多少测试用例,成功了多少,失败了多少等信息。
整个流程:首先是要写好TestCase,然后由TestLoader加载TestCase到TestSuite,然后由TextTestRunner来运行TestSuite,运行的结果保存在TextTestResult中,整个过程集成在unittest.main模块中。
步骤:
导入unittest模块
当前测试类继承unittest.TestCase,相当于当前利用unittest创建了一个test case,这个test case是能够被unittest直接识别。
写setUP(),主要是打开浏览器和打开站点
写一个test_search()用例写搜索的代码
写tearDown(),主要是浏览器退出操作
unittest的简单介绍及使用
一个完整的测试脚本包含:
import unittest
定义一个继承自unittest.TestCase的测试用例类,相当于当前利用unittest创建了一个test case,这个test case是能够被unittest直接识别。
定义setUp和tearDown,在每个测试用例前后做一些辅助工作。
定义测试用例,名字以test开头。
一个测试用例应该只测试一个方面,测试目的和测试内容应很明确。主要是调用assertEqual、assertRaises等断言方法判断程序执行结果和预期值是否相符。
调用unittest.main()启动测试
如果测试未通过,会输出相应的错误提示。如果测试全部通过则不显示任何东西,也可以添加-v参数显示详细信息。
# -*- coding: utf-8 -*-importunittestclassPythonunitTest(unittest.TestCase):defsetUp(self):print("---测试初始化工作---")deftestF(self):i=1+1print(i)deftearDown(self):print("---测试扫尾工作----")if__name__=="__main__":unittest.main()
断言