python进阶教程之函数对象(函数也是对象),python进阶教程
python进阶教程之函数对象(函数也是对象),python进阶教程
秉承着一切皆对象的理念,我们再次回头来看函数(function)。函数也是一个对象,具有属性(可以使用dir()查询)。作为对象,它还可以赋值给其它对象名,或者作为参数传递。
lambda函数
在展开之前,我们先提一下lambda函数。可以利用lambda函数的语法,定义函数。lambda例子如下:
func = lambda x,y: x + y
print func(3,4)
lambda生成一个函数对象。该函数参数为x,y,返回值为x+y。函数对象赋给func。func的调用与正常函数无异。
以上定义可以写成以下形式:
def func(x, y):
return x + y
函数作为参数传递
函数可以作为一个对象,进行参数传递。函数名(比如func)即该对象。比如说:
def test(f, a, b):
print 'test'
print f(a, b)
test(func, 3, 5)
test函数的第一个参数f就是一个函数对象。将func传递给f,test中的f()就拥有了func()的功能。
我们因此可以提高程序的灵活性。可以使用上面的test函数,带入不同的函数参数。比如:
test((lambda x,y: x**2 + y), 6, 9)
map()函数
map()是Python的内置函数。它的第一个参数是一个函数对象。
re = map((lambda x: x+3),[1,3,5,6])
这里,map()有两个参数,一个是lambda所定义的函数对象,一个是包含有多个元素的表。map()的功能是将函数对象依次作用于表的每一个元素,每次作用的结果储存于返回的表re中。map通过读入的函数(这里是lambda函数)来操作数据(这里“数据”是表中的每一个元素,“操作”是对每个数据加3)。
在Python 3.X中,map()的返回值是一个循环对象。可以利用list()函数,将该循环对象转换成表。
如果作为参数的函数对象有多个参数,可使用下面的方式,向map()传递函数参数的多个参数:
re = map((lambda x,y: x+y),[1,2,3],[6,7,9])
map()将每次从两个表中分别取出一个元素,带入lambda所定义的函数。
filter()函数
filter函数的第一个参数也是一个函数对象。它也是将作为参数的函数对象作用于多个元素。如果函数对象返回的是True,则该次的元素被储存于返回的表中。filter通过读入的函数来筛选数据。同样,在Python 3.X中,filter返回的不是表,而是循环对象。
filter函数的使用如下例:
def func(a):
if a > 100:
return True
else:
return False
print filter(func,[10,56,101,500])
reduce()函数
reduce函数的第一个参数也是函数,但有一个要求,就是这个函数自身能接收两个参数。reduce可以累进地将函数作用于各个参数。如下例:
print reduce((lambda x,y: x+y),[1,2,5,7,9])
reduce的第一个参数是lambda函数,它接收两个参数x,y, 返回x+y。
reduce将表中的前两个元素(1和2)传递给lambda函数,得到3。该返回值(3)将作为lambda函数的第一个参数,而表中的下一个元素(5)作为lambda函数的第二个参数,进行下一次的对lambda函数的调用,得到8。依次调用lambda函数,每次lambda函数的第一个参数是上一次运算结果,而第二个参数为表中的下一个元素,直到表中没有剩余元素。
上面例子,相当于(((1+2)+5)+7)+9
根据mmufhy的提醒: reduce()函数在3.0里面不能直接用的,它被定义在了functools包里面,需要引入包,见评论区。
总结
函数是一个对象
用lambda定义函数
map()
filter()
reduce()
类,简单来说就是一个函数的集合,在这个集合里面你定义了很多个函数;方法,其实就是你定义的这些函数。在下面的例子中Class Plus就是一个类,嵌套在这个类里面的两个函数就是所谓的方法,但是__init__只是用于初始化这个类,所以不算是方法。而get_result这个函数就是一个方法了。
举个例子:
Class Plus:
def __init__(self, a,b)
self.a = a
self.b = b
def get_result(self)
return self.a + self.b
在上面这个例子中,self就是对象,这个对象里面有两个参数,一个是self.a,另一个是self.b,对象简单来说就是自身具有多个属性(也可以说是子变量)的变量而已。如果说对象是笼统的东西,那么实例就是具体的东西。对象只是一个模板,有一些属性,而实例就是把数据填到这个模板里面去。比如这里你再这样写:c1 = Plus(1,2),这里c1就是一个实例,你还可以加一句:c2 = Plus(2,3),那c2也是一个实例,但是他们拥有共同的属性和模板。下面的例子就是调用了类里面的方法:
result1 = c1.get_result() >>> 3 输出结果为3
result2 = c2.get_result() >>> 5 输出结果为5
我要纠正推荐答案中的说法!
del并不是用来“删除引用指向的内存空间”,python中的del和c++中的delete是完全两个概念,不要误人子弟。。
一般来讲,del是用来删除变量的引用的,例如a = 1; del a,这里a是对1这个值的引用(python中所有的变量都可视作引用),而del a就是删除这一引用关系,也就是说,1不再被a这个变量引用了,同时a这个变量名也从变量表中剔除了。
如果还是不太清楚,我举这个例子你就明白了:
a = object()
b = a
del a
print b
print a # 该句会报a未定义的异常
这段代码中,a引用了一个新对象object(),而b=a使得b也引用了这个对象,a和b虽然是两个变量,但它们引用的是同一个对象,有点类似于c++中的两个指针指向同一个对象。
而后面del a仅仅只是把a这个变量对object()的引用删掉了,同时a的变量名也失效了,但并不表示object()这个对象被删除了,它还在,并且b还引用着它呢。从后面print b能正常输出就可以看出这一点。
python的内存释放采用的是引用计数机制,也就是当一个对象没有任何引用它的变量了,那么它就会自动被释放,无需人工干预。
此外,del对于不同的对象也会有不同的功能,这取决于对象本身对__del__系统方法的实现。例如一个列表a = [1,2,3],del a[0]表示将列表的首项删除,此时a就变成[2,3]了。如果是自定义的对象,那del的功能更是可以定义成你想要的任何样子,详情请参考python帮助中的__del__词条。
相关内容
- python进阶教程之异常处理,python进阶教程
- python进阶教程之动态类型详解,python进阶教程详解
- Python中使用ConfigParser解析ini配置文件实例,
- Python过滤函数filter()使用自定义函数过滤序列实例,p
- Python中使用item()方法遍历字典的例子,pythonitem
- Python引用(import)文件夹下的py文件的方法,
- Python version 2.7 required, which was not found in the registry,py
- 闭包在python中的应用之translate和maketrans用法详解,pyt
- python中的多线程实例教程,python实例教程
- Python对象的深拷贝和浅拷贝详解,python拷贝详解
评论关闭