北京到三亚:Python函数的返回值和作用域

admin/2020-04-22/ 分类:科技/阅读:

函数的返回值和作用域

1、返回值

def guess(x):
    if x > 3:
        return "> 3"
    else:
        return "<= 3"
print(guess(10))

  1> Python 函数使用 return 语句返回 "返回值”
  2> 所有函数都有返回值,若是没有 return 语句,隐式挪用 return None
  3> return 语句并不一定是函数的语句块的最后一条语句
  4> 一个函数可以存在多个 return 语句,然则只有一条可以被执行。若是没有一条 return 语句被执行到,隐式挪用 return None
  5> 若是有需要,可以显示挪用return None,可以简写为return
  6> 若是函数执行了 return 语句,函数就会返回,当前被执行的 return 语句之后的其它语句就不会被执行了
  7> 返回值的作用:竣事函数挪用、返回 "返回值”

2、能一次返回多个值嘛?

def showvalues(): return 1, 3, 5 print(showvalues()) # 返回 (1, 3, 5)

  函数不能同时返回多个值
  return 1, 3, 5 看似返回多个值,隐式的被 python 封装成了一个元组
  x, y, z = showvalues() 使用解构提取返回值更为利便

3、函数作用域**

3.1 作用域

  一个标识符的可见局限,这就是标识符的作用域,一样平常常说变量的作用域。

x = 20 def fn(): x = 100 # x 的作用域:当前函数 fn() print(x) # x = 20

  注重:每一个函数都市开拓一个作用域。

3.2 作用域分类

  全局作用域:
    在整个程序运行环境中都可见
    全局作用域中的变量称为全局变量

  局部作用域:
    在函数、类等内部可见
    局部作用域中的变量称为局部变量,其使用局限不跨越其所在局部作用域

# 局部变量 def fn1(): x = 1 # 局部作用域,x 为局部变量,使用局限在 fn1 内 def fn2(): print(x) # x 能打印吗?不能 print(x) # x 能打印吗?不能
# 全局变量 x = 5 # 全局变量,也在函数外界说 def foo(): print(x) # 可见吗?可以 foo()

  一样平常来讲外部作用域变量在函数内部可见,可以使用
  反过来,函数内部的局部变量,不能在函数外部看到

4、函数嵌套

  在一个函数中界说另一个函数

def outer(): def inner(): print('inner') print('outer') inner() outer() inner() # 不能以

  内部函数 inner 不能在外部直接使用,会抛出 NameError 异常,由于它在函数外部不能见。
  实在,inner 不外就是一个标识符,就是一个函数 outer 内部界说的变量而已。

5、嵌套函数的作用域

def outer(): o = 65 # 局部变量、内陆 local 变量、暂且变量 def inner(): o = 97 print('inner', o) print('outer 1 ', o) inner() print('outer 2 ', o) outer() # 1:outer 1 65 2:inner 97 3:outer 2 65

  外层变量在内部作用域可见。
  内层作用域中,若是界说了和外层相同的变量,相当于在当前函数作用域中重新界说了一个新的变量,这个内层变量并不能笼罩掉外部作用域中的变量。

6、一个赋值语句的问题

x = 100 def fn(): y = x 200 print(y) fn()
x = 100 def fn(): x  = 1 # 报错! 赋值即界说,即 x = x 1 (局部变量 = 局部变量 1)! print(x) fn()
x = 100 def fn(): print(x) # 报错!该步执行不了! x = 1 # 只要在该作用域内赋值界说('=')局部变量,在该作用域内的所有该变量都为局部变量! print(x) fn()

  能否解决呢?可以,使用 global 语句

x = 100 def fn(): global x # 声明全局变量 print(x) # 100 x = 1 print(x) # 101 fn() print(x) # 101

  注重:全局变量一样平常情形不推荐修改,一旦在作用域中使用 global 声明全局变量,那么相当于在对全局变量赋值、界说。

  global 使用原则:

    1> 外部作用域变量会在内部作用域可见,但也不要在这个内部的局部作用域中直接使用,由于函数的目的就是为了封装,只管与外界隔离。
    2> 若是函数需要使用外部全局变量,请只管使用函数的形参界说,并在挪用传实参解决。
    3> 一句话:不用 global,学习它就是为了深入明白变量作用域。

# 不建议直接传入全局变量! y = [] def foo(): # x 就是标识符,就是变量,就是内陆变量 y.append(1) foo() foo() print(y)
# 建议使用传参的方式,在函数内使用全局变量 y = [] def foo(x): # x 就是标识符,就是变量,就是内陆变量 x.append(1) foo(y) foo(y) print(y)

 

7、闭包**

  自由变量:未在内陆作用域中界说的变量。例如界说在内层函数外的外层函数的作用域中的变量
  闭包:就是一个观点,出现在嵌套函数中,指的是内层函数引用到了外层函数的自由变量,就形成了闭包。许多语言都有这个观点,最熟悉就是 Javascript。

# python 2 实现闭包 def counter(): c = [0] def inc(): c[0]  = 1 # 是赋值即界说嘛?不是!是修改值 return c[0] return inc # 返回标识符,即函数工具  m = counter() m() # 挪用函数 inc(),然则 c 消亡了嘛?没有,内层函数没有消亡,c 不消亡(闭包) m() m() print(m())
# 不推荐使用 global ! def counter(): global c c = 0 def inc(): global c c  = 1 # 不是闭包! return c return inc m = counter() m() m() m() print(m())
# 推荐使用 nonlocal,python 3 实现闭包 def counter(): c = 0 def inc(): nonlocal c # 非当前函数的内陆变量,当前函数之外的随便层函数的变量,绝非 global c = 1 # 是闭包吗?是! return c return inc m = counter() m() m() m() print(m())

  nonlocal 语句:将变量标记为不在内陆作用域界说,而是在上级的某一级局部作用域中界说,但不能是全局作用域中

8、默认值的作用域

def foo(x=1): x  = 1 print(x) foo() # 2 foo() # 2 def bar(x=[]): # x = [],引用类型 x.append(1) # [1] print(x) bar() # [1] bar() # [1, 1]

  为什么上列 bar 函数第二次挪用打印的是 [1, 1]?
    由于函数也是工具,每个函数界说被执行后,就天生了一个函数工具和函数名这个标识符关联。
    python 把函数的默认值放在了函数工具的属性中,这个属性就伴随着这个函数工具的整个生命周期。

# 查看 foo.__defaults__ 属性,它是个元组 def bar(x=[]): x.append(1) print(x) print(bar.__defaults__) bar() # [1] print(bar.__defaults__) bar() # [1, 1] print(bar.__defaults__) # 执行效果: ([],) [1] ([1],) [1, 1] ([1, 1],) # 元组稳定,纪录的是地址,引用类型转变
def foo(x, m=123, n='abc'): m=456 n='def' print(x) print(foo.__defaults__) # (123, 'abc') foo('yang') print(foo.__defaults__) # (123, 'abc')
def foo(x, m=123, *, n='abc', t=[1,2]): m=456 n='def' t.append(12) #t[:].append(12) # t[:],全新复制一个列表,制止引用计数 print(x, m, n, t) print(foo.__defaults__, foo.__kwdefaults__) #(123,) {'n': 'abc', 't': [1, 2]} foo('yang') print(foo.__defaults__, foo.__kwdefaults__) #(123,) {'n': 'abc', 't': [1, 2, 12]}
def x(a=[]): a = a [5] # 加法的本质:返回新列表、新地址;赋值即界说 print(x.__defaults__) # ([],) x() x() print(x.__defaults__) # ([],) def y(a=[]): a  = [5] # = 即 extend => a.extend([5]) print(y.__defaults__) # ([],) y() y() print(y.__defaults__) # ([5, 5],) # 列表的 和 = 的区别: # 示意两个列表合并并返回一个全新的列表。 # = 示意,就地修改前一个列表,在厥后追加后一个列表,就是 extend 方式。 # 例: l1 = [1, 2] l2 = [3, 4] l3 = l1  l2 print(id(l1), id(l2), id(l3)) l3  = l2 # 就地修改 print(id(l3)) 执行效果: 2279905055304 2279905055816 2279906334216 2279906334216

 

9、变量名剖析原则 LEGB**

  Local,内陆作用域、局部作用域的 local 命名空间,函数挪用时建立,挪用竣事消亡。
  Enclosing,Python2.2 时引入了 嵌套函数,实现了闭包,这个就是嵌套函数的外部函数的命名空间
  Global,全局作用域,即一个模块的命名空间。模块被 import 时建立, 注释器退出时消亡。
  Build-in,内置模块的命名空间,生命周期从 python 注释器启动时建立到注释器退出时消亡。例如 print(open),print 和 open 都是内置的变量。

  以是一个名词的查找顺序就是 LEGB

  

 

10、函数的销毁

  界说一个函数就是天生一个函数工具,函数名指向的就是函数工具。
  可以使用del语句删除函数,使其引用计数减 1。
  可以使用同名标识符笼罩原有界说,本质上也是使其引用计数减 1。
  Python程序竣事时,所有工具销毁。
  函数也是工具,也不破例,是否销毁,照样看引用计数是否减为 0。

 

,

sunbet

www.Lfstncnynmzyhzs.com信誉来源于每一位客户的口碑,Sunbet的服务在sunbet行业是出名的顶尖,广西禄福生态农业开发有限责任公司欢迎新老会员、代理的加入。

TAG:
阅读:
广告 330*360
广告 330*360

热门文章

HOT NEWS
  • 周榜
  • 月榜
Sunbet_进入申博sunbet官网
微信二维码扫一扫
关注微信公众号
新闻自媒体 Copyright © 2002-2019 Sunbet 版权所有
二维码
意见反馈 二维码