Python进阶 函数式编程和面向对象编程等
2015-08-03 22:35
806 查看
函数式编程
函数:function函数式:functional,一种编程范式。函数式编程是一种抽象计算机的编程模式。
函数!=函数式(如计算!=计算机)
如下是不同语言的抽象层次不同
高阶函数:能接收函数做参数的函数
变量可以指向函数
函数的参数可以接收变量
一个函数可以接收另一个函数作为参数
例子:
接收abs函数,
定义一个函数,接收x,y,z三个参数。其中x,y是数值,z是函数。
1 2 3 | def add(x,y,z): return z(x) + z(y) add( - 2 , - 3 , abs ) |
PS:Python的函数不但可以返回int、str、list、dict等数据类型,还可以返回函数!
注意:
闭包
像这种内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数的情况,称为闭包(Closure)。
特点是返回的函数还引用了外层函数的局部变量,所以,要正确使用闭包,就要确保引用的局部变量在函数返回后不能变。举例如下:
#希望一次返回3个函数,分别计算1x1,2x2,3x3: defcount(): fs=[] foriinrange(1,4): deff(): returni*i fs.append(f) returnfs 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(lambdax:x*x,[1,2,3,4,5,6,7,8,9]) [1,4,9,16,25,36,49,64,81]
通过对比可以看出,匿名函数lambdax:x*x实际上就是:
deff(x): returnx*x
关键字lambda表示匿名函数,冒号前面的x表示函数参数
(匿名函数有个限制,就是只能有一个表达式,不写return,返回值就是该表达式的结果,返回函数的时候,也可以返回匿名函数:)
装饰器decorator
Python的decorator本质上就是一个高阶函数,它接收一个函数作为参数,然后,返回一个新函数。使用decorator用Python提供的@语法,这样可以避免手动编写f=decorate(f)这样的代码,极大简化Python代码。
模块
导入系统自带的模块math:importmath
如果我们只希望导入用到的math模块的某几个函数,而不是所有函数,可以用下面的语句:
frommathimportpow,sin,log
如果遇到名字冲突怎么办?
如果使用import导入模块名,由于必须通过模块名引用函数名,因此不存在冲突;
如果使用from...import导入log函数,势必引起冲突。这时,可以给函数起个“别名”来避免冲突:
frommathimportlog
fromloggingimportlogaslogger#logging的log现在变成了logger
printlog(10)#调用的是math的log
logger(10,'importfromlogging')#调用的是logging的log
动态导入模块
try:
fromcStringIOimportStringIO
exceptImportError:
fromStringIOimportStringIO
上述代码先尝试从cStringIO导入,如果失败了(比如cStringIO没有被安装),再尝试从StringIO导入
利用import...as...,还可以动态导入不同名称的模块
try:
importjson
exceptImportError:
importsimplejsonasjson
PS:
1.Python的新版本会引入新的功能,但是实际上这些功能在上一个老版本中就已经存在了。要“试用”某一新的特性,就可以通过导入__future__模块的某些功能来实现。
2.如何区分包和普通目录:包下面有个__init__.py每层都有。
安装第三方模块
1.使用easy_install
2.pip(推荐,内置到Python2.7.9)
1 2 3 4 5 | wget " --no-check-certificate#下载pip tar -xzvfpip-1.5.4. tar .gz cd pip-1.5.4 #(会提示安装setuptools,yuminstallpython-setuptools即可) pythonsetup.py install pip install pymongo #可以使用pip安装第三方模块了 |
面向对象编程基础
定义类并创建实例定义一个Person类如下
1 2 | class Person( object ): pass |
创建实例
xiaoming=Person()
如何让每个实例拥有各自不同的属性?
由于Python是动态语言,对每一个实例,都可以直接给他们的属性赋值,例如,给xiaoming这个实例加上name、gender和birth属性:
xiaoming=Person()
xiaoming.name='XiaoMing'
xiaoming.gender='Male'
xiaoming.birth='1990-1-1'
给xiaohong加上的属性不一定要和xiaoming相同:
xiaohong=Person()
xiaohong.name='XiaoHong'
xiaohong.school='No.1HighSchool'
xiaohong.grade=2
实例的属性可以像普通变量一样进行操作:
xiaohong.grade=xiaohong.grade+1
初始化实例属性
1 2 3 4 5 | class Person( object ): def __init__( self ,name,gender,birth): self .name = name self .gender = gender self .birth = birth |
相应地,创建实例时,就必须要提供除self以外的参数:
xiaoming=Person('XiaoMing','Male','1991-1-1')
xiaohong=Person('XiaoHong','Female','1992-2-2')
定义实例方法
1 2 3 4 5 6 | class Person( object ): def __init__( self ,name): self .__name = name def get_name( self ): #它的第一个参数永远是self,指向调用该方法的实例本身 return self .__name |
1 2 3 4 5 6 7 8 9 10 11 12 | class Person( object ): count = 0 @ classmethod def how_many( cls ): #类方法,不用self? return cls .count def __init__( self ,name): self .name = name Person.count = Person.count + 1 Person.how_many() p1 = Person( 'Bob' ) Person.how_many() |
如果一个属性由双下划线开头(__),该属性就无法被外部访问(相当于private).
但是,如果一个属性以"__xxx__"的形式定义,那它又可以被外部访问了,以"__xxx__"定义的属性在Python的类中被称为特殊属性,有很多预定义的特殊属性可以使用,通常我们不要把普通属性用"__xxx__"定义。
题目
请定义Person类的__init__方法,除了接受name、gender和birth外,还可接受任意关键字参数,并把他们都作为属性赋值给实例。
要定义关键字参数,使用**kw;
除了可以直接使用self.name='xxx'设置一个属性外,还可以通过setattr(self,'name','xxx')设置属性。
参考代码:
classPerson(object):
def__init__(self,name,gender,birth,**kw):
self.name=name
self.gender=gender
self.birth=birth
fork,vinkw.iteritems():
setattr(self,k,v)
xiaoming=Person('XiaoMing','Male','1990-1-1',job='Student')
printxiaoming.name
printxiaoming.job
类的继承
继承一个类1 2 3 4 | class Person( object ): def __init__( self ,name,gender): self .name = name self .gender = gender |
1 2 3 4 | class Student(Person): def __init__( self ,name,gender,score): super (Student, self ).__init__(name,gender) self .score = score |
判断类型
函数isinstance()可以判断一个变量的类型
>>>isinstance(p,Person)
获取对象信息
除了用isinstance()判断它是否是某种类型的实例外
type()函数获取变量的类型,它返回一个Type对象
可以用dir()函数获取变量的所有属性:dir(s)
参考:慕课网,python进阶
相关文章推荐
- Python进阶 函数式编程和面向对象编程等
- 函数的作用域
- Python 自然语言处理(NLP)工具库汇总
- windows7下python3.4.3 添加库路径(转)
- python对象拷贝
- 函数的定义与调用
- python数据类型判断type与isinstance的区别
- logistic回归与牛顿方法的python实现 (standford公开课程小作业)
- 用python操作文件和文件夹
- easy_install的安装和使用(Python基础)
- python菜鸟日记3
- python:变量与赋值 基本数据类型
- 【python】获取高德地图省市区县列表
- 理解python函数传参机制
- Python列表推导式---轻量级循环
- PYTHON对文件及文件夹的一些操作
- python 爬虫2 介绍一下怎么抓取cookies,python多线程
- Learning Python Day3
- Python中的print语句
- python常用函数