Python作用域

python代码内部块如if语句内声明变量,在if代码段后在调用此变量并未报如“undefinded name"此类错误,例子如下:

if 1 == 1:
name = 'Jason'
print(name) ##result
Jason

如果在java和c#中,会抛出异常,而在python和javascript中均无报错,这正是因为python和javascript中无块级作用域。

  • 在有块级作用域的语言中,比如java/c#,代码中的name只在当前作用域下生效。
  • 在没有块级作用域的语言中,比如python/javascript中,代码中的name变量,不仅在代码块中生效,在代码块外面也一样生效

python中函数中定义变量,函数执行后,外部调用,是怎样的情况呢?例子如下:

def func():
name = 'Jason' func()
print(name) ##result
print(name)
NameError: name 'name' is not defined

在函数的作用域中,变量无法生效的。

python中有作用域链,对于变量的查找方式是由内向外查找的,当前作用域中有,使用当前变量设置,如果没有,往外查找,直到找到最后找不到而报错。

看个例子能更为直观些:

name='outer'
def f1():
name='f1'
def f2():
name = 'f2'
print(name)
f2()
f1() ##result
f2

按照上面所说的查找规则,先从f2中查找name,f2中name的值为f2,正如执行结果,若果f2内没有name变量,则向外查f1内是否有,若没有则在f1外查找,找到为止,未找到则报错

python/javascript中作用域与函数的关系

对于作用域来说,在函数没有执行之前,他的作用域、作用域链均已经确定。
看下例子:

name = 'Jason'

def f2():
name = 'eric'
f1()
def f1():
print(name)
f2()
##result
Jason
def f1():
print(name)
def f2():
name = 'eric'
return f1
ret = f2()
ret()
##result
Jason
以上两段代码,执行结果一致,这是Python一个很容易掉进的坑,在作用域1中,作用域会直接用使用全局变量name='Jason',但在作用域2中,虽然有一个局部变量name,但在程序最终执行之前,python已经从上到下把作用域和作用域链确定了,就是f1()的执行结果肯定是Jason,不受其他因素的影响。
 

Python特殊用法tip

li=[x+100 for x in range(10)]   #在0-9循环,并且每次循环+100
print(li)
lis=[x+100 for x in range(10) if x > 6] #只有x>6时,x+100
print(lis) li1=[lambda: x for x in range(10)] #首先li是一个列表,列表中的元素都是函数
print(li1)
# print(type(li1))
r=li1[0]() #函数加括号执行lambda表达式
print(r) #最后x为9,所以每个元素都是return 9
output:
[100, 101, 102, 103, 104, 105, 106, 107, 108, 109]
[107, 108, 109]
[<function <listcomp>.<lambda> at 0x0000019EC393D598>, <function <listcomp>.<lambda> at 0x0000019EC393D620>, <function <listcomp>.<lambda> at 0x0000019EC393D6A8>, <function <listcomp>.<lambda> at 0x0000019EC393D730>, <function <listcomp>.<lambda> at 0x0000019EC393D7B8>, <function <listcomp>.<lambda> at 0x0000019EC393D840>, <function <listcomp>.<lambda> at 0x0000019EC393D8C8>, <function <listcomp>.<lambda> at 0x0000019EC393D950>, <function <listcomp>.<lambda> at 0x0000019EC393D9D8>, <function <listcomp>.<lambda> at 0x0000019EC393DA60>]
9

python lamda函数用于定义一些简单函数,如加减等,例子如下:

def lambda():
return x
##li中lambda函数只是如上面定义的函数,返回x,与后面的for循环无直接联系,当for循环结束后,x值为9,付给lambda函数,最终li列表的第一个值为9
li = [lambda :x for x in range(10)]

其实把他拆开,我们可以这么写一行:

li = []
for i in range(10)
def f1():
return i
li.append(f1)
print(li[1]())
##result
9
首先for 循环已完成,i已经赋予9,然后f1()执行时,按照作用域链查找,i=9,那么返回就是9了。
那么如果对f1中的x赋值会怎样:
li = []
for i in range(10)
def f1(x=i):
return x
li.append(f1)
print(li[0]())
print(li[1]())
print(li[2]())

output:

0
1
2

为什么呢,因为x=i是一个表达式,表达式是执行了函数。所以还是要看他的本质,要看函数是否被执行

总结
总结下这篇的重要的三句话吧: python中是以函数作为作用域的,并且python中无块级作用域
对于作用域来说,在函数没有执行之前,他的作用域、作用域链均已经确定。,并且:对于变量的查找方式是由内向外查找的,当前作用域中有,使用当前变量设置,如果没有,往上查找,知道找到最后找不到而报错。
函数在没执行前,内部代码不执行。在碰到lambda时候需要注意!!!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Python基础知识补充(重要)-作用域、特殊语法的更多相关文章

  1. 万恶之源 - Python基础知识补充

    编码转换 编码回顾: 1. ASCII : 最早的编码. ⾥⾯有英⽂⼤写字⺟, ⼩写字⺟, 数字, ⼀些特殊字符. 没有中⽂, 8个01代码, 8个bit, 1个byte 2. GBK: 中⽂国标码, ...

  2. python基础知识07-函数作用域和匿名函数

    1.匿名函数 list(filter(lamda a:a>3,[1,2,3,4,5])) 一般和过滤器一起使用 2.函数的作用域 a = 123 def test(): a = 666 a = ...

  3. python基础知识补充

    set 集合 {} 无序 集合天然去重 增 : s.add s.update 迭代添加 删 : s.pop( ) 随机删除 返回删除值 s.clear( ) 清空 获取到的是 set( ) del s ...

  4. 十一. Python基础(11)—补充: 作用域 & 装饰器

    十一. Python基础(11)-补充: 作用域 & 装饰器 1 ● Python的作用域补遗 在C/C++等语言中, if语句等控制结构(control structure)会产生新的作用域 ...

  5. python基础知识小结-运维笔记

    接触python已有一段时间了,下面针对python基础知识的使用做一完整梳理:1)避免‘\n’等特殊字符的两种方式: a)利用转义字符‘\’ b)利用原始字符‘r’ print r'c:\now' ...

  6. Python基础知识总结笔记(四)函数

    Python基础知识总结笔记(四)函数python中的函数函数中的参数变量作用域偏函数PFA递归函数高阶函数BIFs中的高阶函数匿名函数lambda闭包Closure装饰器Decorator函数式编程 ...

  7. python基础知识(二)

    以下内容,作为python基础知识的补充,主要涉及基础数据类型的创建及特性,以及新数据类型Bytes类型的引入介绍

  8. python 基础知识(一)

    python 基础知识(一) 一.python发展介绍 Python的创始人为Guido van Rossum.1989年圣诞节期间,在阿姆斯特丹,Guido为了打发圣诞节的无趣,决心开发一个新的脚本 ...

  9. python 爬虫与数据可视化--python基础知识

    摘要:偶然机会接触到python语音,感觉语法简单.功能强大,刚好朋友分享了一个网课<python 爬虫与数据可视化>,于是在工作与闲暇时间学习起来,并做如下课程笔记整理,整体大概分为4个 ...

随机推荐

  1. knockout+weui+zepto

    主文件wxapp.ts 1>在ts中,建议继承componentui //操作菜单表 actionsheet showactionsheet { title 上拉菜单标题 btns 操作组 建议 ...

  2. 学习spring1--跟我一起学Spring 3(2)–开发环境配置

    http://www.importnew.com/13185.html#spring     首页 所有文章 资讯 Web 架构 基础技术 书籍 教程 我要投稿 更多频道 » - 导航条 - 首页 所 ...

  3. Servlet 环境设置

    开发环境是您可以开发.测试.运行 Servlet 的地方. 就像任何其他的 Java 程序,您需要通过使用 Java 编译器 javac 编译 Servlet,在编译 Servlet 应用程序后,将它 ...

  4. Spring MVC生成PDF文件

    以下示例演示如何使用Spring Web MVC框架生成PDF格式的文件.首先使用Eclipse IDE,并按照以下步骤使用Spring Web Framework开发基于动态表单的Web应用程序: ...

  5. MySQL中的聚合函数

    创建student表 CREATE TABLE IF NOT EXISTS `student` ( `id` int(4) unsigned NOT NULL AUTO_INCREMENT, `nam ...

  6. Android OpenCV集成摄像头图片动态识别车牌号

    最近两天开发一个使用OpenCV集成的一个识别车牌号的项目,困难重重,总结一下相关经验,以及开发注意事项: 一.开发环境: Android Studio 个人版本 3.1.4 NDK下载:14b CM ...

  7. 关于 UIWebView 的说明

    本文转载至 http://blog.csdn.net/cyforce/article/details/8487856 1.UIWebDocumentView 2.WebView 3. //====== ...

  8. c++包含头文件好还是重新定义好

    A.h struct A { int a; int b; }; B.cpp 在B.cpp里面用到这个结构体 有两种方法 .自己定义一个一模一样的结构体 struct A { }; .包含A.h头文件 ...

  9. iOS学习笔记(三)——iOS系统架构

    iOS的系统架构分为四个层次:核心操作系统层(Core OS layer).核心服务层(Core Services layer).媒体层(Media layer)和可触摸层(Cocoa Touch l ...

  10. solr删除数据(全删除)

    背景:数据索引错了,不想要了.也不想一条条删! 方法: 1.在solr客户端,访问你的索引库(我认为最方便的方法) 1)documents type 选择 XML 2)documents 输入下面语句 ...