Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1798230
  • 博文数量: 335
  • 博客积分: 4690
  • 博客等级: 上校
  • 技术积分: 4341
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-08 21:38
个人简介

无聊之人--除了技术,还是技术,你懂得

文章分类

全部博文(335)

文章存档

2016年(29)

2015年(18)

2014年(7)

2013年(86)

2012年(90)

2011年(105)

分类: Python/Ruby

2013-01-23 17:07:27

通过在前天和昨天的学习知道,python值函数也是对象,是callable,具有该属性的还有方法,内置函数,内置方法,generator function,class,classic class,instance ofclass。

今天就来动手继续学习一下函数的相关概念。

在继续学习之前,我们在回顾一下,函数是对象,对象具有TYPE,ID,VALUE,同时函数还具有属性,比较重要的两个属性:


print  5*4
print  str(5)*4  # notice the difference 
y=lambda i,j: '%2dx%2d=%2d' %(j,i,i*j)
print type(y)
dic_lambda=y.__globals__
for key in dic_lambda.keys():
    print '%s=%s' % (key,dic_lambda[key])
# simple of python
for i in range(1,10):
    for j in range(1,i+1):
        print y(i,j),
    print             # print \\n
程序的输出如下:


20
5555

__builtins__=
__file__=h:\python\untitled-1.py
dic_lambda={'__builtins__': , '__file__': 'h:\\python\\untitled-1.py', 'dic_lambda': {...}, 'key': 'dic_lambda', 'y': at 0x01E5F9F0>, '__name__': '__main__', '__doc__': None}
y= at 0x01E5F9F0>
__name__=__main__
__doc__=None
 1x 1= 1
 1x 2= 2  2x 2= 4
 1x 3= 3  2x 3= 6  3x 3= 9
 1x 4= 4  2x 4= 8  3x 4=12  4x 4=16
 1x 5= 5  2x 5=10  3x 5=15  4x 5=20  5x 5=25
 1x 6= 6  2x 6=12  3x 6=18  4x 6=24  5x 6=30  6x 6=36
 1x 7= 7  2x 7=14  3x 7=21  4x 7=28  5x 7=35  6x 7=42  7x 7=49
 1x 8= 8  2x 8=16  3x 8=24  4x 8=32  5x 8=40  6x 8=48  7x 8=56  8x 8=64
 1x 9= 9  2x 9=18  3x 9=27  4x 9=36  5x 9=45  6x 9=54  7x 9=63  8x 9=72  9x 9=81
这个例子中,我们使用的lambda表达式,也就是匿名函数,匿名函数也是函数,通过type的输出可以看出。通过函数的——globals属性,我们可以知道函数的详细信息。

lambda表达式的优点就是,简洁只有一行,

略微修改一下程序:


y=lambda i,j: '%2dx%2d=%2d' %(j,i,i*j)
print type(y)
# simple of python
for i in range(1,10):
    for j in range(1,i+1):
        print y(i,j),
    print             # print \\n
dic_lambda=y.__globals__
for key in dic_lambda.keys():
    print '%s=%s' % (key,dic_lambda[key])   
程序的输出有略微有点不同:



 1x 1= 1
 1x 2= 2  2x 2= 4
 1x 3= 3  2x 3= 6  3x 3= 9
 1x 4= 4  2x 4= 8  3x 4=12  4x 4=16
 1x 5= 5  2x 5=10  3x 5=15  4x 5=20  5x 5=25
 1x 6= 6  2x 6=12  3x 6=18  4x 6=24  5x 6=30  6x 6=36
 1x 7= 7  2x 7=14  3x 7=21  4x 7=28  5x 7=35  6x 7=42  7x 7=49
 1x 8= 8  2x 8=16  3x 8=24  4x 8=32  5x 8=40  6x 8=48  7x 8=56  8x 8=64
 1x 9= 9  2x 9=18  3x 9=27  4x 9=36  5x 9=45  6x 9=54  7x 9=63  8x 9=72  9x 9=81
__builtins__=
__file__=h:\python\untitled-1.py
j=9
dic_lambda={'__builtins__': , '__file__': 'h:\\python\\untitled-1.py', 'j': 9, 'dic_lambda': {...}, 'i': 9, 'key': 'dic_lambda', 'y': at 0x01E0F9F0>, '__name__': '__main__', '__doc__': None}
i=9
y= at 0x01E0F9F0>
__name__=__main__
__doc__=None
此时我们发现该属性还包含了函数在运行时的变量信息,也就是说函数的属性在函数运行的时候是动态变化的,这一点同python时动态类型的语言就可以看出。

说到lanbda表达式,就不得不说python的函数式编程了,附录给出了python的build_in函数的清单,感兴趣的可以看一下。

说了这么多,下面进入正题,在上述代码中使用python打印了一个乘法公式,该代码看起来和C还是很类似的,貌似代码并没有想传说中的那么simple?

那也就说还有改进的余地了?那怎么改进呢?


print '\\n'.join([ '\\t'.join([ '%2dx%2d=%2d' % (j,i,i*j) for j in range(1,i+1)]) for i in range(1,10)])
这样看起来程序是不是由原来的4行变成了一行,是不是简单了很多?这是使用list comprehention,且采用了list 的嵌套,可读性不是太好。

查看list的定义:


list_display        ::=  "[" [expression_list | list_comprehension] "]"
list_comprehension  ::=  expression list_for
list_for            ::=  "for" target_list "in" old_expression_list [list_iter]
old_expression_list ::=  old_expression [("," old_expression)+ [","]]
old_expression      ::=  or_test | old_lambda_form
list_iter           ::=  list_for | list_if
list_if             ::=  "if" old_expression [list_iter]
该程序同时告诉我们内层的list comprehention 可调用外层的变量。哪还有其它的实现方法么?


本章节主要是介绍函数的,那么你肯定能猜到使用函数肯定也可以,这里就不得不说到BUILD_IN函数,



print '\\n'.join(map((lambda i:'\\t'.join(['%2dx%2d=%2d' % (j,i,i*j) for j in range(1,i+1)])),range(1,10)))
刚开始的程序使用lamb表达式看起来有点勉强,看到精简版的,你对lambda的表达式的用法应该有所熟悉了吧。


看到这以后你是不是对函数的理解有所加深呢?还没有完呢,继续深挖,看到map没,很陌生?没关系,我们有帮助文档:

Help on built-in function map in module __builtin__:


map(...)
    map(function, sequence[, sequence, ...]) -> list
    
    Return a list of the results of applying the function to the items of
    the argument sequence(s).  If more than one sequence is given, the
    function is called with an argument list consisting of the corresponding
    item of each sequence, substituting None for missing values when not all
    sequences have the same length.  If the function is None, return a list of
    the items of the sequence (or a list of tuples if more than one sequence).

几点需要说明,首先该函数式内容函数,接受两个参数,返回结果是一个list,该函数针对第二参数的(默认两个参数,当然你可以调用多个)的每一个元素,调用第一个函数

看到这些对上面程序的理解应该差不多了吧?

还有一个函数值得一提的是函数filter,帮助文档如下:

help> filter
Help on built-in function filter in module __builtin__:
Note that filter(function, iterable) is equivalent to [item for item in iterable if function(item)] if function is not None and [item for item in iterable if item] if function is None.

filter(...)
    filter(function or None, sequence) -> list, tuple, or string
    
    Return those items of sequence for which function(item) is true.  If
    function is None, return the items that are true.  If sequence is a tuple
    or string, return the same type, else return a list.


print filter(lambda x:  x % 2 == 0 ,range(1,10))
print reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])

reduce的功能也类似,只不是对所有的元素求和而已,

For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5). The left argument, x, is the accumulated value and the right argument, y, is the update value from the iterable. If the optional initializer is present, it is placed before the items of the iterable in the calculation, and serves as a default when the iterable is empty. If initializer is not given and iterable contains only one item, the first item is returned


说了这么多,还有一个需要介绍,那就是yield,该语句在ruby里也有,用法已经忘不得了,因此还在重新学习一下。

help> yield
The ``yield`` statement
***********************


   yield_stmt ::= yield_expression


The ``yield`` statement is only used when defining a generator
function, and is only used in the body of the generator function.
Using a ``yield`` statement in a function definition is sufficient to
cause that definition to create a generator function instead of a
normal function.
上面这段外文说了很多,其实就是告诉你,yield主要用来生成generator 函数,并且仅用在generator 函数体中,使用了关键字定义的函数的行为同

一般函数的行为就相同了。

When a generator function is called, it returns an iterator known as a
generator iterator, or more commonly, a generator.  The body of the
generator function is executed by calling the generator's ``next()``
method repeatedly until it raises an exception.
这段是说当GF被调用的时候,它返回一个generator。该函数的函数体只有在调用GF的next方法时才被执行,多次调用可以多次执行。

有点累了,后续继续研究

TO BE CONTINUED !

BUILT_IN FUNCTION:

Built-in Functions


阅读(2159) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~