zoukankan      html  css  js  c++  java
  • 零基础学python-16.6 嵌套作用域

    这一章节我们来讨论一下嵌套作用域

    1.简介

    例子:

    >>> x=1
    >>> def test()
    SyntaxError: invalid syntax
    >>> def test():
    	x=2
    	def test2():
    		print(x)
    	test2()
    	print(x)
    
    	
    >>> test()
    2
    2
    >>> x
    1
    >>> 


    从上面的例子可以看见,test()和test2()方面里面的print都是打印test()方法里面定义的x,而没有涉及到函数外的x,这是根据前面说的LEGB原则

    我们再来看下面的代码,这次我们直接把里面的临时函数映射出来

    >>> def test():
    	x=2
    	def test2():
    		print(x)
    	test2()
    	print(x)
    	return test2
    
    >>> fn2=test()
    2
    2
    >>> fn2()
    2
    >>> 


    虽然test()执行后test不在激活状态,但是fn2映射了里面的test2(),所以当执行fn2的时候,还是可以的

    2.工厂函数

    工厂函数:指的是可以记住嵌套作用域的变量值的函数

    注意:我们这里不推荐这种方式,比较推荐的方式是通过类来记忆状态,比较明了清晰

    >>> def maker(n):
    	def action(x):
    		return x**n
    	return action
    
    >>> f=maker(2)
    >>> f(2)
    4
    >>> f(3)
    9
    >>> g=maker(3)
    >>> g(2)
    8
    >>> g(3)
    27
    >>> 


    我们从上面的代码可以看见,虽然maker已经不再是激活状态,但其实他里面的变量n是激活状态的,f记住了n的状态,然后后面的计算都有n的参与,g同理

    像这种方式非常少见,一般使用在函数式编程和lambda表达式里面,还是再次提醒,处于维护等原因考虑,这种方式不推荐,还是推荐使用类或者公共参数记录某个变量的状态

    其实,上面的代码可以改成下面的形式,这样使用起来更加清晰,维护的代价也降低

    >>> def maker(x,n):
    	return x**n
    
    >>> maker(2,2)
    4
    >>> 


    基本是等价使用的

    3.嵌套作用域与lambda

    lambda表达式:像def一样调用一个函数,但是它只是一个表达式,因此他可以使用在列表等常量当中

    我们下面再把maker改造:

    >>> def maker():
    	x=2
    	action = (lambda n: x**n)
    	return action
    
    >>> x=maker()
    >>> x(3)
    8
    >>> 


    通过lambda表达式,简化了嵌套函数

    4.任意嵌套

    >>> def test():
    	x=0
    	class a:
    		x=1
    		def a1(self):
    			print('a.a1:'+str(x))
    	def test2():
    		x=2
    		print('test2:'+str(x))
    	a().a1()
    	test2()
    
    	
    >>> test()
    a.a1:0
    test2:2


    这里出现一个还没有弄明白的问题,为什么里面嵌套的类不是读取自己的x,而读取外面的x?

    因为test里面的a在test创建的时候a同步创建,因此a里面所定义的x先执行,然后再执行a.a1,这个时候x已经被替换了

    总结:这一章节简单讨论了嵌套作用域、嵌套作用域与工厂函数、嵌套作用域与lambda、嵌套作用域的任意嵌套

    这一章节就说到这里,谢谢大家

    ------------------------------------------------------------------

    点击跳转零基础学python-目录

     

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    Java中printf
    error C3688: invalid literal suffix '__FSTREXP'; literal operator or literal operator template 'operator ""__FSTREXP' not found
    C# IIS 访问网络映射磁盘 读取文件列表
    datatables 参数详解
    Telnet协议详解
    WCF中的ServiceHost初始化两种方式
    C# FTP 上传、下载、获取文件列表
    Oracle存储过程编译卡死的解决方法
    oracle 查询表结构
    Oracle大数据常见优化查询
  • 原文地址:https://www.cnblogs.com/raylee2007/p/4896736.html
Copyright © 2011-2022 走看看