欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

函数的返回值

程序员文章站 2024-03-17 16:00:16
...

函数的返回值

 

In [1]: def add(x, y):   # return 除了返回值以外, 还会结束函数, return之后的语句将不会被执行
   ...:     return x + y
   ...: print('hahaha')
   ...: 
hahaha

In [2]: def add(x, y):
   ...:     return x + y
   ...:     print('hahaha')
   ...: 

In [3]: ret = add(1, 3)

In [4]: ret
Out[4]: 4

In [5]: def guess(x):  # 所以一个函数可以有多个return, 执行到哪个return,就由哪个return 返回结果并结束函数
   ...:     if x > 3:
   ...:         return '>3'
   ...:     return '<=3'
   ...: 

In [6]: s = guess(3)

In [7]: s
Out[7]: '<=3'

In [8]: s = guess(5)

In [9]: s
Out[9]: '>3'

In [10]: 

In [10]: def fn(x):
    ...:     for i in range(x):
    ...:         if x > 3:
    ...:             return i
    ...:     else:
    ...:         print('not bigger than 3')
    ...:         

In [11]: fn(10)
Out[11]: 0

In [12]: fn(3)
not bigger than 3

In [13]: 

In [13]: def fn():        # 如果当函数没有return 语句的时候, 隐式返回了一个None
    ...:     pass
    ...: 

In [14]: ret = fn()

In [15]: type(ret)
Out[15]: NoneType

In [16]: typr(None)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-16-3565bd08d192> in <module>()
----> 1 typr(None)

NameError: name 'typr' is not defined

In [17]: type(None)
Out[17]: NoneType

In [18]: ret == None
Out[18]: True
In [19]: def fn():
    ...:     return 3, 5
    ...: 

In [20]: ret = fn()

In [21]: ret          # 类似于 封装
Out[21]: (3, 5)

In [22]: x, y = ret   # 类似于 解构

In [23]: x
Out[23]: 3

In [24]: y
Out[24]: 5

In [27]: def fn():
    ...:     return None
    ...: 

In [28]: ret = fn()

In [29]: ret == None
Out[29]: True

In [30]: 

In [30]: def fn():
    ...:     return            # 返回None, 可以简写为 return 通常用于结束函数
    ...: 

In [31]: 

In [31]: def fn(x):
    ...:     if x > 3:
    ...:         return
    ...:     return '<=3'
    ...: 

In [32]: fn(5)

In [33]: fn(3)
Out[33]: '<=3'

In [34]: 

函数的嵌套

In [35]: def outter():
    ...:     def inner():
    ...:         print('inner')
    ...:     print('outter')
    ...:     inner()
    ...:         

In [36]: outter()
outter
inner

In [37]: 

一、作用域

In [39]: x = 1

In [40]: def inc():
    ...:     print(x)   # 并未参与到运算中
    ...:     y = x + 1  # 只读可见, 不可写
    ...:     return y
    ...: 

In [41]: inc()
1
Out[41]: 2

In [42]: 
In [42]: def fn():
    ...:     xx = 1
    ...:     print(xx)
    ...:     

In [43]: fn()
1

In [44]: xx
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-44-ce3af7760f12> in <module>()
----> 1 xx

NameError: name 'xx' is not defined

In [45]: 

In [45]: def fn2():
    ...:     peint(xx)
    ...:     

In [46]: fn()
1

In [47]: fn2()  # 变量的作用域 为变量同级的作用域, 也就是说 在哪一个级别定义的, 在哪一个级别就可见
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-47-e87bcb52744c> in <module>()
----> 1 fn2()

<ipython-input-45-ff1e6126d39a> in fn2()
      1 def fn2():
----> 2     peint(xx)
      3 

NameError: name 'peint' is not defined

In [48]: 
In [49]: def fn():
    ...:     xx = 1
    ...:     print(xx)
    ...:     def inner():
    ...:         print(xx)
    ...:     inner()
    ...:         

In [50]: fn()
1
1

In [51]: 

In [51]: def fn():
    ...:     xx = 1
    ...:     print(xx)
    ...:     print(id(xx))
    ...:     def inner():
    ...:         xx = 2
    ...:         print(id(xx))
    ...:     inner()
    ...:     print(xx)
    ...:     print(id(xx))
    ...:         

In [52]: fn()
1
9289856
9289888
1
9289856

In [53]: 
In [54]: def fn():
    ...:     xx = 1
    ...:     print(xx)
    ...:     def inner():
    ...:         xx = 2
    ...:     inner()
    ...:     print(xx)
    ...:         

In [55]: xx = 1

In [56]: def fn():
    ...:     global xx
    ...:     xx += 1
    ...:     

In [57]: fn()

In [58]: xx
Out[58]: 2

In [59]: fn()

In [60]: xx
Out[60]: 3

In [61]: 

In [61]: def fn():
    ...:     global yy
    ...:     yy = 3
    ...:     

In [62]: fn()

In [63]: yy
Out[63]: 3

In [64]: def fn():
    ...:     global zz
    ...:     

In [65]: zz
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-65-15546de8c3b0> in <module>()
----> 1 zz

NameError: name 'zz' is not defined

In [66]: 

金玉良言: 除非你清楚的知道,global 会带来什么, 并明确的知道非global不行,否则不要使用global

二、闭包

In [66]: def counter():
    ...:     x = 0
    ...:     def inc():
    ...:         global x
    ...:         x += 1
    ...:         return x
    ...:     return inc
    ...: 

In [67]: f = counter()

In [68]: f()
Out[68]: 2

In [69]: f()
Out[69]: 3

In [70]: f = counter()

In [71]: f()
Out[71]: 4

In [72]: x
Out[72]: 4

In [73]: f()
Out[73]: 5

In [74]: x
Out[74]: 5

In [75]: x = 0

In [76]: f()
Out[76]: 1

In [77]: x
Out[77]: 1
In [79]: def counter():
    ...:     c = [0]
    ...:     def inc():
    ...:         c[0] += 1
    ...:         return c[0]
    ...:     return inc
    ...: 
# 函数执行完毕之后,仍有部分函数变量的引用存在

In [80]: f = counter()

In [81]: f()
Out[81]: 1

In [82]: c = 100

In [83]: f()
Out[83]: 2

In [84]: lst = [1]

In [85]: id(lst)
Out[85]: 140023278144840

In [86]: lst[0] = 2

In [87]: id(lst)
Out[87]: 140023278144840

In [88]: f()
Out[88]: 3

In [89]: f = counter()

In [90]: f()
Out[90]: 1

In [91]: f()
Out[91]: 2

In [92]: 


1、nonlocal

In [92]: def counter():
    ...:     x = 0
    ...:     def inc():
    ...:         x += 1
    ...:         return x
    ...:     return inc
    ...: 

In [93]: f = counter()

In [94]: f()
---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-94-c43e34e6d405> in <module>()
----> 1 f()

<ipython-input-92-91cd34f02038> in inc()
      2     x = 0
      3     def inc():
----> 4         x += 1
      5         return x
      6     return inc

UnboundLocalError: local variable 'x' referenced before assignment

In [95]: 

In [95]: def counter():    # 通过 nonlocal 关键字,可以对上级作用域的变量,进行 可读可写
    ...:     x = 0
    ...:     def inc():
    ...:         nonlocal x
    ...:         x += 1
    ...:         return x
    ...:     return inc
    ...: 

In [96]: f = counter()

In [97]: f()
Out[97]: 1

In [98]: f()
Out[98]: 2

In [99]: 

赋值既定义

2、默认参数作用域

In [100]: def fn(x=[]):
     ...:     x.append(1)
     ...:     print(x)
     ...:     

In [101]: fn()
[1]

In [102]: fn()
[1, 1]

In [103]: fn
Out[103]: <function __main__.fn>

In [104]: fn.__defaults__
Out[104]: ([1, 1],)

In [105]: 

In [105]: fn()
[1, 1, 1]

In [106]: fn.__defaults__
Out[106]: ([1, 1, 1],)

In [107]: fn.__defaults__ = ([], )

In [108]: fn()
[1]

In [109]: fn.__defaults__
Out[109]: ([1],)

In [110]: 

In [110]: def gn(a=2, b=1):
     ...:     print(a + b)
     ...:     

In [111]: gn.__defaults__
Out[111]: (2, 1)

In [112]: 

全局作用域。什么时候会销毁?

  • 重新定义
  • del 关键字删除
  • 程序结束推出

局部作用域。什么时候销毁?

  • 重新定义
  • del 关键字删除
  • 上级作用域被销毁
In [112]: def fn(aa=[], bb=[]):
     ...:     aa.append(1)
     ...:     bb.append(2)
     ...:     print(aa, bb)
     ...:     

In [113]: fn()
[1] [2]

In [114]: fn()
[1, 1] [2, 2]

In [115]: fn.__defaults__
Out[115]: ([1, 1], [2, 2])

In [116]: 

In [116]: def fn(x=0, y=0):   # int 是不可变类型
     ...:     print(id(x))
     ...:     x = 3
     ...:     print(id(x))
     ...:     x = 4
     ...:     print(id(x))
     ...:     y = 3
     ...:     print(x, y)
     ...:     

In [117]: fn()
9289824
9289920
9289952
4 3

In [118]: fn.__defaults__      # int 是不可变类型
Out[118]: (0, 0)

In [119]: 

如何去接解决list的问题?

  • 使用不可变类型作为默认值
  • 函数体内不改变默认值

 

In [120]: def fn(lst=None):
     ...:     if lst is None:
     ...:         lst = []
     ...:     lst.append(3)
     ...:     print(lst)
     ...:          

In [121]: fn.__defaults__
Out[121]: (None,)

In [122]: fn()
[3]

In [123]: 

In [123]: 

In [123]: def fn(lst=[]):
     ...:     print(id(lst))
     ...:     lst = lst[:]
     ...:     print(id(lst))
     ...:     lst.append(1)
     ...:     print(lst)
     ...:     

In [124]: fn()
140023278495752
140023268626120
[1]

In [125]: fn.__defaults__
Out[125]: ([],)

In [126]: fn()
140023278495752
140023278218120
[1]

In [127]: fn.__defaults__
Out[127]: ([],)

In [128]: 

In [128]: 

In [128]: def fn(lst=None):
     ...:     if lst is None:
     ...:         lst = []
     ...:     else:
     ...:         lst = lst[:]
     ...:         lst.append(3)
     ...:     print(lst)
     ...:           

In [129]: fn()
[]

In [130]: fn()
[]

In [131]: fn.__defaults__
Out[131]: (None,)

In [132]: fn(1)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-132-454eedcabd9c> in <module>()
----> 1 fn(1)

<ipython-input-128-3bf22a286480> in fn(lst)
      3         lst = []
      4     else:
----> 5         lst = lst[:]
      6         lst.append(3)
      7     print(lst)

TypeError: 'int' object is not subscriptable

In [133]: fn([1, 2, 3])
[1, 2, 3, 3]

In [134]: 

 

函数的执行流程:

main

f1()

f2()

f3()

    f4()
    
        f5()
main

三、递归函数   

程序调用自身的编程技巧,称为 递归。

归纳法:通过一类事物的部分对象具有某种性质,推出这类事物的所有对象都具有这种性质的推理方法。

例如,斐波那契数列

fib(n) = 1 if n = 0

fib(n) = 1 if n = 1

fib(n) = fib(n-1) + fib(n-2)

In [146]: def fib(n):
     ...:     if n == 0:
     ...:         return 1
     ...:     if n == 1:
     ...:         return 1
     ...:     return fib(n-1) + fib(n-2)
     ...: 

In [147]: fib(0)
Out[147]: 1

In [148]: fib(1)
Out[148]: 1

In [149]: fib(2)
Out[149]: 2

In [150]: fib(3)
Out[150]: 3

In [151]: fib(4)
Out[151]: 5

In [152]: fib(5)
Out[152]: 8

In [153]: 

In [153]: 

In [153]: def fib(n):
     ...:     return fib(n-1) + fib(n-2)
     ...: 

In [154]: fib(4)
---------------------------------------------------------------------------
RecursionError                            Traceback (most recent call last)
<ipython-input-154-252d5fa3ed3f> in <module>()
----> 1 fib(4)

<ipython-input-153-3e11de167e36> in fib(n)
      1 def fib(n):
----> 2     return fib(n-1) + fib(n-2)

... last 1 frames repeated, from the frame below ...

<ipython-input-153-3e11de167e36> in fib(n)
      1 def fib(n):
----> 2     return fib(n-1) + fib(n-2)

RecursionError: maximum recursion depth exceeded

In [155]: import sys

In [156]: sys.getrecursionlimit()
Out[156]: 3000

 

转载于:https://my.oschina.net/u/3552459/blog/1563172