请教一段 Python 代码! - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
bwangel
V2EX    Python

请教一段 Python 代码!

  •  
  •   bwangel
    bwangelme 2016-08-18 10:46:39 +08:00 3226 次点击
    这是一个创建于 3419 天前的主题,其中的信息可能已经有所发展或是发生改变。

    这是酷壳上一篇文章函数式编程上的一段代码,

    class Pipe(object): def __init__(self, func): self.func = func def __ror__(self, other): def generator(): for obj in other: if obj is not None: yield self.func(obj) return generator() @Pipe def even_filter(num): return num if num % 2 == 0 else None @Pipe def multiply_by_three(num): return num*3 @Pipe def convert_to_string(num): return 'The Number: %s' % num @Pipe def echo(item): print item return item def force(sqs): for item in sqs: pass nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] force(nums | even_filter | multiply_by_three | convert_to_string | echo) 

    关于那个__ror__方法的说明在这里:ror

    我有点不懂的是那个 force 函数时干吗的,它怎么把 num 传递给even_filter函数的。

    还请各位大牛多多指教!

    12 条回复    2016-08-18 21:30:23 +08:00
    yangtukun1412
        1
    yangtukun1412  
       2016-08-18 11:05:42 +08:00
    force() 接收的是一个生成器, 不是 nums.
    bwangel
        2
    bwangel  
    OP
       2016-08-18 11:09:11 +08:00
    好吧,我懂了

    `nums`是一个可迭代对象,

    `nums | even_filter`是一个生成器,以此类推,`nums | even_filter | multiply_by_three`,`nums | even_filter | multiply_by_three | convert_to_string | echo`等都是生成器。

    而 force 函数就是负责迭代最终返回的生成器,由于只要进行迭代就好了,所以 for 循环里面就是 pass 。
        3
    bwangel  
    OP
       2016-08-18 11:09:23 +08:00
    @yangtukun1412 ,嗯,懂了,谢谢!
    bwangel
        4
    bwangel  
    OP
       2016-08-18 11:14:51 +08:00
    另外写了一个易懂的调用过程(但是不大易读):

    ```
    generator = echo.__ror__(convert_to_string.__ror__(multiply_by_three.__ror__(even_filter.__ror__([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))))

    for item in generator:
    pass
    ```
    simonlify
        5
    simonlify  
       2016-08-18 11:30:34 +08:00
    这种写法很高大上啊!
    quxw
        6
    quxw  
       2016-08-18 13:28:38 +08:00
    其实重载,各种运算符。
    理解成这样可以
    map(map(map(map())))
    zhuangzhuang1988
        7
    zhuangzhuang1988  
       2016-08-18 13:38:35 +08:00
    ```F#
    let nums = seq {
    1..10
    }

    let even_filter = fun n -> n % 2 = 0
    let multiply_by_three = fun n -> n * 3
    let convert_to_string = fun n -> sprintf "the number is %d" n
    let echo = fun n -> printfn "%s" n

    nums
    |> Seq.filter even_filter
    |> Seq.map multiply_by_three
    |> Seq.map convert_to_string
    |> Seq.iter echo
    ```

    还是这样的清楚。。
    bwangel
        8
    bwangel  
    OP
       2016-08-18 14:45:08 +08:00
    ```ruby
    nums = [*1..10]

    def multiply_by_three(num)
    return num * 3
    end

    def convert_to_string(num)
    return num.to_s
    end

    a def echo(num)
    puts num
    end

    def even_filter(num)
    return num % 2 == 0
    end

    nums = nums.select { |num| even_filter(num) } \
    .map { |num| multiply_by_three(num)} \
    .map { |num| convert_to_string(num) } \
    .map { |num| echo(num) }
    ```


    @zhuangzhuang1988 ,你的代码是这个意思吧, F#看不懂,就用 Ruby 表达出来了!
    tonic
        9
    tonic  
       2016-08-18 15:04:15 +08:00
    把 `force` 改成 `list` 是一个效果啊, 等价于帮你把生成器展开, 帮你偷窥下里面每个元素是啥.
    bwangel
        10
    bwangel  
    OP
       2016-08-18 15:23:27 +08:00
    @tonic ,你讲得有道理!

    @simonlify ,我也觉得高大上!
    mgna17
        11
    mgna17  
       2016-08-18 15:55:07 +08:00
    城会玩 =_=
    wizardforcel
        12
    wizardforcel  
       2016-08-18 21:30:23 +08:00
    生成器是惰性的,你不遍历它就不生成啊。

    echo 之前所有的可迭代对象都被后一个 Pipe 遍历, echo 生成的只能手动再遍历一次了。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2667 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 08:03 PVG 16:03 LAX 00:03 JFK 03:03
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86