V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
shijingshijing
V2EX  ›  程序员

如何尽量增加 Python 代码行数,在不改变功能的前提下,代码尽量复杂化

  •  1
     
  •   shijingshijing · 2023-11-30 15:14:49 +08:00 · 13062 次点击
    这是一个创建于 369 天前的主题,其中的信息可能已经有所发展或是发生改变。

    RT ,帮朋友问的,他 6 月毕业一直空档,现在好容易找了个传统公司,偏制造业的那种,开发就几个人,老板定 KPI 主要是看代码行数和文档字数。老板的思路是,我提一个功能,朋友帮他实现,然后按代码行数来算这个功能的复杂程度和绩效。老板虽然不懂编程,但是还是很精明的,会给让他们自己排期,定节点,然后评审。项目开始和结束的时候,都会找他懂技术的朋友帮忙看一下。

    他们老板和老板的朋友不傻,所以塞注释那种肯定是不行的。我帮他在网上找了一堆 Python 代码混淆的工具,Pyobfuscate 那种把函数名改成 lllllll 的,肯定也不行。但评审也不会太深入,塞点无效代码应该是可以的,就是太费脑子了。

    目前我和他两个臭皮匠总结了下面几个可行的方法:
    1 ,所有变量都尽量单独显式定义并赋值,美其名曰初始化。
    2 ,能不写在一行的,尽量不写在一行。
    3 ,能封装成函数的,尽量封装成函数,既增加行数,还增加复杂度。
    4 ,tkinter 写的窗口什么的,即使是有默认值,也单独拿出来重新赋值一下。

    效果也是有的,一个 200 多行的 Python 脚本干到了 500 行,但是还是不够,朋友的意思是,最好是随着老板提出的功能线性增加,这样符合他的预期。大家还有什么好办法,集思广益,帮帮他。

    第 1 条附言  ·  2023-12-01 14:29:15 +08:00
    建议提桶跑路和劝老板改 KPI 标准明显行不通的,现在工作市场什么情况大家都清楚,朋友大龄码农,6 月空档到现在,这个工作他当然也不满意,上有老下有小,有些事情也是身不由己,还是说点现实的吧。

    还有,这个也不算什么道德违规吧,保证功能完整,满足老板需求,自己利益最大化,没什么不对。道德上比那些搞医疗广告、App 偷个人隐私的还是高不少。
    102 条回复    2023-12-02 11:00:58 +08:00
    1  2  
    hangbale
        1
    hangbale  
       2023-11-30 15:19:43 +08:00   ❤️ 2
    轮子全部自己造
    maybedk
        2
    maybedk  
       2023-11-30 15:20:03 +08:00
    你不如把 import 的包都重新实现一下
    ModStart
        3
    ModStart  
       2023-11-30 15:31:15 +08:00   ❤️ 24
    不要用库,把库代码都拷贝进来重写一遍
    darkengine
        4
    darkengine  
       2023-11-30 15:33:27 +08:00   ❤️ 6
    把循环人工展开 。。。
    ljsh093
        5
    ljsh093  
       2023-11-30 15:35:09 +08:00   ❤️ 2
    @darkengine #4 你这个最逆天
    janwarlen
        6
    janwarlen  
       2023-11-30 15:36:35 +08:00   ❤️ 43
    《按代码行数来算这个功能的复杂程度和绩效》
    《他们老板和老板的朋友不傻》
    roundgis
        7
    roundgis  
       2023-11-30 15:38:24 +08:00 via Android
    換 java
    jrtzxh020
        8
    jrtzxh020  
       2023-11-30 15:38:27 +08:00
    老板的思路是,我提一个功能,朋友帮他实现。。。 都实现了,为什么还需要你朋友开发???
    coderwink
        9
    coderwink  
       2023-11-30 15:39:07 +08:00
    阿里系出来的吧
    chuckzhou
        10
    chuckzhou  
       2023-11-30 15:39:14 +08:00   ❤️ 3
    有这功夫不如多学点东西,提高自己换更好的工作,否则只能在这种 low 逼公司过一辈子了。
    iorilu
        11
    iorilu  
       2023-11-30 15:40:01 +08:00   ❤️ 2
    有个好方法, 你搜下 cython , 可以将 python 转为 c 代码模块, 然后 python 程序照样调用, 不用改

    结果就是 100 行变几千行 c 代码
    wumou
        12
    wumou  
       2023-11-30 15:40:28 +08:00
    多写一些不会被调用的方法
    krixaar
        13
    krixaar  
       2023-11-30 15:41:00 +08:00
    有需要存储数据和配置的需求的话,往数据库里写(本地就 sqlite 啥的),哪怕存个按钮状态,都用 SQL 操作,不要 context manager ,存个东西取个东西一堆 connect/cursor/prepared statement/close ,建库无限追求三范式,取个数据 join 一堆一个 join 一行,不搞成一个函数全部复制粘贴 DO Repeat Yourself 也是 DRY 原则
    Narcissu5
        14
    Narcissu5  
       2023-11-30 15:41:08 +08:00
    #1 正解,不使用任何第三方库,排序都自己写
    raycool
        15
    raycool  
       2023-11-30 15:41:42 +08:00
    这个问 GPT4 ,对于写好的函数让 gpt4 增加行数
    lambdaq
        16
    lambdaq  
       2023-11-30 15:42:06 +08:00
    那还说啥?用库啊。直接 vendor 到项目里。时不时还改一下库的内部实现。
    gxy2825
        17
    gxy2825  
       2023-11-30 15:52:38 +08:00
    #1 +1 ,能造轮子绝不用现成的轮子,问就是效率更高
    cambria
        18
    cambria  
       2023-11-30 15:54:50 +08:00   ❤️ 6
    Python ?在每一个函数里增加足够多的数据校验和异常处理,任谁都挑不出毛病。
    masterclock
        19
    masterclock  
       2023-11-30 15:56:19 +08:00
    2 楼正解
    Goooooos
        20
    Goooooos  
       2023-11-30 15:57:07 +08:00
    调用每个方法都加个 try expect 包裹
    SenLief
        21
    SenLief  
       2023-11-30 15:58:18 +08:00
    这个很容易啊,把包重新实现一下就好了。
    zhixi
        22
    zhixi  
       2023-11-30 16:01:07 +08:00   ❤️ 3
    @Goooooos 那我觉得不如直接学某大道至简的语言,直接扔上去满屏的

    err := xxxxxx
    if err != nil {

    }
    yph007595
        23
    yph007595  
       2023-11-30 16:01:10 +08:00
    @jrtzxh020 #8 这里的’朋友‘是指 up 主的朋友,而非老板的朋友
    secpool
        24
    secpool  
       2023-11-30 16:04:28 +08:00
    我能说我才帮老板写了脚本 统计 gitlab 所有人的代码提交量吗?😂
    weiwenhao
        25
    weiwenhao  
       2023-11-30 16:12:08 +08:00
    我最近写 golang 就想到这个问题,如果统计代码行数,golang 绝对是最多的。if err + log 至少占了代码量的一半。

    写 python 也可以,方法的开始写个 log, 结束写个 log, 每个 if 里面也写个 log 这样也可以增加代码行数。
    Rebron1900
        26
    Rebron1900  
       2023-11-30 16:23:46 +08:00
    @iorilu 好家伙,指了条明路
    Kinnice
        27
    Kinnice  
       2023-11-30 16:28:07 +08:00
    每一个函数都实现单独一个 class , class 中把所有的魔法函数都 rewrite 一下,最少也得打个日志之类的。
    使用的 的时候必须 x = funcClass() x.init() x.func() x.clean() x.exit()
    ZXiangQAQ
        28
    ZXiangQAQ  
       2023-11-30 17:42:43 +08:00
    @zhixi 好思路,err 处理时顺便打印下日志,日志使用结构化,然后每个属性单独起一行,绝对够行数,类似
    jianchang512
        29
    jianchang512  
       2023-11-30 17:49:52 +08:00
    1. 把用到的内置函数都统统再封装一层
    2. 写一堆用不到的复杂算法
    3. 能用 if 就不要用 for while
    killva4624
        30
    killva4624  
       2023-11-30 18:41:19 +08:00   ❤️ 1
    我贡献一个思路:把 lint 工具的每行最大长度减少,比如 PEP 是 79 ,改成 70 或者 65 ,甚至 50
    param
        31
    param  
       2023-11-30 19:08:56 +08:00 via Android   ❤️ 1
    所有入参都判断一下类型,不对就抛异常
    littlewing
        32
    littlewing  
       2023-11-30 19:17:28 +08:00
    离职
    Chuckle
        33
    Chuckle  
       2023-11-30 19:58:21 +08:00
    库拿出来二次封装很合理吧,瞬间代码量就爆炸了
    louisxxx
        34
    louisxxx  
       2023-11-30 20:19:53 +08:00
    if record['name'] in ["zhang", "liu", "wang", "wu", "le", "liu"]:
    a = a +1

    改成

    if record['name'] == 'zhang':
    a = a + 1
    if record['name'] == 'liu':
    a = a + 1
    if record['name'] == 'wang':
    a = a + 1
    if record['name'] == 'wu':
    a = a + 1
    if record['name'] == 'le':
    a = a + 1
    if record['name'] == 'liu':
    a = a + 1
    mylifcc
        35
    mylifcc  
       2023-11-30 20:27:49 +08:00
    上 pydantic 写几个元类就行了
    iOCZS
        36
    iOCZS  
       2023-11-30 20:48:28 +08:00
    不要以身犯险,有违职业道德,待遇觉得不行,你可以干一段时间跑路。但是务必做好自己的本职工作。
    thinkm
        37
    thinkm  
       2023-11-30 20:51:44 +08:00
    不要用循环
    Bigscience
        38
    Bigscience  
       2023-11-30 20:57:16 +08:00
    建议换老板
    自己人为故意地堆答辩代码,损人害己,建议远离这种不合理的绩效规则
    llsquaer
        39
    llsquaer  
       2023-11-30 20:59:50 +08:00
    import 的库都是深度封装的。你就拆散,按照需要的内容自己封装一次。。即阅读了源码,也自己实现了一遍简易功能,还令老板开心,简直三丰收。

    第二种,GitHub 上随便抄几百行代码,copy 到自己项目里。然后加一个 try....。为了 IDE 乱标红,就对应的在前面加一些变量初始化下。完美解决。
    test0x01
        40
    test0x01  
       2023-11-30 23:52:53 +08:00 via Android   ❤️ 4
    各种 exeption 考虑周全,把 log 也多打一点。既不失水准,方便调试,又增加行数
    garipan
        41
    garipan  
       2023-12-01 01:03:02 +08:00
    你这个需求,ChatGPT 4 应该可以完美满足
    corcre
        42
    corcre  
       2023-12-01 08:17:24 +08:00
    老板怎么统计行数呢, 如果是在 git 那些工具统计的话自己写个格式化工具没事就改一下换行条件能显著提升代码更改行数🐶
    bianhui
        43
    bianhui  
       2023-12-01 08:33:00 +08:00
    为了一个函数,把别人开源项目搬进来
    wangtian2020
        44
    wangtian2020  
       2023-12-01 09:20:58 +08:00
    像我是总是忍不住把 JavaScript 写的尽可能短肯定忍不了,一天就跑路
    angryfish
        45
    angryfish  
       2023-12-01 09:21:02 +08:00
    1.能不用第三方库就不用,自己写,自己实现
    2.多做防御性判断,异常处理能多完善就多完善
    3.多打 log
    4.多用设计模式,各种秀既能
    wangtian2020
        46
    wangtian2020  
       2023-12-01 09:23:49 +08:00
    戒备心强到连开发人员不信任,搞乱七八糟的开会报告,肯定到时候有利润也不会分享给员工,员工当个可替换的工具人。生活只要给我留一口气,这样的公司我就不可能待的
    McZoden
        47
    McZoden  
       2023-12-01 09:42:48 +08:00
    把所有的迭代器遍历,修改为 c 语音风格的 while ,i++
    例如:

    list = [1, 2, 3, 4, 5]
    for i in list: ...

    修改为

    i = 0
    while i < len(list):
    ...
    i += 1

    针对所有的可迭代对象:列表,字典,生成器
    isSamle
        48
    isSamle  
       2023-12-01 09:51:35 +08:00   ❤️ 3
    1.把库拉下来本地自封装:美其名曰脱离网络/版本依赖
    2.所有的逻辑加上诸如“操作记录”,“访问 IP”,“权限判定”,“调用日志”之类的数据记录和管理:美其名曰增强安全管理
    3.命名使用全拼长蛇形链:美其名曰见名知意
    4.所有逻辑加上各种异常校验诸如“有无权限”,“调用是否正常”,“异常原因分类 401/402/403/404…”:美其名曰便于测试维护
    5.尽可能都去构造类,有无必要都再继承后复写相关变量/方法作为新的子类:美其名曰面向对象
    CodeCodeStudy
        49
    CodeCodeStudy  
       2023-12-01 10:18:19 +08:00
    增加代码行数是 java 的看家本领,各种 getter, setter 就已经代码满天飞了
    tangtang369
        50
    tangtang369  
       2023-12-01 10:33:23 +08:00
    所有功能都面向对象 用类封装 每个类的魔法方法(__init__,__new__,__del__,__str__,__repr__,__call__)统统来一遍
    ma836323493
        51
    ma836323493  
       2023-12-01 10:37:26 +08:00
    简单, 用到的轮子, 把轮子源码都拷到项目里面,就成自己的了
    leaflxh
        52
    leaflxh  
       2023-12-01 10:41:42 +08:00
    学 Java 的写法,类中变量的访问和赋值全用 getter 和 setter
    pangdundun996
        53
    pangdundun996  
       2023-12-01 10:45:59 +08:00
    我的建议是准备跑路,不要在这种事上浪费生命
    chengdonghui
        54
    chengdonghui  
       2023-12-01 10:56:24 +08:00
    糊弄了领导的同时,也糊弄了自己
    RockShake
        55
    RockShake  
       2023-12-01 11:05:56 +08:00
    不引用第三方库,直接把第三方库的代码集成到代码中,这量不就起来了么
    43n5Z6GyW39943pj
        56
    43n5Z6GyW39943pj  
       2023-12-01 11:06:04 +08:00
    跑路
    Alexsen
        57
    Alexsen  
       2023-12-01 11:10:32 +08:00
    数据校验和异常处理,再打个日志
    F7TsdQL45E0jmoiG
        58
    F7TsdQL45E0jmoiG  
       2023-12-01 11:11:36 +08:00
    典型的互相伤害
    ztxcccc
        59
    ztxcccc  
       2023-12-01 11:12:35 +08:00
    @janwarlen #6 老板的朋友可能真不傻,而是不知道按行定 KPI
    Donahue
        60
    Donahue  
       2023-12-01 11:13:41 +08:00
    换老板
    aosan926
        61
    aosan926  
       2023-12-01 11:14:27 +08:00
    visper
        62
    visper  
       2023-12-01 11:17:38 +08:00
    把现在的方法写成 class, 功能放 class 里面。抽象出 10 层继承,美其名曰为了以后的扩展性。每一层里面又可以复制一次这个每一个方法,然后改一点或者一些层的留空。
    crayygy
        63
    crayygy  
       2023-12-01 11:21:17 +08:00
    一个孤僧独自归,关门闭户掩柴扉。
    半夜三更子时分,杜鹃谢豹啼子规。
    Rehtt
        64
    Rehtt  
       2023-12-01 11:22:55 +08:00
    那我上周提交了 4w 行代码岂不是无敌🤣
    xz410236056
        65
    xz410236056  
       2023-12-01 11:34:43 +08:00
    pip install 以后就禁用了,for 也禁用了。 当然这工作不要自己做,代码写完后扔 gpt 搞,顺便让他再改改
    stillsilly
        66
    stillsilly  
       2023-12-01 11:37:51 +08:00
    3 ,能封装成函数的,尽量封装成函数,既增加行数,还增加复杂度。

    并不是。
    函数能更好地抽象,少暴露细节,降低复杂度。能减少重复代码,减少行数。
    同一个功能,我的代码量会比我的同事们的少很多,因为我有很多个简短的函数可以复用
    vagusss
        67
    vagusss  
       2023-12-01 11:43:44 +08:00
    引用第三方库的时候, 把源码拷贝出来当成自己的代码,靠谱
    Felldeadbird
        68
    Felldeadbird  
       2023-12-01 11:57:14 +08:00
    建议尽早提桶走人。趁着年轻换一个好点的技术公司更好。把写代码的心思放在这种奇葩事情上,职业生涯污点啊。

    楼上各位大佬的方案都可行。
    InDom
        69
    InDom  
       2023-12-01 12:00:10 +08:00
    var name = 1
    改成

    class name {
    var name = 1
    func set (val) {
    name = val
    }
    func get(){
    return val

    }
    }
    virusdefender
        70
    virusdefender  
       2023-12-01 12:06:56 +08:00
    写个 wrapper ,里面捕获异常,然后返回 (data, error)

    然后 if err is not None: xxx
    chinesehuazhou
        71
    chinesehuazhou  
       2023-12-01 12:08:35 +08:00 via Android
    杀敌一千,自损八百。敷衍了老板,却污染了自己
    dnfQzjPBXtWmML
        72
    dnfQzjPBXtWmML  
       2023-12-01 12:13:14 +08:00
    函数参数尽量改成*args, **kwargs
    xuanbg
        73
    xuanbg  
       2023-12-01 12:29:56 +08:00
    最简单的做法就是复制开源库的代码。
    zypy333
        74
    zypy333  
       2023-12-01 12:46:10 +08:00
    如果有类似的功能,不要复用代码,拷贝改一份,多来几遍就非常酸爽了
    jones2000
        75
    jones2000  
       2023-12-01 13:00:40 +08:00
    把通用的方法,或函数, 或第三方的独立出来,封装成统一的一套函数。 项目开发完成以后,把源码里面的这些函数替换成源码就可以了。
    hlwjia
        76
    hlwjia  
       2023-12-01 13:34:19 +08:00
    @darkengine hahhahahahah 这个太牛逼了
    hlwjia
        77
    hlwjia  
       2023-12-01 13:37:08 +08:00
    @ModStart 这个其实挺好,顺便提升了自己的技术
    hlwjia
        78
    hlwjia  
       2023-12-01 13:37:43 +08:00
    数据库自己实现一个
    dragondove
        79
    dragondove  
       2023-12-01 13:38:07 +08:00
    年初的时候刚好某群举办了一个活动写九九乘法表,我把代码最长的那一位的源码放这里,供参考
    https://github.com/InvoluteHell/NineNineTable/blob/master/HisAtri/%E4%BD%86%E6%B1%82%E6%9C%80%E5%A4%A7.py
    当然,你也可以参考这个 java 版本的,自己定义类型,不过这个不够逆天
    https://github.com/InvoluteHell/NineNineTable/blob/master/Luorenmu/main.java
    如果你想要更加复杂,代码行数多的同时保证“企业级”质量,可以参考企业级 java hello world 编写样例
    https://github.com/Hello-World-EE/Java-Hello-World-Enterprise-Edition/tree/master/src/com/example
    aborigine
        80
    aborigine  
       2023-12-01 13:39:08 +08:00
    过度封装以及重复造轮子
    janus77
        81
    janus77  
       2023-12-01 13:46:41 +08:00
    不要用高阶语法,能写 if 都写 if ,不要用简化语法
    不要重用,本来可以重用的方法都直接拷贝一份出来
    多做判空,多做异常捕获,就算这里几行代码是 100%不为空,你也加个判空。这样也有好处是可以减少 bug ,而且提高了代码量
    vivisidea
        82
    vivisidea  
       2023-12-01 14:00:55 +08:00
    说服老板不要用这种方式来搞,对双方都没意思
    可以找几个例子,去说明这种方式的不合理, 比如

    1. 本来可以调用一个库函数的,对比自己实现一遍
    2. 本来可以很简单的一个策略模式设计,对比写一大堆 if-else 实现
    hevi
        83
    hevi  
       2023-12-01 14:04:10 +08:00
    何必浪费生命呢,去做些有意义的事情不好吗

    就为了讨好资本家吗
    echoyangjx
        84
    echoyangjx  
       2023-12-01 14:04:13 +08:00
    6 哇
    knightgao2
        85
    knightgao2  
       2023-12-01 14:15:17 +08:00
    换个不傻的老板
    aijam
        86
    aijam  
       2023-12-01 14:15:39 +08:00
    提供一个思路: https://gist.github.com/lolzballs/2152bc0f31ee0286b722
    既不容易被抓,看起来还专业
    godall
        87
    godall  
       2023-12-01 14:31:54 +08:00
    @aijam 哈哈完全正确,利用设计模式造一个 helloworld 实现类,看起来专业高大上,实际上就是狗屎!

    话说设计模式是不是就是脱裤子放屁? c/c++时代根本没有这个,自从 java 后就出现这坨屎了。
    shijingshijing
        88
    shijingshijing  
    OP
       2023-12-01 14:37:12 +08:00
    目前看下来:
    1 ,多加 try... excep...是可行的,特别是涉及用户输入,文件访问,网络连接相关的功能,可以猛搞,而且显得专业,考虑周到。
    2 ,封装成 Class 也会大幅增加代码数量,但是感觉需要改动的地方可能有点多,后续如果老板有大功能,重构的话倒是可以考虑。
    3 ,适当自己造轮子这个已经弄过了,有部分输出 xml 就是 writeline 搞的,复杂的还是用标准库的 ElementTree ,程序复杂度有提升,估计后面接手的人看了会皱眉。

    大家继续集思广益,我弄好了一起 Append ,也给有类似需求的人参考。coders help coders.
    8bryo4p5qn758Dmv
        89
    8bryo4p5qn758Dmv  
       2023-12-01 14:44:35 +08:00
    @hangbale #1 就是,标准库全部自己写一遍不就完了
    IsQian
        90
    IsQian  
       2023-12-01 14:51:37 +08:00
    @aijam 这真的只是 helloworld 嘛。。。
    dbus
        91
    dbus  
       2023-12-01 15:23:57 +08:00
    没写过 python ,不知道能不能加测试用例
    013231
        92
    013231  
       2023-12-01 15:32:10 +08:00
    @godall 我怎么记得 GoF 的 Design Patterns 里用的就是 C++?
    leimao
        93
    leimao  
       2023-12-01 15:36:37 +08:00 via iPhone
    @darkengine pragma unroll
    iosyyy
        94
    iosyyy  
       2023-12-01 15:51:01 +08:00
    @hlwjia #77 抄代码不会提升你任何技术
    shyangs
        95
    shyangs  
       2023-12-01 16:02:49 +08:00
    @godall
    @013231

    Advanced C++ Programming Styles and Idioms 初版年份 1991
    Design Patterns: Elements of Reusable Object-Oriented Software 初版年份 1994

    C++ 的設計模式出現的時間比 Java 早,笑嘻了.
    error451
        96
    error451  
       2023-12-01 16:05:12 +08:00
    所有运算符,所有常用函数都是可以自己重写的。
    比如 * 自己用循环累加的方式重写
    len() 自己去计算数组大小
    各种排序函数全部自己写
    所有可以自动迭代的,都自己写迭代器
    所有装饰器都不要用, 自己写
    想 with 这种语法糖都不要用,自己写关闭

    什么包调用,函数调用根本不存在的, 每次都重新写一遍
    cutecore
        97
    cutecore  
       2023-12-01 16:05:19 +08:00
    单元测试,设计模式
    jesusjiang
        98
    jesusjiang  
       2023-12-01 16:25:08 +08:00 via Android
    建立离职,别害人!
    jesusjiang
        99
    jesusjiang  
       2023-12-01 16:26:05 +08:00 via Android
    建议离职,别害人
    bill110100
        100
    bill110100  
       2023-12-01 16:35:55 +08:00
    别太过分了,照着库,改改变量名,都抄进来就好了,这就能让代码量膨胀好几倍,别把老板当傻子。
    1  2  
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1123 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 18:54 · PVG 02:54 · LAX 10:54 · JFK 13:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.