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

今天准备离职的同事交接工作,有一段代码,大家看看。

  •  1
     
  •   CLANNADHH · 2019-10-09 21:36:34 +08:00 · 14151 次点击
    这是一个创建于 1870 天前的主题,其中的信息可能已经有所发展或是发生改变。
    今天准备离职的同事交接工作,有一段代码,大家看看。
    django 写的接口,POST 请求,一共四个参数,下面用 a,b,c,d 代替

    a = request.post.get("a")
    b = request.post.get("b")
    c = request.post.get("c")
    d = request.post.get("d")

    try:
    a + b + c + d + "abcd"
    except:
    # 这里是错误的处理。

    后来询问该同事,他说这是做类型检测,不是字符串就会报错。
    我:!!! 哦~
    75 条回复    2019-10-18 18:57:53 +08:00
    Keyes
        1
    Keyes  
       2019-10-09 21:40:53 +08:00   ❤️ 5
    好精巧的代码
    wuwukai007
        2
    wuwukai007  
       2019-10-09 21:42:15 +08:00 via Android   ❤️ 2
    request.POST 拿到的值不都是字符串么😂
    Leigg
        3
    Leigg  
       2019-10-09 21:47:08 +08:00 via Android
    …不得不说一句,机智!
    beastk
        4
    beastk  
       2019-10-09 21:47:45 +08:00 via iPhone
    哈哈哈,你泄漏公司极密啦
    Takamine
        5
    Takamine  
       2019-10-09 21:51:01 +08:00   ❤️ 2
    isinstance : 你特么都这样了也不会想到我?
    wangyzj
        6
    wangyzj  
       2019-10-09 21:56:41 +08:00
    @Takamine 气死你
    111111111111
        7
    111111111111  
       2019-10-09 22:11:16 +08:00 via Android
    @wuwukai007 大意了吧,get 方法有默认值,返回个 None 就尴尬了
    yoshiyuki
        8
    yoshiyuki  
       2019-10-09 22:15:47 +08:00
    @wuwukai007 有些框架会自动进行数组的转化,PHP 里是这样的,python 强类型不太熟悉,不得而知
    byfar
        9
    byfar  
       2019-10-09 22:25:47 +08:00
    我天,我怎么没想到还能这么检测!!!
    noqwerty
        10
    noqwerty  
       2019-10-09 22:30:00 +08:00 via Android
    为了动态类型操碎了心😂
    CLANNADHH
        11
    CLANNADHH  
    OP
       2019-10-09 22:47:11 +08:00
    @Keyes
    @Leigg
    @byfar
    我是不是可以在他临走前怂恿他删个库 😂
    CLANNADHH
        12
    CLANNADHH  
    OP
       2019-10-09 22:47:55 +08:00
    @wuwukai007 奈何老哥是人才。

    @111111111111 哈,老哥细心。
    CLANNADHH
        13
    CLANNADHH  
    OP
       2019-10-09 22:48:21 +08:00
    @beastk 到底是谁走漏了风声,加薪。
    CLANNADHH
        14
    CLANNADHH  
    OP
       2019-10-09 22:49:32 +08:00
    @Takamine emmm,曰:太长了,记不住。

    @wangyzj @noqwerty 锅从天上来,挡不住。
    CLANNADHH
        15
    CLANNADHH  
    OP
       2019-10-09 22:50:25 +08:00
    @yoshiyuki 老哥是撸 PHP 的吗
    lau52y
        16
    lau52y  
       2019-10-09 22:59:23 +08:00 via iPhone
    每个人都会的,后来的人说前面的人,渐渐的发现自己也变成前人了^_^
    CLANNADHH
        17
    CLANNADHH  
    OP
       2019-10-09 23:03:07 +08:00
    @lau52y 可是这老哥有 4 年+经验了
    Trim21
        18
    Trim21  
       2019-10-09 23:05:32 +08:00 via iPhone
    一时除了专门写个函数还真想不出其他办法来简便的做到同样的事情…
    ClericPy
        19
    ClericPy  
       2019-10-09 23:07:58 +08:00
    取笑新手可不是个好习惯
    CLANNADHH
        20
    CLANNADHH  
    OP
       2019-10-09 23:11:45 +08:00 via Android
    @ClericPy 4 年+工作经验的老哥了 😂
    ClericPy
        21
    ClericPy  
       2019-10-09 23:18:15 +08:00
    @CLANNADHH 好吧... 陈年佳酿般的屎山, 都这么过来的, 没有 code review
    CLANNADHH
        22
    CLANNADHH  
    OP
       2019-10-09 23:21:32 +08:00 via Android
    @Trim21 略略略~
    wangyzj
        23
    wangyzj  
       2019-10-09 23:24:14 +08:00
    @CLANNADHH 这不是经验问题了,这是意识问题
    ila
        24
    ila  
       2019-10-09 23:41:01 +08:00 via Android
    类型检测不是应该 jsonschema 之类吗
    hyserendipity
        25
    hyserendipity  
       2019-10-10 00:00:27 +08:00 via iPhone
    cr 的重要性可见一斑。然而,绝大多数人由于工作太多,疏于提交 cr/帮别人 cr。
    Winrey
        26
    Winrey  
       2019-10-10 00:28:13 +08:00
    serializer 做错了什么,为什么放弃 serializer
    no1xsyzy
        27
    no1xsyzy  
       2019-10-10 03:20:27 +08:00
    @Trim21 看具体需求可以 .get("a", "") 然后 if a and b and c and d 或者说 all((a,b,c,d))
    当然,其实 dataclass + dacite 能够解决大多数这种问题了。
    mamahaha
        28
    mamahaha  
       2019-10-10 05:01:49 +08:00
    我自己写代码也经常有很幼稚的 bug,我总感觉谁都有脑子短路的时候,所以看到别人代码有错都是提醒,心理上不敢去嘲笑。
    是不是证明我还不太专业?专业人士不该出现幼稚的错误吧?
    secsilm
        29
    secsilm  
       2019-10-10 07:11:28 +08:00 via Android   ❤️ 3
    这样写很机智啊,一起检查所有变量的类型。感觉离职的这位水平应该不错
    sunulin
        30
    sunulin  
       2019-10-10 07:27:09 +08:00 via Android
    快,修改下,再来吐槽
    ila
        31
    ila  
       2019-10-10 07:38:40 +08:00 via Android
    @secsilm 这还机智,网上那么多解决方法,为啥不抄一个好的呢
    Allianzcortex
        32
    Allianzcortex  
       2019-10-10 08:50:42 +08:00 via iPhone
    marshmallow 就是应对这种情况
    JerryCha
        33
    JerryCha  
       2019-10-10 09:17:01 +08:00
    学习了,真精巧
    mskf
        34
    mskf  
       2019-10-10 09:20:59 +08:00
    如果很多参数的话这么做确实不错。。
    bakabie
        35
    bakabie  
       2019-10-10 09:22:27 +08:00 via Android
    有一说一,好歹是能用的(
    tonnycao
        36
    tonnycao  
       2019-10-10 09:50:53 +08:00
    为什么不用 isinstance 我是主攻 PHP 的
    Eleflea
        37
    Eleflea  
       2019-10-10 10:28:31 +08:00
    我觉得这样做没什么问题。Python 的 try...except 不仅是用来处理错误的。参见 fluent python P449.

    In Python, try/except is commonly used for control flow, and not just for error han‐
    dling. There’s even an acronym/slogan for that documented in the official Python glos‐
    sary:
    EAFP
    Easier to ask for forgiveness than permission. This common Python coding style
    assumes the existence of valid keys or attributes and catches exceptions if the as‐
    sumption proves false. This clean and fast style is characterized by the presence of
    many try and except statements. The technique contrasts with the LBYL style com‐
    mon to many other languages such as C.
    jinhao7773
        38
    jinhao7773  
       2019-10-10 10:37:00 +08:00
    参考 https://docs.djangoproject.com/en/2.2/ref/request-response/#django.http.QueryDict.get

    如果没有传过来对应的参数,是会有 None 的,人家一行代码就检查了 4 个参数是否都有传值,挺厉害的技巧啊。
    hanxiaomeng
        39
    hanxiaomeng  
       2019-10-10 10:42:01 +08:00
    精巧,思路瞬间开阔了
    lihongjie0209
        40
    lihongjie0209  
       2019-10-10 10:43:18 +08:00
    就不能这么写吗?
    try:
    a = request.post.getAsString("a")
    b = request.post.getAsString("b")
    c = request.post.getAsString("c")
    d = request.post.getAsString("d")

    catch:
    // 异常逻辑

    自己扩展一下或者是写一个工具类都可以啊。


    没看懂这种表意不明的写法有什么好推荐的
    richzhu
        41
    richzhu  
       2019-10-10 10:45:55 +08:00
    哈哈哈哈哈哈😂曰:“有什么问题吗?又不是不能用” (:dog
    lan2e
        42
    lan2e  
       2019-10-10 10:49:53 +08:00
    学到一招,不得不说这哥们 6p 啊
    hellwys1
        43
    hellwys1  
       2019-10-10 10:58:56 +08:00
    我真没觉得这代码有问题……
    dog82
        44
    dog82  
       2019-10-10 10:59:51 +08:00
    这样写比较取巧,对性能又没啥影响
    wliansheng
        45
    wliansheng  
       2019-10-10 11:43:46 +08:00
    可以用 serializer 啊。直接类型检查和 format 各种处理,
    artandlol
        46
    artandlol  
       2019-10-10 11:54:19 +08:00 via Android
    @ila 这么做是最简单的,当然也可以选择写个检测的
    ganbuliao
        47
    ganbuliao  
       2019-10-10 12:00:02 +08:00
    这段代码 再加个注释 就完美了 ^_^
    fml87
        48
    fml87  
       2019-10-10 12:26:49 +08:00
    a, b, c, d = map(request.post.get, ["a", "b", "c", "d"])
    assert all(isinstance(x, str) for x in [a, b, c, d]), "not str"

    其实感觉用 isinstance 可读性没有 a+b+c+d 好。。
    ddzzhen
        49
    ddzzhen  
       2019-10-10 12:30:43 +08:00 via Android
    奇才
    v3xe
        50
    v3xe  
       2019-10-10 12:35:42 +08:00 via iPhone   ❤️ 1
    降低可读性,稳固职场地位。
    Levi233
        51
    Levi233  
       2019-10-10 12:41:36 +08:00   ❤️ 7
    先不说你同事用取巧的方式写代码,你连这段代码都看不懂,你不觉得你自己问题更大吗?还发出来取笑别人,无语了。
    UserNameisNull
        52
    UserNameisNull  
       2019-10-10 13:28:02 +08:00
    精辟。巧妙,学习了。
    CLANNADHH
        53
    CLANNADHH  
    OP
       2019-10-10 13:43:34 +08:00
    @Levi233 发出来大家讨论,怎么就成了取笑别人呢?
    mengzhuo
        54
    mengzhuo  
       2019-10-10 13:46:14 +08:00 via iPhone
    可以啊,但是不判空么
    Vegetable
        55
    Vegetable  
       2019-10-10 13:51:15 +08:00
    少了一段注释,这哥们是个小机灵鬼!
    simonhunter
        56
    simonhunter  
       2019-10-10 13:54:43 +08:00
    请教一下,话说这样写要怎么判断 abcd 中哪个不是字符串需要重新获取或异常处理呢……在 except 里面再一个个去排查吗?
    dwggrv
        57
    dwggrv  
       2019-10-10 14:05:12 +08:00
    妙啊~
    houzhimeng
        58
    houzhimeng  
       2019-10-10 14:07:59 +08:00
    挺有意思的,不错
    wersonliu9527
        59
    wersonliu9527  
       2019-10-10 14:23:13 +08:00
    之前在别人 js 代码里面见过
    function sbtString(s1, s2) {
    var ous = "";
    s1 += "";
    s2 += "";
    for (var i = 1; i <= s1.length; i++) {
    var c1 = s1.substring(i - 1, i);
    var c2 = s2.indexOf(c1);
    if (c2 == -1) {
    ous += c1;
    }
    }
    return ous;
    }
    Levi233
        60
    Levi233  
       2019-10-10 14:29:03 +08:00
    @simonhunter 如果 abcd 里面有变量不是字符串,用+号拼接会报错,因为+号只能拼接字符串类型的变量,有别的类型的变量拼接出来会报错,python 是动态强类型语言。
    Levi233
        61
    Levi233  
       2019-10-10 14:31:24 +08:00
    @simonhunter 额。。看错你的问题了不好意思
    oahebky
        62
    oahebky  
       2019-10-10 14:50:14 +08:00
    如果是希望 a, b, c, d 都存在值,post 的时候这四个都要有,那下面这个做法不好吗?

    try:
    (游标卡尺占位)a = request.post["a"]
    (游标卡尺占位)b = request.post["b"]
    (游标卡尺占位)c = request.post["c"]
    (游标卡尺占位)d = request.post["d"]
    except:
    (游标卡尺占位)# ...

    写个 a+b+c+d+"" 不是很奇怪吗?
    Trim21
        63
    Trim21  
       2019-10-10 14:50:47 +08:00 via Android
    @simonhunter 看这个写法大胆猜测一下大概是不需要判断到底 abcd 哪个是空的,直接返回请求错误就行了。
    haon
        64
    haon  
       2019-10-10 14:53:19 +08:00
    我也这样写过...
    lrxiao
        65
    lrxiao  
       2019-10-10 14:53:38 +08:00
    __add__(
    dicc
        66
    dicc  
       2019-10-10 15:19:32 +08:00
    @lihongjie0209 #40 你确定你用过 django?
    tabris17
        67
    tabris17  
       2019-10-10 15:23:25 +08:00
    @wuwukai007 也可能是 None
    hmxxmh
        68
    hmxxmh  
       2019-10-10 15:24:13 +08:00
    @ila 是的,很好用
    lihongjie0209
        69
    lihongjie0209  
       2019-10-10 15:33:11 +08:00
    @dicc #66 自己扩展一下或者是写一个工具类都可以啊。

    这种常见的框架扩展一下内置的方法应该不难吧
    EdwardLeeJan
        70
    EdwardLeeJan  
       2019-10-10 15:57:06 +08:00
    你不是应该高兴么,毕竟他要离职了
    babedoll
        71
    babedoll  
       2019-10-10 16:00:46 +08:00
    妙啊~
    fuxiuyin
        72
    fuxiuyin  
       2019-10-10 16:11:43 +08:00
    其实还好,不想改的话加句注释。他可能是不太清楚 HTTP 要求所有数据都以字符串发送,所以解出来也都是字符串,就算是真用 request.post(url, data={'a': True})传过去也是'True',所以不用担心会是其他类型,只可能是有这个参数或者没这个参数。所以不想改的话就打个注释留着,改的话就改成
    try:
    a = request.POST['a']
    ....
    就行了
    cyrbuzz
        73
    cyrbuzz  
       2019-10-10 17:32:17 +08:00   ❤️ 1
    楼主头像是为了契合这代码换的?
    dasabi
        74
    dasabi  
       2019-10-12 21:17:35 +08:00 via Android
    之前 python 里面用过这种方法,比较取巧但是难登大雅之堂。你的同事 python 至少有一年经验
    songkai
        75
    songkai  
       2019-10-18 18:57:53 +08:00
    未来的美团外卖人员!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2460 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 16:01 · PVG 00:01 · LAX 08:01 · JFK 11:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.