美文网首页
Python语言之一: python与函数式

Python语言之一: python与函数式

作者: Wu杰语 | 来源:发表于2018-05-21 20:40 被阅读0次

python语言支持多种编程范式,对于函数式,大家一定很感兴趣。但是由于python并不是严格的函数式语言(例如说haskell、erlang这样的语言),它所展现出来的不是完整的函数式语言特性。所以用python,可以是函数式的用法,也可以是过程式的用法,也可以是面向对象的用法。只有利用其中的特性,按照函数式的方式进行思考,才能真正的说函数式。

基于lambda和函数作为一等公民

函数式,顾名思义,就是函数编程,基于lambda演算, 理念是代数运算,关心的是函数的输入输出这对映射。

首先自然是函数作为头等函数和支持lambda,这是最基本的函数式语言的特性,为何这个特性很重要,是为了更重要的特性,高阶函数。例如说:

def addx(x):
   def addy(y):
       return x + y
   return addy

y = 3
add_x = addx(y)
add_y = add_x(4)

这个例子展示了函数作为一等公民

思考方式--纯函数

对于函数式计算,是没有状态的,没有状态带来的好处就是无论何时输入同样的值,输出总是一样的,所以函数式就特别适合并发编程,或者说面向并发。所以写函数的时候,要把函数写成纯函数,和函数要区分开。

例如说:

def add_one(x):
    return x + 1

这个就是无状态的纯函数,任何时候输入2,返回可定是3.

相反的,函数:

x = 1;
def add_one():
    x +=1
    return x

这里就是有状态的,在多线程状况下,遇到的东西是不可预测的。

haskell, erlang本身都是纯函数式语言,语言特性的关系,所以比较容易写出纯函数。

思考方式--高阶函数

接着我们用函数式的三件套展示一下高级函数的用法以及lambda表达式

def odd(x):
    return x % 2 == 0

odds = map(odd, list)

#用lambda一句表达
odds = map(lambda x : x % 2 == 0, list)

可以看到高阶函数的抽象的威力,而且可以用运用这些高阶函数,用流的方式来表达。

思考方式--递归

函数式一般使用递归思考问题,例如说求阶乘,非递归的写法:

def factorial(n):\
    result = 1
    for i in range(n):
        result *= (n + 1)

递归的写法

def factorial(n):
    return factorialInner(n, 1)
def factorialInner(n, result):
    if (n = 0):
        return result
    else:
       return factorialInner(n-1, result * n)

对比一下用erlang表达,多么干净利落:

factorial(1) -> 1;
factorial(n) -> factorial(n - 1) * n.

特性--柯里化

珂里化的特性是python模拟出来的,并不是语言本身的特性。

functiontool.partial(func, *args, **kvs)
partial可以让不兼容的代码一起工作,例如按两点距离排序

import math
import functiontool
def distance(p1, p2):
    x1, y1 = p1
    x2, y2 = p2
    return math.hypot(x2 - x1, y2 - y1)

points = [(3, 4), (5, 6), (7, 8), (1, 2)]
pt = (3, 4)
points.sort(key=functiontool.partial(distance, pt))

partial的实现是python的一个用函数实现简单对象读小技巧

def partial(func, *fargs, **fkeywords):
    def newfunc(*fargs, **fkeywords):
        newkeywords = keywords.copy()
        newkeywords.update(fkeywords)
        return func(*(args + fargs), **newkeywords)
    newfunc.func = func
    newfunc.args = args
    newfunc.keywords = keywords
    return newfunc

特性--延迟计算

延迟计算的特性python是利用自己的语言特性模拟出来的,并不是语言本身的特性。

迭代器实现延迟计算

延迟计算的体现就是迭代器了,例如说制造一个数据源,从1开始,无限度递增,如果用数组,可以表示,但是问题是有那么大的内存可以保存无线长读数据吗?

class IntFromOne(object):
    def __init__(self):
        self.i = 0
    def __iter__(self):
        return self
    def __next__(self):
        self.i += 1
        return self.i

按我的理解,迭代器就是一种接口定义,迭代器本身和延迟计算都是在python解释器中进行了包装或者说有语法糖。
例如说:

 b = IntFromOne()
for i in b:
    do somthing

这里的for语句中,解释器就进行了封装工作,将IntFromOne()对象转成迭代器,并不断调用next()方法,如果要停下来,就必须在next方法中返回stopiter的异常。

还有另外一个更强大一点的generator,我理解generator是利用python解释器是c运行,python函数的堆栈在堆中的特性技术,利用这种技术包装为迭代器。使用yield关键字,不仅能简单的实现迭代器,而且比较符合思考过程。至于这种技术计划再用一篇文章写一下,比较有意思。

面向对象实现延迟计算

这里主要是用描述符定义了decorator,用以描述属性

class lazypropery:
    def __init__(self, func):
        self.func = func
    def __get__(self, instance, cls):
        if instanse is None:
            return self
        else:
            value = self.func(instance)
            setattr(instanse, self.func.__name__, value)
             return value

import math
class Circle:
       def __init__(self, radius):
            self.radius = radius
       @lazyproperty
        def area(self):
              return math.pi * self.radius ** 2

只有调用area属性的时候它才会被计算出来,否则不会计算。

特性 -- Pipeline

用reduce可以表达

def pipe(data, funs):
  return reduce(lambda a, x: x(a), funs, data)

还可以用装饰器把pipeline写成linux的流模式,但这就不在本文讨论范围内了。

总结

python的函数式, 需要按照纯函数、高阶函数、递归的方式思考问题,可以利用珂里化、延迟计算、Pipeline等函数式特性,这么玩,才算函数式。

相关文章

  • Python函数式编程

    虽然 Python 不是函数式编程语言(是命令式编程语言),但是支持许多有价值的函数式编程工具。Python 提供...

  • Python语言之一: python与函数式

    python语言支持多种编程范式,对于函数式,大家一定很感兴趣。但是由于python并不是严格的函数式语言(例如说...

  • Python函数式介绍一 - 高阶函数

    Python函数式介绍一 - 高阶函数Python函数式介绍二 - 链式调用 最近为了给朋友推广Python函数式...

  • 函数式编程初窥

    最近在学习Erlang和Python。Erlang是完全的函数式编程语言,Python语言是面向对象的语言,但是它...

  • Python入门

    Python3教程 安装Python 第一个Python程序 Python基础 函数 高级特性 函数式编程 模块 ...

  • 高阶python 函数式编程

    高阶python 函数式编程 - 函数式 函数式编程(FunctionalProgramming) - 基于lam...

  • Python开发基础

    本章总结 Python是一种动态解释型的编程语言。Python简单易学,功能强大,支持面向对象和函数式编程。...

  • Python函数式编程

    在 Python 中使用函数式编程的最佳实践! 简 介 Python 是一种功能丰富的高级编程语言。它有通用的...

  • Python函数式编程指南

    注:采转归档,自己学习查询使用 Python函数式编程指南(1):概述Python函数式编程指南(2):函数Pyt...

  • 面向对象

    python: 函数式+面向对象

网友评论

      本文标题:Python语言之一: python与函数式

      本文链接:https://www.haomeiwen.com/subject/piptjftx.html