Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2577503
  • 博文数量: 315
  • 博客积分: 3901
  • 博客等级: 少校
  • 技术积分: 3640
  • 用 户 组: 普通用户
  • 注册时间: 2011-05-08 15:32
个人简介

知乎:https://www.zhihu.com/people/monkey.d.luffy Android高级开发交流群2: 752871516

文章分类

全部博文(315)

文章存档

2019年(2)

2018年(1)

2016年(7)

2015年(32)

2014年(39)

2013年(109)

2012年(81)

2011年(44)

分类: Python/Ruby

2012-02-22 21:33:57

       过年了,看书都没有什么状态,感觉很嘈杂!希望在新的一年里,大家都可以事事如意,没事出去散散心,释放自己的烦恼,只有自己快乐,家人健康,朋友幸福才是王道!

       11章是关于函数的,讲的不浅哦。尤其是装饰器那块,我现在还有一个例子没有调试出来。只有慢慢来了,估计是自己没有怎么理解,所以就先搁着,懂了再说。后面敲一个函数式编程的例子:(写下注释,这章都没写多少东西,其实很多都要自己去理解和深入)

 

11.1 函数式编程举例

 

# file: testit.py

#!/usr/bin/env python

 

#该函数传入了一个函数对象(其实只是一个元组的元素,不过是函数名,就像c语言的函数指针),两个参数;

#一个带一个*: 表示非关键字可变长参数(元组)

#一个带两个*: 表示关键字变长参数(字典)

#注意:如果同时出现两种变长参数,要保证关键字变长参数作为最后一个参数,并且非关键字参数出现在它之前就可以

def testit(func, *nkwargs, **kwargs):  

    try:

        retval = func(*nkwargs, **kwargs)

        result = (True, retval)

    except Exception, diag:

        result = (False, str(diag))              #一个元组,两个参数;布尔值和异常字符串

    return result

 

def test():

    funcs = (int, long, float)

    vals = (1234, 12.34, '1234', '12.34')

 

    for eachFunc in funcs:

        print '-' * 20

        for eachVal in vals:

            retval = testit(eachFunc, eachVal)         #testit传入eachFunc---假设是int, 传入eachVal---假设是1234;这样进入testit函数执行,你就明白了

            if retval[0]:

                print '%s(%s) =' % \

                    (eachFunc.__name__, `eachVal`), retval[1]         #这里加``的意义是可以保持像’1234’,’12.34’这样字符串保持本来的显示模式,不然直接eachVal的话,显示时’1234’会变成1234这样去显示;

            else:

                print '%s(%s) = FAILED:' % \

                    (eachFunc.__name__, `eachVal`), retval[1]

 

if __name__ == "__main__":

    test()

 

11.2 lambda关键字的意义

       Lambda表达式返回一个可调用的函数对象至于具体叫什么名字就不知道了,如果要很深入了解的话,估计要去研究lambda的工作机制了。这里我们只是简单的了解下基础知识,能看懂几个小例子就可以了。

       Lambda是单行操作,大大简化你的代码,而且节省内存空间,因为它不会开辟函数栈帧,因此你必须用一个变量来接收它的返回值,不然你直接运用它,结果是看不到的。但是用变量接收后,然后执行变量() 就能看到结果了;这样我们就可以把lambda表达式赋值给一个列表啊,元组之类的;以下是课本的例子:

       def add(x, y) : return x + y ? lambda x, y : x + y        #lambda定义了匿名函数,参数是x, y,执行的操作是x + y

 

11.3 体现函数式编程的内建函数(apply(), filter(),map(),reduce()最难)

       

       apply()就不说了;

       filter(): 以下是工作机制(模拟)

#file: myfilter.py

#!/usr/bin/env python

 

def filter(bool_func, seq):

    filtered_seq = []   #list defination

    for eachItem in seq:

        if bool_func(eachItem):

            filtered_seq.append(eachItem)

    return filtered_seq

 

def foo(item):

    if item == 2:

        return True

    else:

        return False

 

if __name__ == "__main__":

    myseq = (1, 2, '3', 3.4)

print filter(foo, myseq)

 

fileter()的运用:

#file: filter.py

#!/usr/bin/env python

 

from random import randint

 

def odd(n):

    return n % 2

 

allNums = []

for eachNum in range(9): #create 9 count data;

    allNums.append(randint(1, 99))

 

if __name__ == "__main__":

    print filter(odd, allNums)

    print filter(lambda n: n%2, allNums)  #利用lambda改造

    print [n for n in allNums if n%2]         #利用列表改进

    print [n for n in [randint(1, 99) for i in range(9)] if n%2]  #利用列表解析优化

 

reduce()用法;但是对于高级的估计就不懂了,只是了解下简单的用法,我想肯定没那么简单了。

print ‘the total is:’ reduce((lambda x, y: x + y), range(5))  #还是好理解, reduce以此迭代,最终返回一个结果.

 

至于‘偏函数’? 偏函数的设计,我认为就是为了把纷繁的诸多参数(当然有默认参数或者没有)的函数通过partial函数来‘分解’,最后返回的函数对象可以减少到一个参数就可以实现计算,像:baseTwo = partial(int, base = 2)

                            baseTwo(‘1000’)

我们可以封装实现自己的定义函数;这样显得方便多了!至于更高级的应用,以后有机会学到的。注意???文中提到了‘警惕关键字’,其实就是注意,如果你要用库函数来封装自己的函数,那么关键字参数要注意位置,即使是默认参数的函数,如果你写入了base = 2这样的带关键字的默认参数,那么就不会出错了,但是如果你写个2,而且第2参数的位置成为第1参数位置,那么编译器如何能识别了,是吧??

那么你在给函数传递参数时要注意了;还有个解释就是关键字参数始终在形参之后。

 

后面是一个和偏函数有点关系的gui界面,终于到了TKinter了,但是很遗憾我的电脑没装,而且回家了上不了网,以后补上;简单事例:(还是好理解的)

#file: ppFaGUI_TKinter.py

#!/usr/bin/env python

 

import TKinter   #后来装上python-tk后,测试了下;这里需要将TKinter改为Tkinter;下面的都要改;

from functools import partial  #顺便我安装了下python-dev,好像记得跟网络有关??

 

root = TKinter.Tk()

MyButton = partial(TKinter.Button, root, fg = 'white', bg = 'blue')

b1= MyButton(text = 'Button1')

b2= MyButton(text = 'Button2')

qb = MyButton(text = 'Quit', bg = 'red', command = root.quit)

b1.pack()

b2.pack()

qb.pack(fill = TKinter.X, expand = True)

root.title('PFAs!')

root.mainloop()

 

11.4 变量作用域

       由于学习了还是比较久的c,所以就扫了一遍;里面还有些概念要提下,就是为什么局部变量可以覆盖全局变量,而且你同时申明或者加定义一个变量在函数内和全局范围,也不会出错。这是因为编译器在扫描你的代码的时候,首先扫描局部变量,如果发现局部变量有了,那么就不再搜索全局是否有这样名字的变量,所以即使全局定义了也不会报错。最后那个无用的变量就会废弃掉,不会分配在.bss段或者数据段----c概念。

 

       后面还有递归,生成器,闭包(说道闭包,想到编译原理的内容,什么聚簇,闭包啊,烦死了,难懂反正,只有慢慢了解)相关的概念,当然变量作用域将的不少,而且很多挺深的!看了学习没那么简单了………..

 

12. 下一章我就想看下算了。不过里面提到了编码编程,我原来练习的代码里面不可以加入中文,是因为python默认没有支持这种编码格式,所以需要我们自己指定了:

       # -*- coding: UTF-8 -*-

       加入这样一句就可以支持中文了,其实多练习因为也不错;第12章就是主要讲解模块,我看的快,很多地方不太明白,以前在将arm的时候提到驱动模块啊之类的感觉自己好像明白是那么回事,但是要仔细搞懂它的深刻理论加实践也不是那么简单的,我都看的萌了。不过还是知道如何使用自己的模块了:

       文件:testit.py  #把它作为模块

       方法:首先要将该模块拷贝到python模块相同的路径,或者修改环境变量;

                交互模式下:import sys

                                     sys.path    #查看有python哪些环境变量

                                     sys.path.append(‘’)

               使用就和平时导入模块,在用句点属性标识法来访问;或者用from …import 来导入的话就可以直接使用函数;这是因为命名空间的缘故,具体命名空间还是挺深的,值得探究,c++里面强调多!

阅读(1830) | 评论(0) | 转发(0) |
0

上一篇:python异常处理

下一篇:python类

给主人留下些什么吧!~~