面向对象-1
一、概述:
定义:
面向对象程序设计(英语:Object-oriented programming,缩写:OOP)是一种程序设计范型,同时也是一种程序开发的方法。对象指的是类的实例。
它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性。
面向对象程序设计可以看作一种在程序中包含各种独立而又互相调用的对象的思想,
这与传统的思想刚好相反:传统的程序设计主张将程序看作一系列函数的集合,或者直接就是一系列对电脑下达的指令。
面向对象程序设计中的每一个对象都应该能够接受数据、处理数据并将数据传达给其它对象,因此它们都可以被看作一个小型的“机器”,即对象。
1)面向过程的程序设计:核心是过程二字,过程指的是解决问题的步骤,是一种机械式的思维方式。
优点:
复杂度的问题流程化,进而简单化(一个复杂的问题,分成一个个小的步骤去实现,实现小的步骤将会非常简单)
缺点:
一套流水线或者流程就是用来解决一个问题,生产汽水的流水线无法生产汽车,即便是能,也得是大改,改一个组件,牵一发而动全身。
应用场景:
一旦完成基本很少改变的场景,著名的例子有Linux內核,git,以及Apache HTTP Server等。
2)面向对象的程序设计:
核心是对象二字,对象是特征与技能的结合体,与面向过程机械式的思维方式形成鲜明对比,面向对象更加注重对现实世界的模拟。
优点:
解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。
缺点:
1>编程的复杂度远高于面向过程,不了解面向对象而立即上手基于它设计程序,极容易出现过度设计的问题。
2.>无法向面向过程的程序设计流水线似的可以很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题。
应用场景:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等。
面向过程思想:
while 1:
if cpu利用率 > 90%:
#发送邮件提醒
连接邮箱服务器
发送邮件
关闭连接
if 硬盘使用空间 > 90%:
#发送邮件提醒
连接邮箱服务器
发送邮件
关闭连接
if 内存占用 > 80%:
#发送邮件提醒
连接邮箱服务器
发送邮件
关闭连接
面向对象思想:
def 发送邮件(内容)
#发送邮件提醒
连接邮箱服务器
发送邮件
关闭连接
while True:
if cpu利用率 > 90%:
发送邮件('CPU报警')
if 硬盘使用空间 > 90%:
发送邮件('硬盘报警')
if 内存占用 > 80%:
发送邮件('内存报警')
二、类和对象
面向对象编程是一种编程方式,此编程方式的落地需要使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” 的使用。
对象=属性+行为(方法)
把具有相同属性和方法的对象归为一类。类是对象的抽象化,对象是类的实例化。
类就是一个模板,模板里可以包含多个函数,函数里实现一些功能,对象则是根据模板创建的实例,通过实例对象可以执行类中的函数。
self指的是类实例对象本身(注意:不是类本身),在定义类的实例方法时必须写在第一个参数位置上,但在调用该实例方法时不必传入。
__init__()方法是在实例对象时自动执行的方法,叫构造方法;self.Name ,Addr, Type 都是实例对象的属性。
class Person:
def __init__(self, name ,age ,blood_type):
self.name = name
self.age = age
self.blood_type = blood_type
def detail(self):
temp = "i am %s, age %s , blood type %s " % (self.name, self.age, self.blood_type)
print temp
zhangsan = Person('tom', 18, 'A')
lisi = Person('jerry', 73, 'AB')
yangwu = Person('laowang', 84, 'A')
__init__方法:
#方式一、为对象初始化自己独有的特征
class People:
country='China'
x=1
def run(self):
print('----->', self)
# 实例化出三个空对象
obj1=People()
obj2=People()
obj3=People()
# 为对象定制自己独有的特征
obj1.name='jerry'
obj1.age=18
obj1.sex='male'
obj2.name='xxx'
obj2.age=38
obj2.sex='female'
obj3.name='tom'
obj3.age=38
obj3.sex='female'
# print(obj1.__dict__)
# print(obj2.__dict__)
# print(obj3.__dict__)
# print(People.__dict__)
#方式二、为对象初始化自己独有的特征
class People:
country='China'
x=1
def run(self):
print('----->', self)
# 实例化出三个空对象
obj1=People()
obj2=People()
obj3=People()
# 为对象定制自己独有的特征
def chu_shi_hua(obj, x, y, z):
obj.name = x
obj.age = y
obj.sex = z
chu_shi_hua(obj1,'jerry',18,'male')
chu_shi_hua(obj2,'xxx',38,'female')
chu_shi_hua(obj3,'tom',38,'female')
#方式三、为对象初始化自己独有的特征
class People:
country='China'
x=1
def chu_shi_hua(obj, x, y, z):
obj.name = x
obj.age = y
obj.sex = z
def run(self):
print('----->', self)
obj1=People()
# print(People.chu_shi_hua)
People.chu_shi_hua(obj1,'jerry',18,'male')
obj2=People()
People.chu_shi_hua(obj2,'xxx',38,'female')
obj3=People()
People.chu_shi_hua(obj3,'tom',38,'female')
# 方式四、为对象初始化自己独有的特征
class People:
country='China'
x=1
def __init__(obj, x, y, z):
obj.name = x
obj.age = y
obj.sex = z
def run(self):
print('----->', self)
obj1=People('jerry',18,'male')
obj2=People('xxx',38,'female')
obj3=People('tom',38,'female')
# __init__方法
# 强调:
# 1、该方法内可以有任意的python代码
# 2、一定不能有返回值
class People:
country='China'
x=1
def __init__(obj, name, age, sex):
# if type(name) is not str:
# raise TypeError('名字必须是字符串类型')
obj.name = name
obj.age = age
obj.sex = sex
def run(self):
print('----->', self)
# obj1=People('jerry',18,'male')
obj1=People(3537,18,'male')
# print(obj1.run)
# obj1.run() #People.run(obj1)
# print(People.run)
!!!__init__方法之为对象定制自己独有的特征
*****
#1、在没有学习类这个概念时,数据与功能是分离的
def exc1(host,port,db,charset):
conn=connect(host,port,db,charset)
conn.execute(sql)
return xxx
def exc2(host,port,db,charset,proc_name)
conn=connect(host,port,db,charset)
conn.call_proc(sql)
return xxx
#每次调用都需要重复传入一堆参数
exc1('127.0.0.1',3306,'db1','utf8','select * from tb1;')
exc2('127.0.0.1',3306,'db1','utf8','存储过程的名字')
#2、我们能想到的解决方法是,把这些变量都定义成全局变量
HOST=‘127.0.0.1’
PORT=3306
DB=‘db1’
CHARSET=‘utf8’
def exc1(host,port,db,charset):
conn=connect(host,port,db,charset)
conn.execute(sql)
return xxx
def exc2(host,port,db,charset,proc_name)
conn=connect(host,port,db,charset)
conn.call_proc(sql)
return xxx
exc1(HOST,PORT,DB,CHARSET,'select * from tb1;')
exc2(HOST,PORT,DB,CHARSET,'存储过程的名字')
#3、但是2的解决方法也是有问题的,按照2的思路,我们将会定义一大堆全局变量,这些全局变量并没有做任何区分,即能够被所有功能使用,然而事实上只有HOST,PORT,DB,CHARSET是给exc1和exc2这两个功能用的。言外之意:我们必须找出一种能够将数据与操作数据的方法组合到一起的解决方法,这就是我们说的类了
class MySQLHandler:
def __init__(self,host,port,db,charset='utf8'):
self.host=host
self.port=port
self.db=db
self.charset=charset
def exc1(self,sql):
conn=connect(self.host,self.port,self.db,self.charset)
res=conn.execute(sql)
return res
def exc2(self,sql):
conn=connect(self.host,self.port,self.db,self.charset)
res=conn.call_proc(sql)
return res
obj=MySQLHandler('127.0.0.1',3306,'db1')
obj.exc1('select * from tb1;')
obj.exc2('存储过程的名字')
#改进
class MySQLHandler:
def __init__(self,host,port,db,charset='utf8'):
self.host=host
self.port=port
self.db=db
self.charset=charset
self.conn=connect(self.host,self.port,self.db,self.charset)
def exc1(self,sql):
return self.conn.execute(sql)
def exc2(self,sql):
return self.conn.call_proc(sql)
obj=MySQLHandler('127.0.0.1',3306,'db1')
obj.exc1('select * from tb1;')
obj.exc2('存储过程的名字')
数据与专门操作该数据的功能组合到一起