python之面向对象
python编程分为三个阶段:
- 面向过程编程:根据业务逻辑从上到下垒
- 函数式编程:将某功能进行函数封装,使用时调用函数即可,减少代码重复量
- 面向对象编程:对函数进行分类和封装
理论上我们是比较鄙视面向过程编程的,那么问题来了,那函数式编程和面向对象编程我们该用哪个呢?
先来看两个的特点吧:
- 函数编程,逻辑清晰,简单,为项目而生,维护困难,函数式编程提倡的解决方案是数据是不可变的, 就没有了一直在改变的状态, 从而降低了复杂度.
- 面向对象,大而全,复杂,为大项目而生,开发周期长,理论上长久维护简单,实际上一塌糊涂...面向对象一个最大的特点是抽象, 所以面向对象式编程特别适合处理业务逻辑,因此被广泛应用于目前的软件开发当中.
总结
-
那么什么情况下用面向对象呢?当某一些函数具有相同参数时,可以使用面向对象的方式,将参数值一次性的封装到对象,以后去对象中取值即可,我觉得这个是对于我这种初学者的最简答案了吧...
-
什么时候使用函数式编程呢?各个函数之间是独立且无共用的数据
类和对象的创建
面向对象编程方式的落地,需要使用类和对象来实现:
- 类可以看为一个模板,模板了包含了多个函数,函数实现某些功能
- 对象是根据模板创建的实例,通过实例对象可以调用类中的功能函数
- class是关键词,声明创建一个类
- 类后面加(),表示创建对象
- 类中定义函数时,第一个参数必须为self,而类中的函数称为方法
面向对象的三大特性
- 封装
- 继承
- 多态
面向对象之封装
封装就是将内容封装到某个地方,以后再去调用被封装在某处的内容,在使用面向对象的封装特性时,需要:
- 将内容封装到某处
- 从某处调用被封装的内容
#!/usr/bin/env python #-*- coding:utf-8 -*- class Port: def __init__(self,total): """ __init__称之为构造方法 :param total: Port类传递的参数 """ self.total = total def num(self): print(self.total) obj = Port('123') obj.num()
面向对象之继承基础
继承,面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容。
#!/usr/bin/env python # _*_ coding:utf-8 _*_ class People: def __init__(self): print(""" 你的通用特征有:四肢、头发、眼、耳朵 """) class China(People): def info(self): print(""" 你是中国人,你的语言是中文,皮肤是黄色 """) class Us(People): def info(self): print(""" 你是美国人,你的语言是英文,皮肤是黑色 """) c = China() c.info() m = Us() m.info()
多继承
python中的继承可以多继承,意思就是一个子类可以有多个父类,比如:
class a(b,c,d,e): #b,c,d,e为类
def xxx(self):
pass
多继承中需要注意的是:
- 多继承时,按照继承的顺序排优先级c3(c2,c1)
深度优先,无共同父类,多继承方式
图待定……
面向对象中的类成员
- 字段
- 方法
- 属性
字段
字段分为两种:
- 普通字段
- 静态字段
普通字段我们使用的较多,一般是在构造方法时使用.
静态字段在代码加载时已经创建
字段 | 保存位置 | 规则 |
---|---|---|
普通字段 | 保存在对象中 | 只能用对象去访问 |
静态字段 | 保存在类中(节约内存空间) | 对象/类均可访问,但一般使用类访问,万不得已才使用对象访问) |
方法
所有方法都属于类,类基本可以分为三中类型:
- 普通方法
- 静态方法
- 类方法
方法 | 调用方式 | 特征 |
---|---|---|
普通方法 | 由对象去调用执行,属于类 | 至少一个self,对象调用 |
静态方法 | 属于类,但通过类来调用,不依赖于任何对象,方法内部不需要对象封装的值时,可使用静态方法 | 任意参数,没有self,上面添加@staticmethod,类似装饰器的东东 |
类方法 | 静态方法的一种特殊形式,由类调用 | 至少一个cls参数,上面添加classmethod |
静态方法:
class Province: country='中国' #静态字段 def __init__(self,name): self.name=name #普通字段 @staticmethod #静态方法 def show(arg1,arg2): print(arg1,arg2) print(Province.country) hn=Province('HN') print(hn.country) Province.show(123,456) #静态方法调用
属性
属性的特征:具有方法的写作形式,具有字段的访问形式.可取值,可设置,可删除.
先来看看属性是个什么东西吧:
class Pager: def __init__(self,all_count): self.all_count=all_count @property #定义属性 def all_pager(self): a1,a2=divmod(self.all_count,10) if a2==0: return a1 else: return a1+1 @all_pager.setter #赋值属性,将value赋值给方法的参数 def all_pager(self,value): print(value) @all_pager.deleter #删除属性 def all_pager(self): print('del all_pager') obj=Pager(101) ret=obj.all_pager #不需要加括号 print(ret) obj.all_pager=102 del obj.all_pager
属性的基本使用
属性的定义和调用需要注意以下几点:
- 定义时,在普通方法的基础上添加@property装饰器
- 定义时,属性仅有一个self参数
- 调用时,无需括号,obj.all_paper
属性存在的意义:访问属性时,可以制造出和访问字段完全相同的假象,由于属性是由方法变种而来,如果python中没有属性,完全可以由方法来替代.
属性的两种定义方式
python3中全都是新式类,有三种@property装饰方式:
- @property
- 方法名.setter
- 方法名.deleter
其实就像上面的例子.
还有一种方式是静态字段方式.创建值为property的对象的静态字段.
来看个例子:
class Pager: def __init__(self,name): self.name=name def f1(self): return 123 def f2(self,value): print(value) def f3(self): print('del....') foo=property(fget=f1,fset=f2,fdel=f3) obj=Pager(110) ret=obj.foo #调用fget print(ret) obj.foo=778 #调用fset del obj.foo #调用fdel
类方法
类方法通过@classmethod装饰器实现,类方法和普通方法的区别是, 类方法只能访问类变量,不能访问实例变量
class StudentManagement(object): @classmethod def register(cls, school, course): student = Student(school=school, course=course) return student @classmethod def pay(cls, student, money): money = student.payment(paymoney=money) return { 'student': student, 'paymoney': money } @classmethod def select_class(cls, student, class_): student.select_class_(class_=class_) return { 'course': class_.course.name, 'teacher': class_.teacher.name, }