python基础之知识补充-作用域、特殊语法
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基础之知识补充-作用域、特殊语法的更多相关文章
- 一、python基础相关知识体系
python基础 a. Python(解释型语言.弱类型语言)和其他语言的区别? 一.编译型语言:一次性,将全部的程序编译成二进制文件,然后在运行.(c,c++ ,go) 运行速度快.开发效率低 二. ...
- Python学习---django知识补充之CBV
Django知识补充之CBV Django: url --> def函数 FBV[function based view] 用函数和URL进行匹配 url --> ...
- Python基础灬函数补充(作用域,迭代器,生成器)
变量作用域 函数里面操作外部变量时,作用域仅限于函数里面. var1 = 123 def func(): var1 = 456 print("函数里:", var1) func() ...
- python基础17 ---继承补充知识
一.继承的顺序 1.在python中的类可以集成多个类,既然是继承多个类就有类的寻找顺序这么一说.其寻找方法就有广度优先和深度优先两种. 2.当类是新式类,多继承的情况下会按照广度优先的顺序查找. 如 ...
- 2015/9/19 Python基础(15):变量作用域及生成器
变量作用域标识符的作用域是定义为其声明的可应用范围,或者即是我们所说的变量可见性.也就是,我们可以在程序的那个部分去访问一个制定的标识符.全局变量与局部变量定义在函数内的变量有局部作用域,在一个模块中 ...
- Python基础入门知识
本节内容 Python介绍 发展史 Python 2 or 3? 安装 Hello World程序 变量 用户输入 模块初识 .pyc是个什么鬼? 数据类型初识 数据运算 表达式if ...else语 ...
- python基础编程: 编码补充、文件操作、集合、函数参数、函数递归、二分查找、匿名函数与高阶函数
目录: 编码的补充 文件操作 集合 函数的参数 函数的递归 匿名函数与高阶函数 二分查找示例 一.编码的补充: 在python程序中,首行一般为:#-*- coding:utf-8 -*-,就是告诉p ...
- Python基础:11变量作用域和闭包
一:变量作用域 变量可以是局部域或者全局域.定义在函数内的变量有局部作用域,在一个模块中最高级别的变量有全局作用域. 全局变量的一个特征是除非被删除掉,否则它们的存活到脚本运行结束,且对于所有的函数, ...
- Python基础、collections补充
collections collections是Python数据类型的补充,可以实现Counter计数.可命名元组(namedtuple).默认字典.有序字典.双向队列等功能 参考:http://py ...
随机推荐
- unable to access 'https://github.com/shixianqing/img.git/': SSL connect error 解决办法
解决在linux环境下,git clone 项目,走https协议时,报SSL connect error 错误 升级nss yum update -y nss curl libcurl
- Mongoose初使用总结
连接mongoose mongoose连接数据库有两种方式 第一种: 'use strict'; const mongoose = require('mongoose'); mongoose.conn ...
- python_面向对象——编程步骤
校园管理系统: 设计一个学校机构管理系统,有总部.分校.有学院.老师.员工,实现具体如下需求: 1.有多个课程,课程要有定价 2.有多个班级,班级跟课程有关联 3.有多个学生,学生报名班级,交这个班级 ...
- 02 Spring IOC
我们先看看我们在没有spring之前,程序间是怎么解耦的.创建一个maven工程,整体的目录结构 1.创建dao层 IAccountDao.java package com.itzn.dao; pub ...
- 28-SQLServer带见证服务器的镜像搭建
一.注意点 1.数据库的模式要是完整模式. 2.要对数据库完整备份和事务日志备份,分别还原到镜像库上,使用NORECOVERY模式. 3.镜像数据库是不允许删除和操作,即便查看属性也不行. 4.先删除 ...
- Django中出现:TemplateDoesNotExist at
setting文件中加入:
- 使用selenium 多线程爬取爱奇艺电影信息
使用selenium 多线程爬取爱奇艺电影信息 转载请注明出处. 爬取目标:每个电影的评分.名称.时长.主演.和类型 爬取思路: 源文件:(有注释) from selenium import webd ...
- 1040 too many connections
先重启mysql. 登录成功后执行以下语句查询当前的最大连接数:select VARIABLE_VALUE from information_schema.GLOBAL_VARIABLES where ...
- Codeforces Round #524 (Div.2)题解
题解 CF1080A [Petya and Origami] 这道题其实要我们求的就是 \[\lceil 2*n/k \rceil + \lceil 5*n/k \rceil + \lceil 8*n ...
- LibreOJ #507. 「LibreOJ NOI Round #1」接竹竿
二次联通门 : LibreOJ #507. 「LibreOJ NOI Round #1」接竹竿 /* LibreOJ #507. 「LibreOJ NOI Round #1」接竹竿 dp 记录一下前驱 ...