热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python入门基础三元表达式、命名空间、作用域、函数名本质、闭包

1.三元表达式(三目运算式)2.命名空间(namespace)3.命名空间查找顺序4.作用域5.globals和locals的区别6.函数的嵌套和作用域7.函数名
1.三元表达式(三目运算式)
#1 三元表达式(三目运算法)
#格式为: 为真时的结果 if 判定条件 else 为假时的结果
#另外三元表达式只适合较为简洁的条件判定,较为复杂的判定建议不要用这种方式写代码,因为比较让他人难以理解。

a = 10
b = 15

compare = a if  a > b else b    #谁大返回谁
print(compare)
2.命名空间(namespace)
#2 命名空间(namespace)
#命名空间是名称和对象的印象,也可以将命名空间理解成一个字典,例如定义变量的时候,变量名名就是对应字典的key,而后面的赋值内容就是字典的value,再举例说函数也是一样,函数名就是字典的key,函数体就是字典的value;
#各个命名空间是独立的,没有任何关系的,所以一个命名空间中不能存在重名,但不同的命名空间可以重名并且没有影响。
#在python当中命名空间分为内置空间、全局空间、局部空间三种。

#(1)python解释器拥有自己内置空间,内置的函数在解释器启动时就被加载到内存中,任何模块都可以访问它,它存放着函数和异常。
#(2)每个模块拥有它自已的命名空间,叫做全局命名空间,它记录了模块的变量,包括函数、类、其它导入的模块、模块级的变量和常量。
#(3)每个函数都有着自已的命名空间,叫做局部命名空间,它记录了函数的变量,包括函数的参数和局部定义的变量。
3.命名空间查找顺序
#3 命名空间查找顺序
# 假设查找当前命名空间中的“s”变量。
# (1)局部命名空间:首先在局部命名空间中查找,如果没有发现继续去上层全局命名空间查找,如果再没有继续向上层内置命名空间查找,如果再没有python会返回错误。
# (2)全局命名空间:首先在全局命名空间中查找,如果没有发现继续去上层内置命名空间查找,如果再没有python会返回错误。
# (3)内置命名空间:如果在内置命名空间差找不到,直接返回错误。

#1)局部命名空间内调用全局命名空间的变量:
a = 10
def my():
    print(a)    #可以成功打印出来10

my()


#如果换成这样就不能调用了:
a = 10
def my():
    a += 1  #对于不可变类型在局部命名空间中可以查看,但不能直接去修改。
    #错误:UnboundLocalError: local variable ‘a‘ referenced before assignment
    print(a)    #可以成功打印出来10

my()

#在全局命名空间调用内置命名空间的变量:
x = 10
def my(x):  # x = 15
    print(x)    # x =15

my(15)
print(x)    # x = 10,全局命名空间只会在当前或上级内置命名空间中查找x,不会去局部命名空间中查找x
4.作用域
#4 作用域
#作用域就是作用范围,按照生效范围可以分为全局作用域和局部作用域两种。
#(1)全局作用域:包含内置命名空间和全局命名空间,在整个文件中任意位置可以被引用,并且全局有效。
#(2)局部作用域:局部命名空间,只能在局部范围内有效。
5.globals和locals的区别
# 5 globals和locals的区别
#globals方法
#globals永远打印全局的名字
def a():
    print(globals())    #局部命名空间中的输出结果和全局命名空间中的输出结果一样

a()
print(globals())

#locals方法
#输出什么,根据locals所在位置决定。
def func():
    a = 10
    b = 12
    print(locals()) #打印的信息时局部命名空间的变量信息

func()
print(locals()) #打印的信息和globals一样


#global 关键字
#如果在局部命名空间中需要修改全局命名空间的变量值,需要在其之前用global声明即可,其后面的操作将对全局变量有效。

a = 12
def func():
    global a    #对变量a进行全局声明,之后的操作将对全局的变量有效
    a = 25
    print(a)    # a = 25 对全局变量有效

func()
print(a)    # a = 25
6.函数的嵌套和作用域
#6 函数的嵌套和作用域链
#(1)函数的嵌套调用
def my_compare1(a,b):       #顺序1
    return a if a > b else b    #顺序8    #顺序10

def my_compare2(a,b,c):     #顺序2
    c1 = my_compare1(a,b)   #顺序7
    return my_compare1(c,c1)    #顺序9

a = 10      #顺序3
b = 20      #顺序4
c = 15      #顺序5
print(my_compare2(a,b,c))       #顺序6    #顺序11 打印函数的返回值

#(2)函数的嵌套定义
def f1():       #顺序1
    print(in f1)      #顺序3
    def f2():       #顺序4
        print(in f2)      #顺序6
    f2()            #顺序5
f1()        #顺序2

#(3)函数的作用域链
#one

def f1():
    a = 1
    def f2():
        def f3():
            print(a)    #打印出的结果是 1 ,因为现在f3属于子局部命名空间,存在父局部命名空间,如果当前子局部域名空间没有,就会向上查找变量a,直至到内置命名空间。
        f3()
    f2()

f1()

#two

def f1():
    a = 1
    def f2():
        a = 2
    f2()
    print(a in f1 : ,a)   #此处的变量a,打印出来的是1,因为print和f2函数命名所处f1函数体中,而f2函数体中的a = 2 所处空间是print所在空间的子局部空间,所以print 打印 a的时候不会向下查找。
f1()


#(4)nonlocal关键字
#nonlocal 只能用于局部变量 找上层中离当前函数最近一层的局部变量
#声明了nonlocal的内部函数的变量修改会影响到 离当前函数最近一层的局部变量
a = 10
def f1():
    a = 1
    def f2():
        a = 2
        def f3():
            nonlocal a  #对变量声明nonlocal之后,后面对变量a的操作只会对上一层的局部变量有影响。
            a = 2 + 1
        f3()
        print(a in f2:,a)
    f2()
    print(a in f1 : ,a)

f1()
print(a)
7.函数名的本质
#7 函数名的本质
#函数名本质上就是函数的内存地址
#(1)可以被引用
def func():
    print(hello word!)
fun = func
fun()   #fun()和func()调用函数体之后,打印的信息完全一致
func()

#(2)可以被当作容器类的元素
def f1():
    print(f1)
def f2():
    print(f2)
def f3():
    print(f3)

l = [f1,f2,f3]
d = {f1:f1,f2:f2,f3:f3}
#调用
l[0]()  #调用f1函数体的内容
d[f2]()   #调用f2函数体的内容

#(3)可以当做函数的参数或返回值
#当参数
def func1():
    print(abc)

def func2(func1):
    func1()         #调用func1函数
    print(def)

func2(func1)    #将func1函数名当做参数传递给func2函数

#当返回值
def func1():
    print(abc)

def func2():
    print(def)
    return func1    #将func1函数名当做地址返回

a = func2() #将func1函数的内存地址复制给变量a
a() #调用func1函数
8.闭包
#8 闭包函数
#闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在
# ,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。(看起来相当难以理解)

#对于上面的解释,我总结闭包在嵌套函数的环境中,内部函数调用外部函数的变量,并且外部函数的变量一直存在,下面举个例子看看。
def func():
    a = 0
    print(输出外部函数的变量:,a)
    def f1():
        print(内部函数输出变量:,a)
    return  f1

f = func()
f()         #第一次调用会打印出来“输出外部函数的变量: 0” 和“内部函数输出变量: 0”
f()         #再次调用会打印出来“内部函数输出变量: 0”,包括后面无论几次调用,打印的结果都是这种,不会出现上面的情况,这就是闭包的方式之一

#判断闭包函数的方法__closure__
#输出的__closure__有cell元素 :是闭包函数
def func():
    name = eva
    def inner():
        print(name)
    print(inner.__closure__)    #打印结果:(,)
    return inner

f = func()
f()

#输出的__closure__为None :不是闭包函数
name = egon
def func2():
    def inner():
        print(name)
    print(inner.__closure__)    #因为外部函数体(局部空间)内不存在变量,所以打印结果:None
    return inner

f2 = func2()
f2()

python入门基础-三元表达式、命名空间、作用域、函数名本质、闭包


推荐阅读
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 本文介绍了指针的概念以及在函数调用时使用指针作为参数的情况。指针存放的是变量的地址,通过指针可以修改指针所指的变量的值。然而,如果想要修改指针的指向,就需要使用指针的引用。文章还通过一个简单的示例代码解释了指针的引用的使用方法,并思考了在修改指针的指向后,取指针的输出结果。 ... [详细]
author-avatar
灬段裝丶緈褔_998
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有