类与对象定义
面向过程与面向对象
面向过程编程:
根据操作数据的函数或语句块来设计程序的。
面向对象编程:
数据和功能结合起来,用称为对象的东西包裹起来组织程序的方法;
在大多数时候你可以使用面向过程编程,但是有些时候当需要编写大型程序或是寻求一个更加合适的解决方案的时候,就需要面向对象的编程,Python既可以提供面向过程的编程,也可以面向对象的编程,归根到底,Python语言是面向对象的编程语言。
类与对象示例
class Bird():
def __init__(self):
self.hungry = True
def eat(self):
if self.hungry:
print('Aaaah...')
self.hungry = False
else:
print('No,thanks!')
>>> b1=Bird()
>>> b1.eat ()
Aaaah...
>>> b1.eat ()
No,thanks!
>>> b1.eat ()
No,thanks!
>>> b1.hungry
False
>>> b1.hungry
False
类和对象是面向对象编程的两个主要方面,类创建一个新类型,而对象是这个类的实例 。这类似于上面一个类Bird(),而b1是类Bird的一个实例,也就是类的一个对象(实例)。
类的组成元素:
关键字(类): class
类的名字: Bird
构造函数: __init__(self)
类的方法: eat(self) (b1.eat())
类的特性: hungry (b1.hungry)
class Class_Name(SuperClass,…):
class_variable = value
def __init__(self, argv):
statement
def class_func(self, argv):
statement
关键字(类):class
类的名字: Class_name
构造函数: __init__(self,argv)
类的方法: class_func(self, argv)
类的特性: class_variable
class_object_1 = Class_Name()
class_object_2 = Class_Name()
class_object_1.class_variable
class_object_2.class_variable
class_object_1.class_func(argv)
class_object_2.class_func(argv)
对象定义: class_object_1 = Class_Name()
对象特性: class_object_1.class_variable
对象方法: class_object_1.class_func(argv)
类与对象特性
类与对象特性
对象可以使用普通的属于对象的变量存储数据,属于一个对象或类的变量被称为特性;对象也可以使用属于类的函数具有的功能;这样的函数被称为类的方法。这些术语帮助我们把它们与孤立的函数和变量区分开来;特性和方法可以合称为类的属性。
特性有两种类型:属于每个实例/类的对象或者属于类本身,它们分别被称为实例变量和类变量。
类使用class关键字创建,类的特性和方法被列在一个缩进块中。
与类和对象的名称空间绑定的普通变量,即这些名称只在这些类与对象的前提下有效。
类名.类变量(使用对象名.类变量也可访问);
对象名.对象变量。
命名空间定义的位置:
类特性:紧跟在类定义之后;
对象特性:在__init__中使用self.xxx=定义。
例子:
class var():
value = 1
>>> instance1=var()
>>>var.value
>>>instance1.value
类与对象方法
类的方法与普通的函数只有一个特别的区别:类的方法必须有一个额外的第一个参数名称self,但是在调用这个方法的时候你不必为这个参数赋值,Python会提供这个值,这个特别的变量指的是对象本身,按照惯例它的名称就是在类定义中常见的 self 这个变量名。
可以是任意一个变量名,但最好遵循通用的规则;
Self 这个变量名具有一定的魔法,在具体的对象中它有特定的意义。
Self参数的工作原理:假如你有一个类称为MyClass和这个类的一个实例MyObject。当你调用这个对象的方法MyObject.method(arg1, arg2)的时候,这会由Python自动转为MyClass.method (MyObject, arg1, arg2),这就是 self 的使用原理。
如果你有一个不需要参数的方法,你还是得给这个方法定义一个带有 self 参数。
类与对象方法的使用:调用方法同普通函数一致,忽略self参数。
对象名.方法名(参数…)
class Bird:
def __init__(self):
self.hungry = True
def eat(self):
if self.hungry:
print('Aaaah...')
self.hungry = False
else:
print('No,thanks!')
>>> b=Bird()
>>> b.hungry
True
>>> b.eat()
Aaaah...
>>> b.eat()
No,thanks!
>>> b.eat()
No,thanks!
类与对象:(
__init__构造函数;
__del__析构函数;
__len__,__getitem__,__setitem__, __delitem__这是系列映射规则;……
__privatename 私有类的变量名;
@decorators 装饰器;
__iter__迭代器;
……
类与对象多态
Polymorphism:术语多态来自于希腊语,多态意味着就算不知道变量所引用的对象类型是什么,还是能对它进行操作,而且它也能根据(或者类)对象的类型的不同而表现出不同的行为。
class var():
value = 1
>>>instamce1=var()
>>>var.value =‘Python ’
>>>instance1.value =55
def add1(x,y):
return x+y
>>>x=1,y=23
>>>x=“spam”,y=‘Python ’
>>>add1(x,y)
类与对象封装
Encapsulation:封装是对外部隐藏对象内部细节的原则,看起来有点象多态,但封装并不等于多态;多态可以让用户对于不知道是什么类或者对象类型的对象进行方法调用;而封装是可以不用关心对象是如何构建的而直接进行使用。
class var():
value = 1
>>> instance1=var()
>>> instance2=var()
>>> instance1.value=‘Python ’
>>> instance2.value=55
类与对象继承
Inheritance:以普通类为基础建立专门的类对象;如果已经有一个基类,想再建立一个新类,新类中要添加几种新方法,而又要用原来基类的一些方法,这个时候新类就要继承基类的方法,而又有新的方法,这就是继承;继承的方法就是在新类定义中添加一个基类作为参数。
class SongBird(Bird):
def __init__(self):
self.sound = ‘Squawk’
def sing(self):
print(self.sound)
类的构造函数
类的构造函数的形式为:
def __init__(self):
superclass.__init__(self) #未绑定超类
super(subclass, self).__init__( ) #调用super( )
statement
类的构造函数与其它普通方法不同的地方在于,当一个对象被创建后,会立即调用构造方法,就有点类似于程序中的 init 的初始化方法。
如果要继承构造方法,可以调用未绑定的超类构造方法,也可以用super函数调用超类构造函数。
类的构造函数继承
class Bird:
def __init__(self):
self.hungry = True
def eat(self):
if self.hungry:
print('Aaaah...')
self.hungry = False
else:
print('No,thanks!')
class SongBird(Bird):
def __init__(self):
super(SongBird, self).__init__( )
self.sound = ‘Squawk’
def sing(self):
print(self.sound)
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实例中,包括运行了多少测试用例,成功了多少,失败了多少等信息。
Test Fixture:
对一个测试用例环境的搭建和销毁,通过覆盖TestCase的setUp()和tearDown()方法来实现。
这个有什么用呢?比如说在这个测试用例中需要访问数据库,那么可以在setUp()中建立数据库连接以及进行一些初始化,在tearDown()中清除在数据库中产生的数据,然后关闭连接。注意tearDown的过程很重要,要为以后的TestCase留下一个干净的环境。
整个流程:首先是要写好TestCase,然后由TestLoader加载TestCase到TestSuite,然后由TextTestRunner来运行TestSuite,
运行的结果保存在TextTestResult中,整个过程集成在unittest.main模块中。
一个完整的测试脚本包含:
1.import unittest
2.定义一个继承自unittest.TestCase的测试用例类
3.定义setUp和tearDown,在每个测试用例前后做一些辅助工作。
4.定义测试用例,名字以test开头。
5.一个测试用例应该只测试一个方面,测试目的和测试内容应很明确。主要是调用assertEqual、assertRaises等断言方法判断程序执行结果和预期值是否相符。
6.调用unittest.main()启动测试
7.如果测试未通过,会输出相应的错误提示。如果测试全部通过则不显示任何东西,也可以添加-v参数显示详细信息。
介绍以下unittest的基本用法。
第1种用法(以下代码是官方文档的sample)。
import unittest
class TestSequenceFunctions(unittest.TestCase):
def setUp(self):
self.seq = range(10)
def test_choice(self):
element = random.choice(self.seq)
self.assertTrue(element in self.seq)
def test_sample(self):
with self.assertRaises(ValueError):
random.sample(self.seq, 20)
for element in random.sample(self.seq, 5):
self.assertTrue(element in self.seq)
def setDown(self):
pass
if __name__ == '__main__':
unittest.main()
1.从unittest.TestCase继承一个子类。
2.定义测试方法,以test开头。
3.调用unittest.main(),这个方法会自动执行所有以test开头的测试方法。
第2种调用方法:自己创建一个TestSuite,添加需要执行测试的TestCase,然后使用TestRunner().run(suite)执行测试。
if __name__ == '__main__':
suite = unittest.TestSuite()
suite.addTest(TestSequenceFunctions('test_choice')
suite.addTest(TestSequenceFunctions('test_sample')
unittest.TextTestRunner().run(suite)
测试主要是调用assertEqual、assertRaises等断言方法判断程序执行结果和预期值是否相符。
常见的断言方法有:
方法 | Checkse | 备注 |
assertEqual(a,b) | a==bp | 测试的二个值是相等,如果不相等,测试失败 |
assertNotEqual(a,b) | a!=be | 测试的二个值不相等,如果比较结果相等,测试失败 |
assertTure(x) | Bool(x) is Truer | 期望的结果是Truee |
assertFalse(x) | Bool(x) is Falser | 期望的结果是 Falser |
assertls(a,b) | a is be | |
assertlsNot(a,b) | a is not be | |
assertln(a,b) | a in be | |
assertNotin(a,b) | a not in be | |
Fail() | 无条件的失败。 |
拓展-测试报告的生成
#导入测试报告生成的模块
import HTMLTestRunner
suite = unittest.TestSuite()
# 定义生成测试报告的名称 filename1=r". result\" + str(time.strftime('%Y%m%d%H%M%S')) + ".html" fp = file(filename1,'wb')
# 定义测试报告的路径,标题,描述等内容 runner=HTMLTestRunner.HTMLTestRunner(stream=fp,title=u'自动化测试报告',description=u'自动化测试报告')
#执行测试脚本,并生成测试报告 runner.run(suite)
报告的内容:
拓展-数据驱动(文本、表格等)
文本: 例子: 作用是获取data_file文本中内容,存放在列表中,作为输入。
data_file的内容:
姓名 性别 年龄
张三 男 20
李四 男 24
……
def datatouch(i): source = open ("./data_file.txt", "r") values = source.readlines() word=values[i].split() return word
Data_1= datatouch(1)
Test_value1= str(Data_1[0])
数据驱动:从某个数据文件(例如文本、 Excel 文件、CSV 文件、数据库等)中读取输入、输出的测试数据,然后通过变量传入事先录制好的或手工编写的测试脚本中。
常用操作:
导入模块
import xlrd
打开Excel文件读取数据
data=xlrd.open_workbook('excelFile.xls')
获取一个工作表
table = data.sheets()[0] #通过索引顺序获取
table = data.sheet_by_index(0) #通过索引顺序获取
table = data.sheet_by_name(u'Sheet1')#通过名称
获取整行和整列的值(数组)
table.row_values(i)
table.col_values(i)
获取行数和列数
nrows = table.nrows
ncols = table.ncols
获取单元格
cell_A1 = table.cell(0,0).value
cell_C4 = table.cell(2,3).value
例子:
import xlrd
data =xlrd.open_workbook('companylist.xlsx')
table = data.sheets()[0]
table_value1= str(table.cell(1,0).value)