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
sensui7
V2EX  ›  Python

js 党可以吐槽一下 Python 吗

  •  
  •   sensui7 · 2017-09-12 00:49:17 +08:00 · 18961 次点击
    这是一个创建于 2389 天前的主题,其中的信息可能已经有所发展或是发生改变。

    缩进真的不习惯, map 返回的竟然是一个迭代器, 也许这就是大佬吧, 匿名函数 还要写 lambda 这么长的单词, 列表的长度还要用 len 函数而不是 len 属性, 您的列表到底是不是对象呢? 要不是对象您的 append 方法又是怎么回事? 我大 js

    js:
    arr.map(x => x*2)
    python:
    list(map(lambda x: x*2, arr))
    

    非引战, python 的优点就是生态环境, 我也是看中这点...

    156 条回复    2019-09-27 13:58:27 +08:00
    1  2  
    rogwan
        1
    rogwan  
       2017-09-12 00:52:44 +08:00 via Android
    数 } 真数不清楚哇😭
    eric6356
        2
    eric6356  
       2017-09-12 00:58:22 +08:00
    cdwyd
        3
    cdwyd  
       2017-09-12 00:59:19 +08:00 via Android   ❤️ 11
    不可以
    Nitroethane
        4
    Nitroethane  
       2017-09-12 01:01:32 +08:00 via Android
    每个人的习惯不同啊,一中语言写多了,刚开始写别的语言肯定各种不爽,很正常。所以嘛,最好的解决办法就是几种语言同时换着写,比如我最近用 python 写服务端,前端再写 JS,很酸爽。唯一不爽的一点就是 JS 的括号真心难数🙄
    mooncakejs
        5
    mooncakejs  
       2017-09-12 01:01:46 +08:00 via iPhone
    据说看 python 工具书之类的要自备尺子
    shihira
        6
    shihira  
       2017-09-12 01:04:04 +08:00 via Android   ❤️ 2
    把 lambda 整个单词打出来这一点我也不满意。缩进让代码易读就是个笑话。

    list 是对象,它的长度是来自__len__这个函数,len 只不过帮你调用了它而已。len 这里其实更像是一个 adapter,抹平容器间的差别的通用方法。举个相似的例子,比如在 C++里,你可以 vec.begin(),也可以 std::begin(vec)。

    返回迭代器是懒求值嘛,自然就有懒求值的好处,和坏处。
    CryMeatel
        7
    CryMeatel  
       2017-09-12 01:07:48 +08:00 via iPad   ❤️ 2
    。。。那是你不会写 python,那个逻辑一般这么写:[x*2 for x in arr]
    map 在 python 官方文档中明确不建议用
    Miy4mori
        8
    Miy4mori  
       2017-09-12 01:08:03 +08:00 via iPhone
    Java 写惯了感觉这俩都不够 OO,很痛苦。
    wellsc
        9
    wellsc  
       2017-09-12 02:26:07 +08:00 via iPhone
    @Miy4mori Erlang 才是最 OO 的语言,Java 顶多算是 OOP
    lovestudykid
        10
    lovestudykid  
       2017-09-12 02:46:00 +08:00   ❤️ 1
    @mooncakejs 笑了。那 js 看书怎么办,拿笔给括号编号么?
    msg7086
        11
    msg7086  
       2017-09-12 02:52:06 +08:00
    Python 的 OO 风格本来就有点问题,容器对象的长度方法竟然是个下划线方法;然后虽然提供了类似 map 的函数式调用和 lambda 表达式,却告诉你不要去用他们。之前转去代工一个 Python 程序的时候,写代码要多难受有多难受。

    @Miy4mori 听说 Java 还有非对象元素。
    jtsai
        12
    jtsai  
       2017-09-12 03:57:56 +08:00 via Android
    就这槽点 Python 严重吐槽 js 的数据类型
    RqPS6rhmP3Nyn3Tm
        13
    RqPS6rhmP3Nyn3Tm  
       2017-09-12 04:07:48 +08:00 via iPhone
    @msg7086 下划线倒是没什么问题,正确的做法不应该是 Len() 吗
    __repr__也是同理
    zhoufenfens
        14
    zhoufenfens  
       2017-09-12 04:08:31 +08:00 via Android
    最近写 ts,感觉静态类型作用没想象中那么大,写的烦琐
    msg7086
        15
    msg7086  
       2017-09-12 04:09:24 +08:00
    @BXIA len(arr) 实在是太丑了。
    lrxiao
        16
    lrxiao  
       2017-09-12 04:12:59 +08:00
    python 的 lambda 槽点确实大..神 tm 只能 capture by ref 还不能做正常的 for/if
    lazy 有 lazy 的好啊
    mozutaba
        17
    mozutaba  
       2017-09-12 04:13:00 +08:00 via Android
    我技术并不厉害,都是写些业务流程类的。不过 C++,java,php,js,python 发现回不去了。还是 python 方便
    lrxiao
        18
    lrxiao  
       2017-09-12 04:14:08 +08:00
    有个 UFCS 就更好了(
    list.len == len(list)
    lrxiao
        19
    lrxiao  
       2017-09-12 04:15:38 +08:00
    js 的 arrow function 还是很爽
    kenshinji
        20
    kenshinji  
       2017-09-12 05:51:49 +08:00 via iPhone
    @Miy4mori OO ? java 写起来不累么?虽然我也是每天写 java,但是真心累觉不爱
    ech0x
        21
    ech0x  
       2017-09-12 06:05:40 +08:00 via iPhone
    异教徒为什么要挑起圣战😂
    laxenade
        22
    laxenade  
       2017-09-12 06:17:10 +08:00 via Android
    @msg7086 所以 ruby 才是最好的语言
    lightening
        23
    lightening  
       2017-09-12 06:58:32 +08:00
    Rubyist 飘过,笑而不语
    asdf123101
        24
    asdf123101  
       2017-09-12 07:27:42 +08:00 via Android
    在这种地方 list comprehension 比 map 要方便。整体感觉 Python 比 JavaScript 要方便,好用。很多 JavaScript 的新方法都有抄 Python,比如 JavaScript 有实验性的 list comprehension。
    arischow
        25
    arischow  
       2017-09-12 07:41:49 +08:00 via iPhone
    因为推崇用各种 comp 而不是 map,你自己没去了解怪 Python 咯。
    arischow
        26
    arischow  
       2017-09-12 07:42:41 +08:00 via iPhone
    @arischow 我也是非引战,但你这种标题本身就有引战的意味,并不是强行定义非引战就 OK
    TangMonk
        27
    TangMonk  
       2017-09-12 07:44:15 +08:00 via Android
    ruby 大法好
    zaeneas
        28
    zaeneas  
       2017-09-12 07:48:26 +08:00
    我记得 underscore.js 以及 lodash 也是 map 返回迭代器的;这样可以和 filter 之类混合时运算较快

    lambda 我倒不是觉得什么问题,但是问题在于 lambda 只能撸一行,于是稍微复杂一点的 callback 都必须新声明一个函数

    以及 default variable 的设计也是坑

    不过对 callback 不友善才应该是 js 写惯了的对 python 不爽的地方
    crab
        29
    crab  
       2017-09-12 07:53:43 +08:00   ❤️ 1
    chenqh
        30
    chenqh  
       2017-09-12 07:58:03 +08:00
    因为 len 是 builtin 方法啊,你也可以使用"a".__len__(),这样来获取长度
    xiaozizayang
        31
    xiaozizayang  
       2017-09-12 08:05:52 +08:00 via Android
    len 方法很突出 python 的思想
    NoAnyLove
        32
    NoAnyLove  
       2017-09-12 08:06:53 +08:00   ❤️ 5
    @shihira 我的观点恰恰相反,缩进让代码可读性增加,特别对于初学者,不会对无数的{}感到恐惧,同时也有强迫开发者优化逻辑和结构的被动效果。

    @msg7086 Python 的数据模型应该算是非常优雅的了,所有基本的属性都有 builtin 的函数对应。话说,你写 Java 的时候难道重来没有纠结过:我去,这个对象到底应该用 size ? size()? length ?还是 length()?来获取长度?感觉 Ruby 的做法就是:不要纠结了,我全部都提供给你用。而 Python 的做法是:不要纠结了,统统用 len()就好了。

    @lrxiao lambda 在 functional programming 里面很好用,不过 Guido 并不承认 Python 是一个 functional programming 语言,所以没有加强 lambda 的功能,只能用简单的表达式确实不如 Ruby 强大。不过感觉意图在于强迫开发者不要写过于复杂的 lambda 函数,有复杂功能的都该有个名字。gtqdg
    wwqgtxx
        33
    wwqgtxx  
       2017-09-12 08:08:54 +08:00 via iPhone
    python 万物皆对象,就算函数也是个对象
    用 len()的好处是为了统一各种有长度的对象,有些对象的长度是动态获取的,你要是用 xxx.len 的话就必须要用 @property 把一个参数强行动态化了,从实用性来说还不如直接定义__len__()然后由编译器自动调用

    不过 python 的 lambda 不能跨行的确是个大缺点
    allenhu
        34
    allenhu  
       2017-09-12 08:23:34 +08:00 via Android   ❤️ 2
    @NoAnyLove 也吐槽一下代码缩进,简直就是为了标新立异,没有太大实际作用,新手也基本是从 helloword 开始,能有无数{}?如果对{}都感到恐惧,那基本也不用编程了,相反,{}的含义更容易理解。而且其他语言基本都是用{},没有额外学习成本
    msg7086
        35
    msg7086  
       2017-09-12 08:24:22 +08:00
    @NoAnyLove 是啊,Ruby 就是你想怎么写就怎么写,觉得怎么写舒服就怎么写。
    est
        36
    est  
       2017-09-12 08:25:22 +08:00 via iPhone
    楼主还没发现 [].sort() 的坑说明你业务写得还不够多。。。
    TabGre
        37
    TabGre  
       2017-09-12 08:27:15 +08:00 via iPhone
    @Nitroethane Lisp 不服😜
    popok
        38
    popok  
       2017-09-12 08:28:24 +08:00
    py 和 js,我支持 js
    gimp
        39
    gimp  
       2017-09-12 08:35:34 +08:00
    7L 说的对,你这写法很不 pythonic
    metaquant
        40
    metaquant  
       2017-09-12 08:39:10 +08:00
    以我浅薄的编程经验,语法就是个日久生情的过程,刚开始用觉得别扭,之后觉得顺手,最后就觉得优美了。想我当年从 matlab 转到 python 时,还觉得 python 语法难看了,现在回头看,觉得当时写 matlab 时全局变量满天飞简直就是个灾难
    dikT
        41
    dikT  
       2017-09-12 08:44:37 +08:00   ❤️ 9
    });});});});});
    jeffersonpig
        42
    jeffersonpig  
       2017-09-12 08:48:31 +08:00   ❤️ 1
    说是“非引战”却偏偏干着引战的事情。那句话怎么说来着?
    aristotll
        43
    aristotll  
       2017-09-12 08:48:56 +08:00
    缩进的确是昏招 其他 Python 语法特性不评价
    ox180
        44
    ox180  
       2017-09-12 08:50:19 +08:00
    @mooncakejs 您用了??
    ox180
        45
    ox180  
       2017-09-12 08:53:31 +08:00
    @gimp 我同意你的观点。
    imn1
        46
    imn1  
       2017-09-12 08:59:00 +08:00
    那么 js 中字典是不是对象呢?

    js 我最混乱是这个:
    a=new Array();
    a[0]=1;
    a[1]=2;
    a[2]=3;
    alert(a.length);
    a["a"]=1;
    a["b"]=2;
    a["c"]=3;
    alert(a.length);
    b={"a":1, "b":2};
    alert(b.length);
    c=["aa","bb","cc"];
    alert(c.length);

    @jtsai #12 说的对,LZ 思想里把 list/tuple/dict/set 等都认为是 array 了
    js 中就一个 array 的 class,里面写一次 length 就够了
    而 python 中 list/tuple/dict/set 等是不同的 class,每个都写一遍 length 属性?不如提一个内置函数,对可数对象计算长度
    a7063888
        47
    a7063888  
       2017-09-12 08:59:30 +08:00 via iPhone
    好一个非引战,刚接触 Python 缩进确实奇葩
    ikeeper
        48
    ikeeper  
       2017-09-12 09:01:37 +08:00
    返回迭代器是为了节省内存
    gyorou
        49
    gyorou  
       2017-09-12 09:07:21 +08:00
    有了内置函数就不够面向对象了,更偏向于面向接口,要求特定的数据类型要实现某个接口。
    在一切都是对象的语言中,是不存在数据类型这种东西的。所有的东西都是对象,包括所谓定义数据类型的 class 也是。
    Chingim
        50
    Chingim  
       2017-09-12 09:09:12 +08:00 via Android
    @imn1 那__len__是怎么回事?
    shuirong1997
        51
    shuirong1997  
       2017-09-12 09:09:20 +08:00 via Android
    @dikT 格式化代码+看前面的括号 就能分辨出哪个是哪个
    Keyes
        52
    Keyes  
       2017-09-12 09:10:48 +08:00
    @sensui7 所以楼主可以去看看 Scala,我已经入坑无法自拔

    Scala:
    x.map(_*2)
    bbsteel
        53
    bbsteel  
       2017-09-12 09:13:33 +08:00 via Android   ❤️ 2
    关于缩进,至少让我看到的最烂的 python 依然能看得下去,但最烂的 js 代码。。。。
    imn1
        54
    imn1  
       2017-09-12 09:23:49 +08:00
    @Chingim
    __len__也是调用内置 len()的吧?提供给自定义而已
    oska874
        55
    oska874  
       2017-09-12 09:35:14 +08:00
    不可以。
    xbotter
        56
    xbotter  
       2017-09-12 09:36:08 +08:00
    说生态环境好 确认不是在黑 Java ?
    Chingim
        57
    Chingim  
       2017-09-12 09:38:04 +08:00
    @imn1 len 调用 __len__

    所以我就更不懂为什么 python 要提供一个 len 函数?
    SuperMild
        58
    SuperMild  
       2017-09-12 09:39:33 +08:00 via iPhone
    论面向对象,论语法强大优雅,当然是 ruby 了。
    mimzy
        59
    mimzy  
       2017-09-12 09:40:51 +08:00
    @shihira #6 对于内置对象如 list,在 CPython 中它长度并不来自 __len__ 这个函数:

    "No method is called for the built-in objects of CPython: the length is simply read from a field in a C struct. Getting the number of items in a collection is a common operation and must work efficiently for such basic and diverse types as str, list, memoryview, and so on."

    -- Fluent Python, page 14

    大家也可以读一下这页的 "Why len Is Not a Method",我理解的大意是说 "len is not called as a method because it gets special treatment as part of the Python data model".
    mimzy
        60
    mimzy  
       2017-09-12 09:42:46 +08:00
    @Chingim #57 为了效率。见 #59
    keysona
        61
    keysona  
       2017-09-12 09:43:05 +08:00
    有点好笑啊。


    刚看了流畅的 python,里面对 python 这种 magic method 是持赞赏态度的,看完我也这么觉得。

    结果在这里看到完全不同的观点。

    哈哈,前后端通写的我也觉得 js 不爽,有很多奇怪的情况,这些不一致,有违直觉的结果也让我也不爽啊。
    airborne007
        62
    airborne007  
       2017-09-12 09:43:26 +08:00
    不吹不黑,js 就是个垃圾语言。
    fy
        63
    fy  
       2017-09-12 09:45:12 +08:00
    总结下问题:为啥 python 语言写法和 js 不一样?和我习惯的不同,怎么可以这样?
    keysona
        64
    keysona  
       2017-09-12 09:46:06 +08:00
    缩进真不是个问题。

    单纯是个习惯,刚开始不习惯觉得不爽我觉可以接受。

    当你去看别人几万几万行的代码,你就会明白缩进有多重要了。
    bramblex
        65
    bramblex  
       2017-09-12 09:46:31 +08:00
    js 和 python 比我当然站 js。

    毕竟 js 有 typescript,你 Python 没有 typethon 啊!
    qdzzyb
        66
    qdzzyb  
       2017-09-12 09:46:47 +08:00
    python 难道不是应该这么写 `arr = [i * 2 for i in arr]`
    imn1
        67
    imn1  
       2017-09-12 09:47:02 +08:00
    @Chingim #57

    object.__len__(self)

    Called to implement the built-in function len(). Should return the length of the object, an integer >= 0. Also, an object that doesn ’ t define a __bool__() method and whose __len__() method returns zero is considered to be false in a Boolean context.
    keysona
        68
    keysona  
       2017-09-12 09:49:43 +08:00
    rocksolid
        69
    rocksolid  
       2017-09-12 09:50:11 +08:00
    换 python2 就好了
    keysona
        70
    keysona  
       2017-09-12 09:50:25 +08:00
    @airborne007

    es6 的 js,写起来舒服多了。

    之前的简直是个噩梦!
    Chingim
        71
    Chingim  
       2017-09-12 09:54:41 +08:00
    @imn1 没错啊, len() 调用 __len__
    airborne007
        72
    airborne007  
       2017-09-12 09:54:55 +08:00
    @keysona 然而 es6 很多东西也是抄 Python 的,再说,要兼容 IE 大哥呢,es6 不是你想用就能用。
    recall704
        73
    recall704  
       2017-09-12 09:55:27 +08:00
    习惯就好,刚学的时候恨不得自己加上 {},然后再用程序去掉。
    keysona
        74
    keysona  
       2017-09-12 09:55:29 +08:00
    脚本语言鄙视链。


    ruby -- python -- js

    谁也不服谁。
    bramblex
        75
    bramblex  
       2017-09-12 09:56:00 +08:00
    @keysona
    类型约束,类型检查,函数类型,高阶类型。就连 typescript 的类型系统,我现在还觉得太智障,更别说 python 的这种玩具级别了。
    keysona
        76
    keysona  
       2017-09-12 09:57:05 +08:00
    @airborne007

    写前端,自觉砍掉 ie。

    只兼容最新的 chrome & firefox。
    sunzhenyucn
        77
    sunzhenyucn  
       2017-09-12 09:58:45 +08:00
    简单,觉得不好不用就是了。
    大概 JS 不是`})})})})};`?(逃
    Chingim
        78
    Chingim  
       2017-09-12 10:02:18 +08:00
    @mimzy 意思是说用全局的 len() 用来 "getting the length is simply read from a field in a C struct." 吗?
    那么为什么 arr.len() 不能用来做同样的事情呢? 我的意思是 python 的内置数组为什么没有添加一个 len 方法, 然后用这个方法去读取 C 结构体的字段呢? arr.len() 更 OO 不是吗

    如果理解有误, 请指正
    keysona
        79
    keysona  
       2017-09-12 10:02:55 +08:00
    @bramblex

    额,我个人不是很喜欢在动态语言加上类型。也许没经历过大项目吧。

    总感觉怪怪的。
    Miy4mori
        80
    Miy4mori  
       2017-09-12 10:03:23 +08:00 via iPhone
    @kenshinji 今年已经是 2017 年啦,该不会还拿记事本写 Java 吧?
    YYYeung
        81
    YYYeung  
       2017-09-12 10:03:38 +08:00
    缩紧还好,就是在 Python 里面没有 js 那种闭包写法感觉有点不习惯
    ThinkCat
        82
    ThinkCat  
       2017-09-12 10:04:49 +08:00
    coffeescript, 一箭双雕, 既有了 js,也有了 python 缩进 ,语法还精简
    keysona
        83
    keysona  
       2017-09-12 10:05:03 +08:00
    @Miy4mori

    虽然是 2017 年了,但是不用 ide,我还真不会写 java。
    reus
        84
    reus  
       2017-09-12 10:10:17 +08:00
    引战就是引战,不是你一句“非引战”就不是了。

    非常讨厌楼主这种人
    wizardoz
        85
    wizardoz  
       2017-09-12 10:10:25 +08:00
    如果一种语言很烂,它的生态环境如何会好?
    lrxiao
        86
    lrxiao  
       2017-09-12 10:12:08 +08:00
    缩进要是和 Haskell 一样提供两种方式就好了:(
    lrxiao
        87
    lrxiao  
       2017-09-12 10:12:18 +08:00
    就没有这么多战争了
    lrxiao
        88
    lrxiao  
       2017-09-12 10:15:13 +08:00
    @NoAnyLove 匿名函数不只在 FP 里用的多..实际上基本上语言都能写很优雅的 lambda Py 的 lambda 很弱
    bramblex
        89
    bramblex  
       2017-09-12 10:16:48 +08:00   ❤️ 1
    @keysona

    好的类型系统是避坑神器,尤其是代码量大逻辑复杂的时候。

    而且是写这种动态语言的时候,哪怕没有类型系统,其实在写代码的时候自己脑子里还是需要开一个静态检查,真的很累的。类型系统就是把脑子里的那个静态检查让程序去做了而已。
    bramblex
        90
    bramblex  
       2017-09-12 10:17:43 +08:00
    @ThinkCat

    coffee 作者已经明确说明不继续加新特性,并且推荐大家写 es6 了
    bramblex
        91
    bramblex  
       2017-09-12 10:18:35 +08:00
    @airborne007 不吹不黑,python 这种垃圾语言,抄我 Haskell 还抄那么丑。
    xiaomeimei
        92
    xiaomeimei  
       2017-09-12 10:19:16 +08:00
    两个都写,也没有好坏,不过,不管编辑器如何好,js 回调太多,层次很深的时候,就不好区分块了。所以写 js 尽量不要写太深的嵌套,3 层是最多的。
    mooncakejs
        93
    mooncakejs  
       2017-09-12 10:19:20 +08:00
    @lovestudykid
    js 已经有了 promise,n 层的括号已经是过去式了。 相反 py 定义一个匿名函数都要持续缩进
    @ox180
    之前公司共享书籍上,py 的都是点了````来表示空格个数 2333.
    bramblex
        94
    bramblex  
       2017-09-12 10:20:13 +08:00
    @lrxiao

    Haskell 的缩进其实是很复杂的,我尝试过实现 haskell style 的 parser,解析的真心复杂。
    imn1
        95
    imn1  
       2017-09-12 10:21:33 +08:00
    @Chingim #71
    好吧,我前面写错了,写了__len__()方法,而不是__len__属性
    len()调用的是方法,而不是属性

    __len__属性,返回的也可能是个对象,__len__()方法返回的是值,两者调用性质不同
    https://stackoverflow.com/questions/20302558/why-python-function-len-is-faster-than-len-method


    In [19]: b=[[1,2,3]]

    In [20]: b.__len__
    Out[20]: <method-wrapper '__len__' of list object at 0x7f6032f6b0c8>

    In [21]: len(b)
    Out[21]: 1

    In [22]: b[0].__len__
    Out[22]: <method-wrapper '__len__' of list object at 0x7f60335d63c8>

    In [23]: b[0].__len__()
    Out[23]: 3
    cbiqih
        96
    cbiqih  
       2017-09-12 10:22:36 +08:00
    Java 转 Python 的我,写 Python 感觉一种莫名的爽~
    Kisesy
        97
    Kisesy  
       2017-09-12 10:26:36 +08:00
    @bramblex 想要类型检查,可以写 pyx 啊,可以用 C 编译器编译,py 的语法,C 的速度
    jtsai
        98
    jtsai  
       2017-09-12 10:28:56 +08:00
    @cbiqih 圣战转到了 java,我跟你一样,感觉多活了几年。
    iFlicker
        99
    iFlicker  
       2017-09-12 10:31:15 +08:00   ❤️ 2
    就我一个很喜欢 Python 这种缩进风格的么?
    zhangsen1992
        100
    zhangsen1992  
       2017-09-12 10:47:33 +08:00
    js 才混乱吧,});});});});});
    1  2  
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5458 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 54ms · UTC 08:51 · PVG 16:51 · LAX 01:51 · JFK 04:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.