一个关于作用域的吐槽 - 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
Aloento
V2EX    Python

一个关于作用域的吐槽

  •  1
     
  •   Aloento 2023-03-15 02:08:00 +08:00 3241 次点击
    这是一个创建于 1017 天前的主题,其中的信息可能已经有所发展或是发生改变。

    今天在看 Hifigan 的源码,突然发现 IDE 提示 ch 变量 warning

     self.resblocks = nn.ModuleList() for i in range(len(self.ups)): ch = upsample_initial_channel // (2 ** (i + 1)) for j, (k, d) in enumerate(zip(resblock_kernel_sizes, resblock_dilation_sizes)): self.resblocks.append(resblock(ch, k, d)) self.conv_post = Conv1d(ch, 1, 7, 1, padding=3, bias=False) self.ups.apply(init_weights) 

    局部变量 ch 可能在赋值之前使用

    首先说明本人不会 python ,今天看到这段百思不得其解

    询问 AI 也没问出个所以然,遂询问朋友

    得到了这样的回答:

    Python 的 for 不认为是作用域

    Python 没有语句块的概念

    最小作用域就是闭包或者函数

    知道这个以后我脑海中只有一句话

    真的是令人叹为观止

    25 条回复    2023-03-15 23:43:31 +08:00
    zhlxsh
        1
    zhlxsh  
       2023-03-15 02:34:01 +08:00 via iPhone
    局部变量 ch 可能在赋值之前使用

    这句话是说,在 for 循环结束后使用了 ch ?

    假设我理解没错,语言没有强制规定 for 循环作用域,代码跑起来没问题,编译器报语法错误。 那就是是写的人不规范
    KMpAn8Obw1QhPoEP
        2
    KMpAn8Obw1QhPoEP  
       2023-03-15 02:50:41 +08:00 via Android
    这…你可能没写过 JS ?
    KMpAn8Obw1QhPoEP
        3
    KMpAn8Obw1QhPoEP  
       2023-03-15 02:51:49 +08:00 via Android
    不对啊 你写过 JS 为啥会叹为观止…S6 之前不都这样吗
    KMpAn8Obw1QhPoEP
        4
    KMpAn8Obw1QhPoEP  
       2023-03-15 02:53:16 +08:00 via Android
    直接 var 或者连 var 都不写 就直接在 global 上定义属性才叫叹为观止…
    Aloento
        5
    Aloento  
    OP
       2023-03-15 03:00:39 +08:00
    @enchilada2020 我是直接从 ES6 开始学的 JS (不如说一来就用的 TS )
    然后写代码一直都是非常的规范,从来没用过黑魔法
    所以说虽然我知道 var 是全局,但是 python 这种连 var / let / := 也不需要的语言
    属实是超出了我的认知范围
    KMpAn8Obw1QhPoEP
        6
    KMpAn8Obw1QhPoEP  
       2023-03-15 03:02:24 +08:00 via Android
    @Aloento 哈哈 看看 ES6 之前的 JS 那才叫群魔乱舞的感觉 直接写规范 TS 是正确选择
    celerysoft
        7
    celerysoft  
       2023-03-15 03:19:32 +08:00
    如果 len(self.ups) == 0 ,for 循环没有执行,那 ch 就没有赋值,并且直接在 self.conv_post = Conv1d(ch, 1, 7, 1, padding=3, bias=False) 这里调用了,所谓的「局部变量 ch 可能在赋值之前使用」说的就是这种情况吧

    不过我有点不理解你吐槽的点,你是觉得 ch 应该在没有声明的情况下就能使用吗?还是说不习惯 Python 没有专门的词用于变量声明
    KMpAn8Obw1QhPoEP
        8
    KMpAn8Obw1QhPoEP  
       2023-03-15 03:25:17 +08:00 via Android
    @celerysoft 他吐槽的是 Python 没块作用域…
    fantasticfears
        9
    fantasticfears  
       2023-03-15 03:43:15 +08:00
    Python 没有块作用域。Python 没有块作用域。Python 没有块作用域。
    重要的事情说三遍
    celerysoft
        10
    celerysoft  
       2023-03-15 04:24:22 +08:00
    @enchilada2020 那我的确没理解 OP 的意思,如果在不知道 Python 没有块作用域的前提下来读这段代码,确实晦涩难懂
    xuanbg
        11
    xuanbg  
       2023-03-15 07:58:11 +08:00
    这个哪怕是 Java ,也一样会报这个警告。因为你在倒数第二行是用了 ch 变量,如果 self.ups 为空集合,ch 上哪去赋值呢?
    cmdOptionKana
        12
    cmdOptionKana  
       2023-03-15 08:18:14 +08:00
    Python 的作用域确实是比较与众不同,稍稍有点难用,并且没啥特别优点,我认为算是 Python 设计得比较差的一点。

    但日常使用也没啥大问题就是了。
    cbdyzj
        13
    cbdyzj  
       2023-03-15 08:21:29 +08:00
    Python 没有块作用域,C 、C++、Java 、Javascript 、C#、Rust 等主流语言都支持块作用域,PO 不清楚实属正常
    楼上说 ES3 也不支持块作用域的,现在是 2023 年
    darkengine
        14
    darkengine  
       2023-03-15 08:42:33 +08:00
    @xuanbg 换 Java 直接就编不过了
    xuanbg
        15
    xuanbg  
       2023-03-15 09:01:01 +08:00
    @darkengine 可以过的。但我怀疑 OP 贴的代码中最后两行代码的缩进不对,应该加两个空格,这样就不会有这个警告。并且,变量在使用逻辑上也能和上面的循环对应起来。
    hsfzxjy
        16
    hsfzxjy  
       2023-03-15 09:05:44 +08:00 via Android
    @xuanbg 缩进是对的,代码就是这样,相当于一种取巧的方式获得 ch 最后一个计算结果
    raymanr
        17
    raymanr  
       2023-03-15 09:15:42 +08:00
    这个还比较好理解吧,

    如果 len(self.ups) == 0 那么循环就不会执行,

    那么就会出现 ch 没有出现初始化的情况,

    应该会抛出 NameError 吧

    在循环前给 ch 一个初始化的值是更合理的做法

    这个是作者写得不规范的问题, 和 let var 之类的声明语句没关系, 反正没有声明也检查出这个问题了嘛
    bl4ckoooooH4t
        18
    bl4ckoooooH4t  
       2023-03-15 09:17:36 +08:00
    在 for i in range(len(self.ups)): 里面定义了 ch , 如果 len(self.ups) == 0 , 那么 ch 变量就不会被定义,这样就引用了未定义的变量。 应该是这样吧
    fbichijing
        19
    fbichijing  
       2023-03-15 09:39:31 +08:00
    平时写的时候好像倒没怎么在意这个问题。只是乍一看起来代码感觉好像不太自然。如果是我自己在写的话可能在 for 前面给 ch 初始化一下。
    好像许多编程语言 for 里面的局部变量都无法在 for 之外调用,如果 Python 确实这么做也可以的话,反而说明了使用变量前初始化的必要性。万一使用了一个自己前面定义过的变量,但是自己不记得了,这就会出现难以调试的 bug.
    pendulum
        20
    pendulum  
       2023-03-15 10:10:37 +08:00
    for 循环之前应该先初始化 ch ,因为 for 循环后又用到了 ch 。或者给 for 循环里面的 ch 加个 nonlocal
    proxytoworld
        21
    proxytoworld  
       2023-03-15 10:56:00 +08:00
    因为 python 不确定是不是一定进入 for 循环里面赋值(猜测)所以才会报这个错,如果你确保一定会进入的话可以忽略这个,毕竟编译器比较死板
    KMpAn8Obw1QhPoEP
        22
    KMpAn8Obw1QhPoEP  
       2023-03-15 11:11:01 +08:00 via Android
    @proxytoworld 这样做等于在埋坑 半年后你会忘了这个在代码里体现不出来的隐藏默认条件 之后如果因为某种原因这个条件被破坏了 那就是炸弹
    raymanr
        23
    raymanr  
       2023-03-15 11:11:39 +08:00
    @enchilada2020 我多年以前自学 js 的时候看到这里都吐了, 但凡变量名写错, 就变成了全局变量真的吐了, 加上其他各类坑问题风骚语法, 以至于很长时间里 Javascript 在我眼里就是混乱邪恶的语言代表....... 即便现在好了很多, js 这东西还是让我觉得能不碰就不碰的好
    KMpAn8Obw1QhPoEP
        24
    KMpAn8Obw1QhPoEP  
       2023-03-15 11:24:21 +08:00 via Android
    @raymanr 是很恶心 哈哈 偏偏它成了 Web 领域避不开的语言
    whileFalse
        25
    whileFalse  
       
    这不很正常吗,你 for 循环不一定会跑啊 万一 self.ups 是空数组呢
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1058 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 18:18 PVG 02:18 LAX 10:18 JFK 13:18
    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