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. SQL SERVER中如何查找存储过程中一段代码

    select b.name ,a.text from syscomments a,sysobjects b where and object_id(b.name)=a.id and b.xtype i ...

  2. python - django (母版与组件)

    # 把多个页面通用的部分提取出来 放在一个母版中 # 其它的页面只需要继承 母版就可以 # 使用步骤:( 继承的语句要放在第一行 ) """ 1. 把公用的 HTML 部 ...

  3. Git - Q

    GIT :实现版本控制的软件 命令: git init # 初始 git (先执行这个才能执行接下来的) git status # 查看当前文件夹状态 git add 文件名 # 对指定文件进行版本控 ...

  4. BZOJ4802 欧拉函数 (Pollard-Rho Miller-Robin)

    题目 求大数的欧拉函数φ\varphiφ 题解 Pollard-Rho 板子 CODE #pragma GCC optimize (3) #include <bits/stdc++.h> ...

  5. GO语言基本数据类型

    一.整型 Go语言的数值类型分为以下几种:整数.浮点数.复数,其中每一种都包含了不同大小的数值类型,例如有符号整数包含 int8.int16.int32.int64 等,每种数值类型都决定了对应的大小 ...

  6. spark提交任务报错: java.lang.SecurityException: Invalid signature file digest for Manifest main attributes

    spark提交任务报错: java.lang.SecurityException: Invalid signature file digest for Manifest main attributes ...

  7. Vagrant Docker Composer Yarn 国外资源下载慢或失败的问题

    1 问题 有时,我们请求国外资源时,下载巨慢,甚至失败.如: cd vue-devtools/ $ yarn install 进行到 cypress.... 时,可能失败. 2 解决 次日凌晨(7-8 ...

  8. am335x system upgrade kernel emmc(十八)

    1      Scope of Document This document describes EMMC hardware design 2      Requiremen 2.1     Func ...

  9. 数据结构实验之二叉树一:树的同构 (SDUT 3340)

    题解:把原本结构体的左右子树的类型定义成 int 型,用来存放这个结点的左右子树的编号,分别建造两棵二叉树,按个比较,如果在第二棵树中没有找到,那么就不用在判断了. #include <bits ...

  10. 如何查看Linux cpu核数、版本等信息

    CPU总核数 = 物理CPU个数 * 每颗物理CPU的核数 总逻辑CPU数 = 物理CPU个数 * 每颗物理CPU的核数 * 超线程数 1.查看CPU信息(型号): [root@iZ2ze1rl2qy ...