Browsed by
分类: Python

Python修饰器的函数式编程

Python修饰器的函数式编程

Python的修饰器的英文名叫Decorator,当你看到这个英文名的时候,你可能会把其跟Design Pattern里的Decorator搞混了,其实这是完全不同的两个东西。虽然好像,他们要干的事都很相似——都是想要对一个已有的模块做一些“修饰工作”,所谓修饰工作就是想给现有的模块加上一些小装饰(一些小功能,这些小功能可能好多模块都会用到),但又不让这个小装饰(小功能)侵入到原有的模块中的代码里去。但是OO的Decorator简直就是一场恶梦,不信你就去看看wikipedia上的词条(Decorator Pattern)里的UML图和那些代码,这就是我在《 从面向对象的设计模式看软件设计》“餐后甜点”一节中说的,OO鼓励了——“厚重地胶合和复杂层次”,也是《 如此理解面向对象编程》中所说的“OO的狂热者们非常害怕处理数据”,Decorator Pattern搞出来的代码简直就是OO的反面教程。

Python 的 Decorator在使用上和Java/C#的Annotation很相似,就是在方法名前面加一个@XXX注解来为这个方法装饰一些东西。但是,Java/C#的Annotation也很让人望而却步,太TMD的复杂了,你要玩它,你需要了解一堆Annotation的类库文档,让人感觉就是在学另外一门语言。

而Python使用了一种相对于Decorator Pattern和Annotation来说非常优雅的方法,这种方法不需要你去掌握什么复杂的OO模型或是Annotation的各种类库规定,完全就是语言层面的玩法:一种函数式编程的技巧。如果你看过本站的《函数式编程》,你一定会为函数式编程的那种“描述你想干什么,而不是描述你要怎么去实现”的编程方式感到畅快。(如果你不了解函数式编程,那在读本文之前,还请你移步去看看《函数式编程》) 好了,我们先来点感性认识,看一个Python修饰器的Hello World的代码。

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (41 人打了分,平均分: 4.22 )
Loading...
函数式编程

函数式编程

当我们说起函数式编程来说,我们会看到如下函数式编程的长相:

  • 函数式编程的三大特性:
    • immutable data 不可变数据:像Clojure一样,默认上变量是不可变的,如果你要改变变量,你需要把变量copy出去修改。这样一来,可以让你的程序少很多Bug。因为,程序中的状态不好维护,在并发的时候更不好维护。(你可以试想一下如果你的程序有个复杂的状态,当以后别人改你代码的时候,是很容易出bug的,在并行中这样的问题就更多了)
    • first class functions:这个技术可以让你的函数就像变量一样来使用。也就是说,你的函数可以像变量一样被创建,修改,并当成变量一样传递,返回或是在函数中嵌套函数。这个有点像Javascript的Prototype(参看Javascript的面向对象编程
    • 尾递归优化:我们知道递归的害处,那就是如果递归很深的话,stack受不了,并会导致性能大幅度下降。所以,我们使用尾递归优化技术——每次递归时都会重用stack,这样一来能够提升性能,当然,这需要语言或编译器的支持。Python就不支持。
  • 函数式编程的几个技术
    • map & reduce :这个技术不用多说了,函数式编程最常见的技术就是对一个集合做Map和Reduce操作。这比起过程式的语言来说,在代码上要更容易阅读。(传统过程式的语言需要使用for/while循环,然后在各种变量中把数据倒过来倒过去的)这个很像C++中的STL中的foreach,find_if,count_if之流的函数的玩法。
    • pipeline:这个技术的意思是,把函数实例成一个一个的action,然后,把一组action放到一个数组或是列表中,然后把数据传给这个action list,数据就像一个pipeline一样顺序地被各个函数所操作,最终得到我们想要的结果。
    • recursing 递归 :递归最大的好处就简化代码,他可以把一个复杂的问题用很简单的代码描述出来。注意:递归的精髓是描述问题,而这正是函数式编程的精髓。
    • currying:把一个函数的多个参数分解成多个函数, 然后把函数多层封装起来,每层函数都返回一个函数去接收下一个参数这样,可以简化函数的多个参数。在C++中,这个很像STL中的bind_1st或是bind2nd。
    • higher order function 高阶函数:所谓高阶函数就是函数当参数,把传入的函数做一个封装,然后返回这个封装函数。现象上就是函数传进传出,就像面向对象对象满天飞一样。

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (90 人打了分,平均分: 4.61 )
Loading...
二叉树迭代器算法

二叉树迭代器算法

(感谢 @文艺复兴记(todd) 投递此文)

二叉树(Binary Tree)的前序、中序和后续遍历是算法和数据结构中的基本问题,基于递归的二叉树遍历算法更是递归的经典应用。

假设二叉树结点定义如下:

// C++
struct Node {
    int value;
    Node *left;
    Node *right;
}

中序递归遍历算法:

// C++
void inorder_traverse(Node *node) {
    if (NULL != node->left) {
        inorder_traverse(node->left);
    }
    do_something(node);
    if (NULL != node->right) {
        inorder_traverse(node->right);
    }
}

前序和后序遍历算法类似。

但是,仅有遍历算法是不够的,在许多应用中,我们还需要对遍历本身进行抽象。假如有一个求和的函数sum,我们希望它能应用于链表,数组,二叉树等等不同的数据结构。这时,我们可以抽象出迭代器(Iterator)的概念,通过迭代器把算法和数据结构解耦了,使得通用算法能应用于不同类型的数据结构。我们可以把sum函数定义为:

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (25 人打了分,平均分: 3.04 )
Loading...
一些有意思的算法代码

一些有意思的算法代码

Keith Schwarz是一个斯坦福大学计算机科学系的讲师。他对编程充满了热情。他的主页上他自己正在实现各种各样的有意思的算法和数据结构,http://www.keithschwarz.com/interesting/, 目前这个网页上有88个(见下面的列表),但这位大哥要干135个,你可以看看他的To-Do List

从这个列表上,我们可以看到,他从去年7月份就在自己实现这些东西了,我把他实现的这些算法转过来,

  • 另一方面我希望这个事可以影响到一些正在学习编程的人。看看别人是怎么学习编程的,希望对你有借鉴作用。
Name Link Date Added Language Description
Binomial Heap (link) 7‑24‑2010 C++ An implementation of a binomial heap data structure for use as a priority queue.
Bounded Priority Queue (link) 7‑24‑2010 C++ An implementation of a priority queue with a fixed upper limit to its size..
Matrix (link) 7‑24‑2010 C++ A collection of classes for manipulating matrices.
VList (link) 8‑16‑2010 Java An implementation of the List abstraction backed by a VList.
Function Wrapper (link) 8‑16‑2010 C++ A C++ wrapper class around unary functions.
String (link) 8‑17‑2010 C++ An implementation of a string abstraction that uses the small string optimization.

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (26 人打了分,平均分: 4.27 )
Loading...
Python 和 PyGame 的一些示例

Python 和 PyGame 的一些示例

看到一个网页收集了很多使用Python和PyGame写游戏的示例,分享给大家。(注:我不知道用Python/PyGame写游戏其性能会怎么样,但是一些小游戏应该是没有问题的)

这个网页同时给了一本介绍Python和PyGame的电子书(PDF),下面的这些例子就是这本书的示例。所有的这些示例可以打包下载

基础 Python 示例

Pygame 图形示例

pygame_base_template.py – 开启一个黑的 pygame 窗口。当你要写一个新的代码时,你可以使用这个示例的代码初始化你的程序。
simple_graphics_demo.py – 作图,画一些简单的图形。 simple_graphics_demo_thumb.png

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (10 人打了分,平均分: 2.90 )
Loading...
在Javascript里写Python

在Javascript里写Python

以前,本站介绍过去一种写HTML和CSS的新方法,以一种杂交式的代码,昨天给大家介绍了.NET代码和Python及Ruby代码的互相转换工具,但是这个世界可能比我们想像的还疯狂。IronPython 是一个在.NET平台上运行Python的东西,就像那些在JVM上运行其它语言的东东一样。当然,IronPython最邪恶的事情并不是在.NET上运行Python,而是在Javascript里写Python的语法。这个畸形混血儿的网址在这里(请注意翻墙)。

使用这个玩意很简单,下面,让我们看看这个混血儿长啥样?

首先,你需要链接一个js文件:

<script src="http://gestalt.ironpython.net/dlr-latest.js" type="text/javascript"></script>

然后,让我们看看如何写一个按钮事件:

<input id="button" type="button" value="Say, Hello!" />
<script type="text/python">
  def button_onclick(s, e):
      window.Alert("Hello from Python!")
  document.button.events.onclick += button_onclick
</script>

你对此事怎么看?欢迎留下你的看法。

好烂啊有点差凑合看看还不错很精彩 (10 人打了分,平均分: 3.20 )
Loading...
五大基于JVM的脚本语言

五大基于JVM的脚本语言

还记得以前本站的一篇文章《如何在Google App Engine上运行PHP》吗,其实那是借用 Quercus, 一个 100% 的用Java 实现的一个 PHP 引擎。今天,这样的东西太多了,能运行在Java的虚拟机JVM上的程序意味着有天然的跨平台性,现在JVM并不单单只能运行Java程序,在JVM上出现了若干使用Java虚拟机运行的脚本程序,比如什么PHP, Python, Ruby等等,这里有一篇文章评论了在JVM上的可以运行的排名前五脚本语言。他们分别是:

  1. Groovy。构建在强大的Java语言之上 并添加了从Python,Ruby和Smalltalk等语言中学到的诸多特征,为Java开发者提供了现代最流行的编程语言特性,而且学习成本很低(几乎为零),在开发Web,GUI,数据库或控制台程序时, 通过减少框架性代码 大大提高了开发者的效率。支持单元测试和模拟(对象),可以简化测试。无缝集成 所有已经存在的 Java对象和类库。直接编译成Java字节码,这样可以在任何使用Java的地方 使用Groovy。
  2. JRuby。一个纯Java实现的Ruby解释器。通过JRuby,你可以在JVM上直接运行Ruby程序,调用Java的类库。很多Java编写的Ruby IDE都是使用JRuby来解释语法的。
  3. Scala。一种多范式的编程语言,设计意图是要整合面向对象编程和函数式编程的各种特性。Scala编程语言近来抓住了很多开发者的眼球。它看起来像是一种纯粹的面向对象编程语言,而又无缝地结合了命令式和函数式的编程风格。Scala的名称表明,它还是一种高度可伸缩的语言。Scala的设计始终贯穿着一个理念:创造一种更好地支持组件的语言。
  4. Fantom 。Fantom 前身是 (Fan) 是一个基于 Java 和 .NET 平台的编程脚本引擎,用来在运行时产生 JVM 和 .NET 平台的字节码,该语言是面向对象的,跟 Groovy 和 JRuby 有点类似,可通过特定的接口来集成 Java 的类库。
  5. Jython。Jython由于继承了Java和Python二者的特性而显得很独特。其是一种完整的语言,而不是一个Java翻译器或仅仅是一个Python编译器,它是一个Python语言在Java中的完全实现。Jython也有很多从CPython中继承的模块库。最有趣的事情是Jython不像CPython或其他任何高级语言,它提供了对其实现语言的一切存取。所以Jython不仅给你提供了Python的库,同时也提供了所有的Java类。这使其有一个巨大的资源库。

下面是一张表格比较了这五大JVM脚本语言:

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (15 人打了分,平均分: 3.33 )
Loading...
Python处理encoding的小技巧

Python处理encoding的小技巧

用Python写过处理文本经常会遇到需要decoding或者encoding, 尤其是处理中文的时候。

encoding的问题处理起来是个脏活儿,报错不太容易看懂,网上相关资料不太好查。有同感?请继续读下去。

常规做法是读取文件的时候立刻decode, 所有的处理工作都用unicode,写会文件的时候encode. 但是等到读取的时候在处理的代码读/写起来都很别扭,感觉像穿上鞋以后袜子滑下来了…Python 3.1.1以上的版本解决了该问题。在Python 3.1.1中,打开文件可以加入encoding的参数:

file = open(filename, encoding='xxx')

啊,这样看起来终于舒坦了。 不同写如下的code了

file = open(filename)
for line in file:
    decoded_line = line.decode('xxx')
    do something else
提倡使用utf8
好烂啊有点差凑合看看还不错很精彩 (16 人打了分,平均分: 2.88 )
Loading...
Python程序员的进化

Python程序员的进化

以前本站发布过一篇《程序员的进化》,以一种幽默的代码展现方式调侃了程序。下面这篇是关于Python程序员的。以阶乘为例,很有意思。

新手程序员

def factorial(x):
    if x == 0:
        return 1
    else:
        return x * factorial(x - 1)
print factorial(6)

第一年的刚学完Pascal的新手

def factorial(x):
    result = 1
    i = 2
    while i <= x:
        result = result * i
        i = i + 1
    return result
print factorial(6)

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (42 人打了分,平均分: 4.26 )
Loading...
如何使用Python操作摄像头

如何使用Python操作摄像头

用过USB摄像头的都知道,你需要使用鼠标来操作它,比如截个图,录个像什么的,要点N次鼠标,对于我们那些不喜欢多次点击鼠标的人来说,这是一件很boring的事情,所以,本文将教你如何使用Python来操作摄像头。

这里,我们需要三个Python库: VideoCapturePIL  和 pygame。使用这三个库你可以非常容易的编写一个摄像头程序。之所以使用pygame,其目的就是因为这个库可以处理视频帧(fps)。下面是代码:

from VideoCapture import Device
import ImageDraw, sys, pygame, time
from pygame.locals import *
from PIL import ImageEnhance

res = (640,480)
pygame.init()
cam = Device()
cam.setResolution(res[0],res[1])
screen = pygame.display.set_mode((640,480))
pygame.display.set_caption('Webcam')
pygame.font.init()
font = pygame.font.SysFont("Courier",11)

def disp(phrase,loc):
    s = font.render(phrase, True, (200,200,200))
    sh = font.render(phrase, True, (50,50,50))
    screen.blit(sh, (loc[0]+1,loc[1]+1))
    screen.blit(s, loc)

brightness = 1.0
contrast = 1.0
shots = 0

while 1:
    camshot = ImageEnhance.Brightness(cam.getImage()).enhance(brightness)
    camshot = ImageEnhance.Contrast(camshot).enhance(contrast)
    for event in pygame.event.get():
        if event.type == pygame.QUIT: sys.exit()
    keyinput = pygame.key.get_pressed()
    if keyinput[K_1]: brightness -= .1
    if keyinput[K_2]: brightness += .1
    if keyinput[K_3]: contrast -= .1
    if keyinput[K_4]: contrast += .1
    if keyinput[K_q]: cam.displayCapturePinProperties()
    if keyinput[K_w]: cam.displayCaptureFilterProperties()
    if keyinput[K_s]:
        filename = str(time.time()) + ".jpg"
        cam.saveSnapshot(filename, quality=80, timestamp=0)
        shots += 1
    camshot = pygame.image.frombuffer(camshot.tostring(), res, "RGB")
    screen.blit(camshot, (0,0))
    disp("S:" + str(shots), (10,4))
    disp("B:" + str(brightness), (10,16))
    disp("C:" + str(contrast), (10,28))
    pygame.display.flip()

这段代码中的一些要点的解释如下:

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (9 人打了分,平均分: 3.67 )
Loading...