Python 函数式编程和面向对象编程
函数式编程
函数:function。
函数式:functional,一种编程范式。函数式编程是一种抽象计算机的编程模式。
函数!= 函数式(如计算!=计算机)
如下是不同语言的抽象 层次不同
- 高阶函数
能接收函数做参数的函数:
1.变量可以指向函数
2.函数的参数可以接收变量
3.一个函数可以接收另一个函数作为参数
例子
接收abs函数,定义一个函数,接收x,y,z三个参数。其中x,y是数值,z是函数 。
def add(x,y,z):
return z(x)+z(y)
print add(-2,-3,abs)
其他高阶函数:map()函数、reduce()函数、filter()函数。
PS:Python的函数不但可以返回int、str、list、dict等数据类型,还可以返回函数!
闭包
像这种内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数的情况,称为闭包(Closure)。
特点是返回的函数还引用了外层函数的局部变量,所以,要正确使用闭包,就要确保引用的局部变量在函数返回后不能变。举例如下:
# 希望一次返回3个函数,分别计算1x1,2x2,3x3:
def count():
fs = []
for i in range(1, 4):
def f():
return i*i
fs.append(f)
return fs
f1, f2, f3 = count()
你可能认为调用f1(),f2()和f3()结果应该是1,4,9,但实际结果全部都是 9(请自己动手验证)。
原因就是当count()函数返回了3个函数时,这3个函数所引用的变量 i 的值已经变成了3。由于f1、f2、f3并没有被调用,所以,此时他们并未计算 i*i,当 f1 被调用时:
>>> f1() 9 # 因为f1现在才计算i*i,但现在i的值已经变为3
因此,返回函数不要引用任何循环变量,或者后续会发生变化的变量。
匿名函数(lambda )
>>> map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]) [1, 4, 9, 16, 25, 36, 49, 64, 81]
通过对比可以看出,匿名函数lambda x: x * x 实际上就是:
def f(x):
return x * x
关键字lambda 表示匿名函数,冒号前面的 x 表示函数参数(匿名函数有个限制,就是只能有一个表达式,不写return,返回值就是该表达式的结果,返回函数的时候,也可以返回匿名函数。)
装饰器 decorator
Python 的 decorator 本质上就是一个高阶函数,它接收一个函数作为参数,然后,返回一个新函数。
使用 decorator 用 Python 提供的 @ 语法,这样可以避免手动编写 f = decorate(f) 这样的代码,极大简化Python代码。
模块
导入系统自带的模块 math:
import math
如果我们只希望导入用到的 math 模块的某几个函数,而不是所有函数,可以用下面的语句:
from math import pow, sin, log
如果遇到名字冲突怎么办?
如果使用 import 导入模块名,由于必须通过模块名引用函数名,因此不存在冲突;
如果使用from...import 导入log函数,势必引起冲突。这时,可以给函数起个“别名”来避免冲突:
from math import log from logging import log as logger # logging的log现在变成了logger print log(10) # 调用的是math的log logger(10, 'import from logging') # 调用的是logging的log
动态导入模块
下面代码先尝试从cStringIO导入,如果失败了(比如cStringIO没有被安装),再尝试从StringIO导入。
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
利用import ... as ...,还可以动态导入不同名称的模块
try:
import json
except ImportError:
import simplejson as json
PS:
- Python的新版本会引入新的功能,但是实际上这些功能在上一个老版本中就已经存在了。要“试用”某一新的特性,就可以通过导入
__future__模块的某些功能来实现。 - 如何区分包和普通目录:包下面有个
__init__.py每层都有。
面向对象编程
定义类并创建实例
定义一个Person类如下
class Person(object):
pass
(object),表示该类是从哪个类继承下来的。
创建实例
xiaoming = Person()
如何让每个实例拥有各自不同的属性?
由于Python是动态语言,对每一个实例,都可以直接给他们的属性赋值,例如,给xiaoming这个实例加上name、gender和birth属性:
xiaoming = Person() xiaoming.name = 'Xiao Ming' xiaoming.gender = 'Male' xiaoming.birth = '1990-1-1'
给xiaohong加上的属性不一定要和xiaoming相同:
xiaohong = Person() xiaohong.name = 'Xiao Hong' xiaohong.school = 'No. 1 High School' xiaohong.grade = 2
`实例的属性可以像普通变量一样进行操作:
xiaohong.grade = xiaohong.grade + 1
初始化实例属性
class Person(object):
def __init__(self, name, gender, birth):
self.name = name
self.gender = gender
self.birth = birth
__init__()方法的第一个参数必须是 self(也可以用别的名字,但建议使用习惯用法)。后续参数则可以自由指定,和定义函数没有任何区别。
相应地,创建实例时,就必须要提供除 self 以外的参数:
xiaoming = Person('Xiao Ming', 'Male', '1991-1-1')
xiaohong = Person('Xiao Hong', 'Female', '1992-2-2')
定义实例方法
class Person(object):
def __init__(self, name):
self.__name = name
def get_name(self): #它的第一个参数永远是 self,指向调用该方法的实例本身
return self.__name
定义类方法(类似Java的静态方法)
class Person(object):
count = 0
@classmethod
def how_many(cls): #类方法
return cls.count
def __init__(self, name):
self.name = name
Person.count = Person.count + 1
print Person.how_many()
p1 = Person('Bob')
print Person.how_many()
访问限制
如果一个属性由双下划线开头(__),该属性就无法被外部访问(相当于private)。但是,如果一个属性以"__xxx__"的形式定义,那它又可以被外部访问了,以"__xxx__"定义的属性在 Python 的类中被称为特殊属性,有很多预定义的特殊属性可以使用,通常我们不要把普通属性用"__xxx__"定义。
- 题目
请定义Person类的__init__方法,除了接受 name、gender 和 birth外,还可接受任意关键字参数,并把他们都作为属性赋值给实例。
要定义关键字参数,使用**kw;
除了可以直接使用self.name = 'xxx'设置一个属性外,还可以通过 setattr(self, 'name', 'xxx')设置属性。
- 参考代码:
class Person(object):
def __init__(self, name, gender, birth, **kw):
self.name = name
self.gender = gender
self.birth = birth
for k, v in kw.iteritems():
setattr(self, k, v)
xiaoming = Person('Xiao Ming', 'Male', '1990-1-1', job='Student')
print xiaoming.name
print xiaoming.job
类的继承
继承一个类
class Person(object):
def __init__(self, name, gender):
self.name = name
self.gender = gender
定义 Student 类时,只需要把额外的属性加上,例如score:
class Student(Person):
def __init__(self, name, gender, score):
super(Student, self).__init__(name, gender)
self.score = score
一定要用super(Student, self).__init__(name, gender)去初始化父类,否则,继承自Person的Student将没有name 和 gender。函数super(Student, self)将返回当前类继承的父类,即 Person,然后调用__init__()方法,注意self参数已在super()中传入,在__init__()中将隐式传递,不需要写出(也不能写)
判断类型
函数isinstance()可以判断一个变量的类型
>>> isinstance(p, Person)
获取对象信息
除了用isinstance()判断它是否是某种类型的实例外,type() 函数获取变量的类型,它返回一个 Type 对象。可以用dir()函数获取变量的所有属性: dir(s)。
Python 函数式编程和面向对象编程的更多相关文章
- python笔记 - day7-1 之面向对象编程
python笔记 - day7-1 之面向对象编程 什么时候用面向对象: 多个函数的参数相同: 当某一些函数具有相同参数时,可以使用面向对象的方式,将参数值一次性的封装到对象,以后去对象中取值即可: ...
- angular2系列教程(六)两种pipe:函数式编程与面向对象编程
今天,我们要讲的是angualr2的pipe这个知识点. 例子
- 大数据技术之_16_Scala学习_04_函数式编程-基础+面向对象编程-基础
第五章 函数式编程-基础5.1 函数式编程内容说明5.1.1 函数式编程内容5.1.2 函数式编程授课顺序5.2 函数式编程介绍5.2.1 几个概念的说明5.2.2 方法.函数.函数式编程和面向对象编 ...
- Python进阶 函数式编程和面向对象编程等
函数式编程 函数:function 函数式:functional,一种编程范式.函数式编程是一种抽象计算机的编程模式. 函数!= 函数式(如计算!=计算机) 如下是不同语言的抽象 层次不同 高阶函数: ...
- 浅谈Python中函数式编程、面向对象编程以及古怪的PythonIC
1.函数式编程作为结构化编程的一种,正在受到越来越多的重视.那么什么事函数式编程呢? 在维基百科中给出了详细的定义,函数式编程又称泛函数编程,是一种编程规范,它将函数运算视为数学上的函数计算.简单的来 ...
- python 学习笔记7 面向对象编程
一.概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发"更快更好更强..." ...
- python学习笔记(七):面向对象编程、类
一.面向对象编程 面向对象--Object Oriented Programming,简称oop,是一种程序设计思想.在说面向对象之前,先说一下什么是编程范式,编程范式你按照什么方式来去编程,去实现一 ...
- 洗礼灵魂,修炼python(31)--面向对象编程(1)—面向对象,对象,类的了解
面向对象 1.什么是面向对象 (图片来自网络) 哈哈,当然不是图中的意思. 1).面向对象(Object Oriented,OO)是软件开发方法.利用各大搜索引擎得到的解释都太官方,完全看不懂啥意思对 ...
- 洗礼灵魂,修炼python(40)--面向对象编程(10)—定制魔法方法+time模块
定制魔法方法 1.什么是定制魔法方法 首先定制是什么意思呢?其实就是自定义了,根据我们想要的要求来自定义.而在python中,其实那些所谓的内置函数,内置方法,内置属性之类的其实也是自定义出来的,不过 ...
随机推荐
- 面试之路(29)-TCP流量控制和拥塞控制-滑动窗口协议详解
拥塞: 拥塞发生的主要原因在于网络能够提供的资源不足以满足用户的需求,这些资源包括缓存空间.链路带宽容量和中间节点的处理能力.由于互联网的设计机制导致其缺乏"接纳控制"能力,因此在 ...
- 关于GPL329A中获取摄像头sensor id的问题
首先我拿到了sensor_id应用程序的源码,我要在上面添加获取ov2685 的 sensor id的代码. 利用find . -name get_sensor_id找到该代码编译之后生成的a.ou ...
- ionic1 打包过程 常用命令行
ionic start myapp myapp是项目名字 ionic start myapp --v2 ...
- c语言 基本运算
计算机的基本能力就是计算,所以一门程序设计语言的计算能力是非常重要的.C语言之所以无所不能,是因为它不仅有丰富的数据类型,还有强大的计算能力.C语言一共有34种运算符,包括了常见的加减乘除运算.这讲就 ...
- Oracle 10g DG 数据文件迁移
背景:某客户Oracle 10g 的DG由于空间不足,之前将部分数据文件迁移到其他目录,如今原目录扩容成功,要将之前迁移的数据文件再次迁移回来. 环境:Oracle 10.2.0.5 DG 单机 首先 ...
- mobile angualar ui的简单使用
最近做一个微信App形式的业务平台,之前从别人的推荐文中知道了mobile angualar ui这个东西,这次纯做mobile Web就试用了一下,之前PCWeb中用过AngularJS,Hybri ...
- jquery文本框内容实时监控
$("#A").bind("input propertychange", function () { $("#B").val($(this) ...
- XAMPP重置MySQL密码
找到XAMPP的安装位置,这里以我的为例:C:\xampp 那么MySQL的路径:C:\xampp\mysql phpMyAdmin的路径:C:\xampp\phpMyAdmin 修改MySQL密码 ...
- python实现四则运算和效能分析
代码github地址:https://github.com/yiduobaozhi/-1 PSP表格: 预测时间(分钟) planning 计划 15 Estimate 估计这个任务需要多少时间 10 ...
- 设计模式的征途—13.代理(Proxy)模式
所谓代购,简单说来就是找人帮忙购买所需要的商品.代购分为两种类型,一种是因为在当地买不到某件商品,又或者是因为当地这件商品的价格比其他地区的贵,因此托人在其他地区甚至国外购买该商品,然后通过快递发货或 ...