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

Python3 列表能被闭包函数使用,整数变量却不行呢?

  •  
  •   DuDuDu0o0 · 2022-04-20 18:44:30 +08:00 · 1645 次点击
    这是一个创建于 952 天前的主题,其中的信息可能已经有所发展或是发生改变。

    问题:

    最近在使用 python3 刷题,发现一个比较奇怪的现象,想用闭包的特性去使用一个外层作用域的变量,如果这个变量是 list 的话,则 ok ,非 list 就会报错,我需要怎么做才可以闭包使用整数变量呢

    如下面 ide 截图这样: https://imgtu.com/i/LsNiB8

    代码如下:

    class Solution:
        def isValidBST(self, root: TreeNode) -> bool:
            pre = -sys.maxsize -1
            o = []
            def trace(root) -> bool:
                if not root:
                    return True
                if not trace(root.left): return False
                o.append(root.val) # 为什么 list 可以被闭包进来
                if pre >= root.val: # 但是整数变量却不行呢?
                    return False
                else:
                    pre = root.val
                if not trace(root.right):return False
                return True
    
            return trace(root)
    
    
    
    
    6 条回复    2022-04-21 09:13:41 +08:00
    eurekavip
        1
    eurekavip  
       2022-04-20 18:52:04 +08:00
    python 里面赋值会自动变成局部变量,你的 else 里面有赋值操作:pre = root.val
    DuDuDu0o0
        2
    DuDuDu0o0  
    OP
       2022-04-20 18:55:42 +08:00
    @eurekavip 感谢,我把 pre = root.val 注释之后确实没报错了,
    有什么办法能在 闭包里 对外面的变量赋值呢?难道只能 read ?
    pursuer
        3
    pursuer  
       2022-04-20 18:58:43 +08:00
    使用 nonlocal 引入外部变量
    LeeReamond
        4
    LeeReamond  
       2022-04-20 22:23:02 +08:00   ❤️ 3
    这是语言特性,具体问题就是子 block 对父 block 中资源的处理方案,各个语言对这三点的处理不尽相同,一般的三个问题是 1 、能否感知,2 、能否读取,3 、能否修改。

    就 python 来说是能感知和读取,修改的话会创建副本,所以父 block 不用担心变量被子 block 或调用乱改。可能有一些考量在,虽然目前我个人来说更喜欢闭包可以全权修改的方案。

    解决方案一般是 nonlocal 或者传递指针,传递指针是指传进子 block 的是对象或者[0,],子 block 中用 item.property += 1 或者 item[0] += 1 的方式修改。nonlocal 效率更高,不过传指针更灵活一些,性能其实倒是不太有所谓,python 列表单次寻址耗时大概是 20 纳秒左右,在绝大多数场景中这并不是值得在意的开销。
    stimw
        5
    stimw  
       2022-04-21 01:11:41 +08:00 via iPhone
    我的 c++只用来刷题。。🐶
    cheng6563
        6
    cheng6563  
       2022-04-21 09:13:41 +08:00
    你套个 list 就行了,只有一个变量的 list 。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3128 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 13:45 · PVG 21:45 · LAX 05:45 · JFK 08:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.