python作用域

无函数的作用域

在python中没有块级作用域

什么叫块级作用域呢?先来看个例子:

if 1 == 1:
name= 'alex'
print(name)

运行结果为alex

在javascript、python中运行结果为alex,但是在java和C#中,会抛出异常:没有name的变量

for i in range(10):
name=i
print(name)

结果也是9

为什么会出现这种情况呢,归根结底就是因为块级作用域

在python中,一个tab或者空格缩进,表示一个代码块

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

python中以函数为作用域

再来看一下这个:

def fun():
name ='alex'
fun()
print(name)

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

总结1

所以我们可以总结一下:python中是以函数作为作用域的,并且python中无块级作用域

python中的作用域链

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

看个例子能更为直观些:

name='cc'
def f1():
name='alex'
def f2():
name='bb'
print(name)
f2()
f1()

输出:

bb

按照上面所述,查找name的方式就是从f2函数中查找,如果有就是bb,如果没有,就是f1中的alex,如果还没有就是cc,如果最外面的全局变量中也没有,那么程序必然会报错。

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

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

看下例子:

name = 'alex'
def f1(): #作用域1
print(name)
###################
def f2(): #作用域2
name='cc'
f1()
f2()
name = 'alex'
def f1(): #作用域1
print(name)
######################
def f2(): #作用域2
name = 'cc'
return f1
ret = f2()
ret()

上面两个输出均为alex

说下原因吧:我们已经知道了,python中是以函数为作用域的,在作用域1中,作用域会直接用使用全局变量name='alex',但在作用域2中,虽然有一个局部变量name,但在程序最终执行之前,python已经从上到下把作用域和作用域链确定了,就是f1()的执行结果肯定是alex,不受其他因素的影响。

python中的特殊语法

直接上例子吧,据说是一个新浪面试题:

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

输出结果:

[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中:函数在没执行前,内部代码不执行。

所以,我们在看li1=[lambda: x for x in range(10)],这行代码中,lambda:x是一个函数,函数内部x只是一个x变量,不会被赋值,而for x in range(10)的执行结果都是9;所以内部是10个lambda函数,而函数可以认为是lambda : x,但这个x其实已经赋予9的值了,但因为没有执行,暂时是x,加括号后就直接返回9.

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

li = []
for i in range(10)
def f1():
return i
li.append(f1)
print(li[1]())

首先for 循环已完成,i已经赋予9,然后f1()执行时,按照作用域链查找,i=9,那么返回就是9了。

那么:

li = []
for i in range(10)
def f1(x=i):
return x
li.append(f1)
print(li[0]())
print(li[1]())
print(li[2]())

输出是

0
1
2

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

总结

总结下这篇的重要的三句话吧:

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

python 3 和2.7 class 类多继承时的区别

在python2.7中,类默认不继承object类,叫经典类;继承object类,叫新式类

在python3中,如果按照2.7中的规则,所有的类都算新式类

多继承并且有共同父类的情况下:

  • 经典类,一条道走到黑,然后再从第二个继承类中找
  • 新式类,查找的最后的终点是共同父类,所以在查找途中如果遇到共同父类,会返回创建对象类下一个父类类中,知道走到最后共同类。

python基础之知识补充-作用域、特殊语法的更多相关文章

  1. 一、python基础相关知识体系

    python基础 a. Python(解释型语言.弱类型语言)和其他语言的区别? 一.编译型语言:一次性,将全部的程序编译成二进制文件,然后在运行.(c,c++ ,go) 运行速度快.开发效率低 二. ...

  2. Python学习---django知识补充之CBV

    Django知识补充之CBV Django: url    -->  def函数      FBV[function based view]  用函数和URL进行匹配 url    --> ...

  3. Python基础灬函数补充(作用域,迭代器,生成器)

    变量作用域 函数里面操作外部变量时,作用域仅限于函数里面. var1 = 123 def func(): var1 = 456 print("函数里:", var1) func() ...

  4. python基础17 ---继承补充知识

    一.继承的顺序 1.在python中的类可以集成多个类,既然是继承多个类就有类的寻找顺序这么一说.其寻找方法就有广度优先和深度优先两种. 2.当类是新式类,多继承的情况下会按照广度优先的顺序查找. 如 ...

  5. 2015/9/19 Python基础(15):变量作用域及生成器

    变量作用域标识符的作用域是定义为其声明的可应用范围,或者即是我们所说的变量可见性.也就是,我们可以在程序的那个部分去访问一个制定的标识符.全局变量与局部变量定义在函数内的变量有局部作用域,在一个模块中 ...

  6. Python基础入门知识

    本节内容 Python介绍 发展史 Python 2 or 3? 安装 Hello World程序 变量 用户输入 模块初识 .pyc是个什么鬼? 数据类型初识 数据运算 表达式if ...else语 ...

  7. python基础编程: 编码补充、文件操作、集合、函数参数、函数递归、二分查找、匿名函数与高阶函数

    目录: 编码的补充 文件操作 集合 函数的参数 函数的递归 匿名函数与高阶函数 二分查找示例 一.编码的补充: 在python程序中,首行一般为:#-*- coding:utf-8 -*-,就是告诉p ...

  8. Python基础:11变量作用域和闭包

    一:变量作用域 变量可以是局部域或者全局域.定义在函数内的变量有局部作用域,在一个模块中最高级别的变量有全局作用域. 全局变量的一个特征是除非被删除掉,否则它们的存活到脚本运行结束,且对于所有的函数, ...

  9. Python基础、collections补充

    collections collections是Python数据类型的补充,可以实现Counter计数.可命名元组(namedtuple).默认字典.有序字典.双向队列等功能 参考:http://py ...

随机推荐

  1. 【搜索-剪枝-偏难】PAT-天梯赛-L3-015. 球队“食物链”

    L3-015. 球队“食物链” 某国的足球联赛中有N支参赛球队,编号从1至N.联赛采用主客场双循环赛制,参赛球队两两之间在双方主场各赛一场. 联赛战罢,结果已经尘埃落定.此时,联赛主席突发奇想,希望从 ...

  2. 学习php doctrine

    了解symfony3.3.PHP FIG.Doctrine: 了解angular2.material2:. 熟悉git:了解开源项目:openstack docker ceph等: NoSQL(HBa ...

  3. WCF之MSMQ消息队列

    一.MSMQ简介 MSMQ(微软消息队列)是Windows操作系统中消息应用程序的基础,是用于创建分布式.松散连接的消息通讯应用程序的开发工具. MSMQ与XML Web Services和.Net ...

  4. python - django (查询、聚合、分组)

    # """ ---- 正向查询按字段,反向查询按表名 一: 一对多 正向查询:(字段对象.关联表.查询字段) x_obj = models.Book.objects.fi ...

  5. BZOJ 3749: [POI2015]Łasuchy(贪心)

    Orz大佬博客 CODE #include <bits/stdc++.h> using namespace std; typedef long long LL; char cb[1< ...

  6. pip 安装包 不行 自己下载whl 包自己安装

    https://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted

  7. Elasticsearch 监控

    导语 Elasticsearch(文中简称ES)是分布式全文搜索引擎,产品提供高可用.易扩展以及近实时的搜索能力,广泛应用于数据存储.搜索和实时分析.很多服务的可用性对ES重度依赖.因此,保障ES自身 ...

  8. 三个方法(apply、call、bind)

    一.apply()和call() 方法中如果没传入参数,或者是null,那么调用该方法的函数对象中的this就是默认的window <script> function f1(x,y){ c ...

  9. 项目 java.lang.NoClassDefFoundError 异常。

    项目部署之后调用接口失败:异常信息: NoClassDefFoundError ClassNotFoundException 注意这两种是有区别的. 具体转 https://www.cnblogs.c ...

  10. hbuilder mui html vue ul li 自定义循环赋值ID

    <ul class="mui-table-view mui-table-view-chevron"> <li class="mui-table-view ...