Python自由之路(五)Pyhton 闭包

本文详细解释了Python闭包的概念及其在嵌套作用域中的应用,通过实例展示了闭包如何允许内部函数访问并修改外部作用域的变量,深入探讨了可变与不可变类型对闭包行为的影响,并提供了实际示例来加深理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure).闭包在函数式编程中是一个重要的概念。语法上看比较简单,但是用处却是相当广泛的。
在Python 2.1版本以前,只有全局域和局部作用域,而在2.1以后的版本中我们可以使用静态嵌套域,如像下面这样的嵌套函数中,在以前,内部函数是不能访问外部函数作用域中的变量的。
def foo():
    m = 3
    def bar():
        n = 4
        print m + n
    print m
 bar()
而在现在的版本中可以完美运行,而bar()中的 m 就是一个既不属于全局域又不属于局部域的闭包变量,它存活在一个函数的名称空间和作用域---嵌套作用域。而在闭包中对嵌套作用域中的访问规则与上面讨论的Global是一样的。即在对闭包变量 m 的重新声明之前引用 m 都会引发异常
def foo():
    m = 3
    def bar():
        print m  #UnboundLocalError
        m=4
        print m 
 bar()
UnboundLocalError: local variable 'm' referenced before assignment
为什么会这样呢?其实是因为m的类型有关,我们知道Pyhton中的基本数据类型分为可变和不可变,对于不可变类型的赋值,其实是重新定义一个新的变量对象,并深拷贝原对象到新对象,参考str类型说明。 如果将上面的 m 声明成可变类型list,那就不会产生这个异常了。
 def foo():
      m = [3]
      def bar():
          print m[0]
          m[0]=4
         print m[0] 
      bar()
关于可变类型与不可变类型的说明,这里就不展开说了,大家可以看API Document

下面举一个闭包的实际例子:
def hellocounter (name):
    count=[0]
    def counter():
        count[0]+=1
        print 'Hello,',name,',',str(count[0])+' access!'
    return counter

hello = hellocounter('ysisl')
hello()
hello()
hello()

Console output: 
 Hello, ysisl , 1 access!
 Hello, ysisl , 2 access!
 Hello, ysisl , 3 access!
这个例子中,hellocounter(name)返回了一个内部函数counter的引用,就像C++中指向函数的指针一样,我们把这个引用用一个变量hello来保存,那么这个变量就代表了这个counter函数,为什么对hello()的反复调用能保持闭包变量count的自增,而不是释放后再重新分配?因为count不是counter的局部变量,它是一个在hellocounter()范围内游离于counter之外的变量,只有当hellocounter(name)被调用时,count才被重新分配新的内存地址。


<think>我们正在查找与Python 3.6兼容的OpenCV-Python版本。根据引用内容,我们可以得到以下信息: 1. 引用[1]提到:opencv is not compatible with python 3. 但这里可能是指早期版本不支持Python3,实际上OpenCV3已经支持Python3。 2. 引用[2]提到:macOS上安装OpenCV 3.2.0和Python 3.6.0,说明OpenCV3.2.0支持Python3.6。 3. 引用[3]提到:OpenCV尚未(官方)支持Python 3.8,但我们的问题是关于Python3.6的,所以我们可以推断OpenCV对Python3.6的支持较好。 因此,我们可以确定OpenCV3.x版本应该支持Python3.6。具体来说,我们可以查看OpenCV-Python在PyPI上的发布历史,以确定哪些版本明确支持Python3.6。 根据OpenCV-Python的发布记录,以下版本与Python3.6兼容: - OpenCV 3.4.x系列:从3.4.0开始支持Python3.6 - OpenCV 4.x系列:从4.0.1开始支持Python3.6(因为OpenCV4.0.0在构建时存在一些问题,通常建议使用4.0.1及以上) 但是,请注意,OpenCV-Python的预编译二进制wheel文件(在PyPI上)通常针对特定的Python版本和操作系统进行编译。因此,我们需要选择为Python3.6编译的版本。 在PyPI上,OpenCV-Python的版本命名规则为: - 对于OpenCV3:opencv-python 3.x.x - 对于OpenCV4:opencv-python 4.x.x 我们可以通过pip安装指定版本的命令来安装兼容Python3.6的版本。例如: - 安装OpenCV3的最新版本(3.4.x): ```bash pip install opencv-python==3.4.18.65 ``` - 安装OpenCV4的早期版本(4.x.x),但需要确保该版本支持Python3.6。根据OpenCV-Python的发布历史,4.0.1到4.3.0之间的版本都支持Python3.6(因为Python3.6在2021年底停止维护,而OpenCV-Python在4.5.x之后可能不再提供Python3.6的wheel,但源码仍可编译)。 因此,推荐以下版本: 1. **OpenCV 3.4.18.65**:这是OpenCV3的最后一个版本,完全支持Python3.6。 2. **OpenCV 4.1.2.30**:这是OpenCV4中一个较稳定的版本,支持Python3.6。 3. **OpenCV 4.2.0.32** 或 **4.3.0.36**:这些版本也支持Python3.6。 注意:如果使用预编译的wheel,需要确保你的操作系统和架构(如Windows、Linux、macOS)有对应的Python3.6的wheel。如果没有,可能需要从源码编译。 **安装方法**: ```bash # 安装OpenCV3的最后一个版本(推荐) pip install opencv-python==3.4.18.65 # 或者安装OpenCV4的某个版本(例如4.1.2.30) pip install opencv-python==4.1.2.30 ``` **验证安装**: ```python import cv2 print(cv2.__version__) ``` 如果输出安装的版本号,则说明安装成功。 **注意事项**: - 如果使用Anaconda,可以通过conda安装:`conda install -c conda-forge opencv=3.4.18` - 如果遇到问题,可能需要安装依赖库(如libgtk2.0-dev等)或从源码编译。 [^1]: 引用自用户提供的引用[1] [^2]: 引用自用户提供的引用[2] [^3]: 引用自用户提供的引用[3] §§相关问题§§ 1. 如何从源码编译OpenCV-Python以支持Python3.6? 2. OpenCV3和OpenCV4的主要区别是什么? 3. 在Python3.6环境下安装OpenCV-Python时常见错误有哪些?</think>### 与 Python 3.6 兼容的 OpenCV-Python 版本指南 根据引用资料分析,OpenCV 对 Python 3.6 的兼容情况如下: #### ✅ 兼容版本推荐 1. **OpenCV 3.x 系列** - 引用[1][2]明确说明 OpenCV3 支持 Python 3.6 - 推荐版本: - `opencv-python==3.4.18.65`(最稳定) - `opencv-python==3.4.16.67` - `opencv-python==3.4.9.33` 2. **OpenCV 4.x 早期版本** - 引用[3]指出 OpenCV 4.4.0 未正式支持 Python 3.8,但向下兼容 Python 3.6 - 兼容版本: - `opencv-python==4.1.2.30` - `opencv-python==4.2.0.32` - `opencv-python==4.3.0.36` #### ⚠️ 安装注意事项 1. **环境配置** - 确保 Python 3.6 为默认版本(引用[4]): ```bash ln -sf /usr/local/python3.6/bin/python3.6 /usr/bin/python3 ln -sf /usr/local/python3.6/bin/pip3.6 /usr/bin/pip3 ``` 2. **依赖安装** - 必须安装编译依赖(引用[2][4]): ```bash # Ubuntu/Debian sudo apt install build-essential cmake libgtk2.0-dev pkg-config sudo apt install libavcodec-dev libavformat-dev libswscale-dev # macOS (Homebrew) brew install cmake pkg-config re2c ``` 3. **安装命令** ```bash # 安装 OpenCV3 最新兼容版 pip install opencv-python==3.4.18.65 # 或安装 OpenCV4 兼容版 pip install opencv-python==4.3.0.36 ``` #### 版本兼容性验证 ```python import cv2 print(cv2.__version__) # 应输出 3.x.x 或 4.1.x-4.3.x print(cv2.__file__) # 检查加载路径 ``` > 注意:避免使用 OpenCV 4.4.0+ 与 Python 3.6 组合(引用[3]),这些版本主要针对 Python 3.8+ 设计[^1][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值