1、函数的定义:

  函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。

  函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。

定义一个函数:

  你可以定义一个由自己想要功能的函数,以下是简单的规则:

  • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()
  • 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
  • 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
  • 函数内容以冒号起始,并且缩进。
  • return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。

语法:

 def 函数名(参数1,参数2,参数3,,,,):
“描述信息”
函数体
return #用来定义返回值,可以跟任意数据类型<br><br>
def print_line():
print("*"*13)
def print_msg():
print("alex lala")
print_line()
print_msg()
print_line()
*************
alex lala
*************

2、函数的调用:  

1,定义时无参,调用时也无参(无参函数)
      2,定义时有参,调用时需要传参(有参函数)

  定义一个函数只给了函数一个名称,指定了函数里包含的参数,和代码块结构。

  这个函数的基本结构完成以后,你可以通过另一个函数调用执行,也可以直接从Python提示符执行。

函数的参数介绍:
     1,从实参角度分析
            ⑴按照位置传值
            ⑵按照关键字传值
            ⑶混着用(按照位置和关键字)
   注意问题:①按位置传值必须在按关键字传值的前面
                 ②对于一个形参只能赋值一次
     2,从形参角度来分析
           ⑴位置参数(必须传值的参数)
           ⑵默认参数

默认参数必须注意的问题是:默认参数必须放到位置参数的后面

3、return语句

  return语句[表达式]退出函数,选择性地向调用方返回一个表达式。

  没有return返回None

  return1返回1

  return1,2,3返回(1,2,3)元组

  多个return只返回第一个

4、变量的作用域:

  一个程序的所有的变量并不是在哪个位置都可以访问的。访问权限决定于这个变量是在哪里赋值的。

变量的作用域决定了在哪一部分程序你可以访问哪个特定的变量名称。两种最基本的变量作用域如下: 

  • 全局变量:定义在函数外的拥有全局作用域
  • 局部变量:定义在函数内部的变量

  局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。

#内置名称空间
#全局名称空间
#局部名称空间

 #!/usr/bin/python
# -*- coding: UTF- -*- total = ; # 这是一个全局变量
# 可写函数说明
def sum( arg1, arg2 ):
#返回2个参数的和."
total = arg1 + arg2; # total在这里是局部变量.
print "函数内是局部变量 : ", total
return total; #调用sum函数
sum( , );
print "函数外是全局变量 : ", total 上例输出的结果:
函数内是局部变量 :
函数外是全局变量 :

5、传参:

  在实参的角度:
  规则:按位置传值必须在按关键字传值的前面
  对一个形参只能赋值一次
    1.按照位置传值
    2.按照关键字传值
    3.混着用
  在形参的角度:
  规则:默认参数必须放到位置参数的后面
    1.位置参数
    2.默认参数
    3.*args (接收位置传值)
    4.**kwargs(接收关键字传值)

6、函数嵌套

 #嵌套调用

 def my_max(x,y)
res=x id x>y else y
return res
print(my_max(,)) def my_max1(a,b,c,d):
res1=my_max(a,b)
res2=my_max(res1,c)
res3=my_max(res2,d)
return res3
print(my_max1(,,,))
 #嵌套定义

 x=
def f1():
x=
print("----->f1",x)
def f2():
x=
print("---->f2",x)
def f3():
x=
print("--->f3",x)
f3()
f2()
f1()

7、函数对象

 def foo():#foo代表函数的内存地址
print('foo')
print(foo)#打印出的是foo函数的内存地址,内存地址加括号就可以调用该函数 #函数可以被赋值
f=foo
print(f)#打印的是foo函数的内存地址
f()#等于foo() #把函数当成参数传递
def bar(func):
print(func)
func()
bar(foo)#传入的是foo函数的内存地址,运行结果是打印foo函数的内存地址和foo函数的运行结果 #把函数当成返回值
def bar(func):
print(func)
return func
f=bar(foo)
print(f)
f()

8、闭包

  定义:首先必须是内部定义的函数,该函数包含对外部作用域而不是全局作用域名字的引用

 #闭包
x=
def f1():
x=
y=
def f2():
print(x)
print(y)
return f2  #返回得f2不仅是返回了f2函数局部作用域还返回了引用的外部作用域的变量
f=f1()
print(f)
print(f.__closure__)#必须是闭包才能用此命令
print(f.__closure__[].cell_contents)#查看值
print(f.__closure__[].cell_contents)
-------------------------------------------------------------------------------------------------------------------------------
<function f1.<locals>.f2 at 0x0000000000A7E1E0>
(<cell at 0x0000000000686D08: int object at 0x000000005E5522D0>, <cell at 0x0000000000686D38: int object at 0x000000005E5522F0>)
  #代表f2引用了,f1中的x=
  #代表f2引用了,f2中的y=

闭包用途:爬虫

 #爬虫
from urllib.request import urlopen
def get(url):
return urlopen(url).read()
print(get('http://www.baidu.com')) #专门爬百度页面
def f1(url):
def f2():
print(urlopen(url).read())
return f2  #返回的是f2的内存地址 和 url
baidu=f1('http://www.baifu.com')#等式右边就是return的值,也就是f2的内存地址 和 url<br><br>baidu()

9、递归函数

  定义:在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。

  举个例子,我们来计算阶乘n! = 1 x 2 x 3 x ... x n,用函数fact(n)表示,可以看出:

  fact(n) = n! = 1 x 2 x 3 x ... x (n-1) x n = (n-1)! x n = fact(n-1) x n

  所以,fact(n)可以表示为n x fact(n-1),只有n=1时需要特殊处理。

  于是,fact(n)用递归的方式写出来就是:

 def fact(n):
if n==:
return
return n*fact(n-) #这种思想太牛逼了,感觉脑洞大开
print(fact())

我们在计算fact(5),可以根据函数定义看到计算过程如下:

 ===> fact()
===> * fact()
===> * ( * fact())
===> * ( * ( * fact()))
===> * ( * ( * ( * fact())))
===> * ( * ( * ( * )))
===> * ( * ( * ))
===> * ( * )
===> *
===>

递归函数的有点就是定义简单,逻辑清晰。理论上,所有的函数都可以写成循环的方式,但循环的逻辑不如递归清晰。

  使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。可以试试fact(1000),最好别试。

  解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的。

  尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。

  上面的fact(n)函数由于return n * fact(n - 1)引入了乘法表达式,所以就不是尾递归了。要改成尾递归方式,需要多一点代码,主要是要把每一步的乘积传入到递归函数中:

 def fact(n):
return fact_iter(n,)
def fact_iter(num,product):
if num == :
return product
return fact_iter(num-,num*product)
print(fact())

可以看到,return fact_iter(num - 1, num * product)仅返回递归函数本身,num - 1num * product在函数调用前就会被计算,不影响函数调用。

  fact(5)对应的fact_iter(5, 1)的调用如下:

 ===> fact_iter(, )
===> fact_iter(, )
===> fact_iter(, )
===> fact_iter(, )
===> fact_iter(, )
===>

尾递归调用时,如果做了优化,栈不会增长,因此,无论多少次调用也不会导致栈溢出。

  遗憾的是,大多数编程语言没有针对尾递归做优化,Python解释器也没有做优化,所以,即使把上面的fact(n)函数改成尾递归方式,也会导致栈溢出。

  总结:

  使用递归函数的优点是逻辑简单清晰,缺点是过深的调用会导致栈溢出。

  针对尾递归优化的语言可以通过尾递归防止栈溢出。尾递归事实上和循环是等价的,没有循环语句的编程语言只能通过尾递归实现循环。

  Python标准的解释器没有针对尾递归做优化,任何递归函数都存在栈溢出的问题。

python基础----函数的定义和调用、return语句、变量作用域、传参、函数嵌套、函数对象、闭包、递归函数的更多相关文章

  1. Python函数的定义与调用、返回值、参数

    一.函数是什么 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.比如print(),len()等.但你也可以自己创建函数,这被叫做用户自 ...

  2. Kotlin基础(二)函数的定义与调用

    函数的定义与调用 一.预备知识:在Kotlin中创建集合 fun main(args: Array<String>) { //Kotlin中定义各自集合 val ,,,) val list ...

  3. 12_传智播客iOS视频教程_注释和函数的定义和调用

    OC的注释和C语言的注释一模一样.它也分单行注释和多行注释. OC程序里面当然可以定义一个函数.并且定义的方式方法和调用的方式方法和我们C语言是一模一样的.OC有什么好学的?一样还学个什么呢? 重点是 ...

  4. js函数的定义和调用

    函数的定义 函数使用function 声明,后跟一组参数以及函数体,语法如下: function functionName([age0,age1,......argn]){ statements } ...

  5. Python基础------列表,元组的调用方法

    Python基础------列表,元组的调用方法@@@ 一. 列表 Python中的列表和歌曲列表类似,也是由一系列的按特定顺序排列的元素组成的,在内容上,可以将整数,实数,字符串,列表,元组等任何类 ...

  6. linux shell自定义函数(定义、返回值、变量作用域)介绍

    http://www.jb51.net/article/33899.htm linux shell自定义函数(定义.返回值.变量作用域)介绍 linux shell 可以用户定义函数,然后在shell ...

  7. day03 函数基本语法及特性 2. 参数与局部变量 3. 返回值 嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8.内置函数

    本节内容 1. 函数基本语法及特性 2. 参数与局部变量 3. 返回值 嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8.内置函数 温故知新 1. 集合 主要作用: 去重 关系测 ...

  8. python函数基础(函数的定义和调用)

    函数的定义 python定义函数使用def关键字 return[表达式]语句用于退出函数,选择性的向调用方返回一个表达式,不带参数值的return语句返回none def 函数名(参数列表): 函数体 ...

  9. Python基础--函数的定义和调用

    一.函数的作用: 提高代码的可读性,减少代码的冗余,方便调用和修改,组织结构清晰 二.函数的定义:函数遵循先定义后调用的原则 1.无参函数 def funcname(): #def 是关键字,后跟函数 ...

随机推荐

  1. 240. 搜索二维矩阵 II

    二维数组搜索 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target.该矩阵具有以下特性: 每行的元素从左到右升序排列. 每列的元素从上到下升序排列. 示例: 现有矩阵 ...

  2. windows更改MySQL存储路径

    在C:\ProgramData\MySQL\MySQL Server 5.7文件夹 my.ini是默认的配置文件.在这里我们只更改数据存储路径.不更改配置文件 1 # Path to the data ...

  3. 减少Java垃圾的产生,降低内存使用量

    1.尽量少使用静态的变量,因为它会一直占用内存, 2.尽量少使用String字符串去做拼接,相加.因为String是定长的每次相加都会产生新的临时对象,生成垃圾对象,尽量使用StringBuffer, ...

  4. 深度学习论文笔记:Deep Residual Networks with Dynamically Weighted Wavelet Coefficients for Fault Diagnosis of Planetary Gearboxes

    这篇文章将深度学习算法应用于机械故障诊断,采用了“小波包分解+深度残差网络(ResNet)”的思路,将机械振动信号按照故障类型进行分类. 文章的核心创新点:复杂旋转机械系统的振动信号包含着很多不同频率 ...

  5. less 语法特性翻译稿 - 特性快速预览部分

    原文地址 http://lesscss.cn/features/ 概述 作为CSS的一种扩展语法,Less不仅仅向后兼容CSS,新的特性也是基于CSS现有语法.这使得学习Less变得容易,如果你有所怀 ...

  6. Amazon 成功的秘訣是…

    從任何的標準去看,今日的 Amazon,都是一家超級成功的企業 — 它的線上書城和其他 B2C 電子商務業務,全球第一,年營業額超過 200 億美金.它的 AWS (Amazon Web Servic ...

  7. 如何理解IPD+CMMI+Scrum一体化研发管理解决方案之CMMI篇

    如何快速响应市场的变化,如何推出更有竞争力的产品,如何在竞争中脱颖而出,是国内研发企业普遍面临的核心问题,为了解决这些问题,越来越多的企业开始重视创新与研发管理,加强研发过程的规范化,集成产品开发(I ...

  8. scrum立会报告+燃尽图(第二周第七次)

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2252 一.小组介绍 组名:杨老师粉丝群 组长:乔静玉 组员:吴奕瑶.公冶 ...

  9. RIGHT-BICEP测试第二次

    1.Right-结果是否正确? 正确 2.B-是否所有的边界条件都是正确的? 正确 3.P-是否满足性能要求? 部分满足 4.是否满足有无括号? 无 5.数字个数是否不超过十? 只是双目运算 6.能否 ...

  10. 1st 本周工作量及进度统计

    1. 项目:英文文章词频统计 项目类型:个人项目 项目完成情况:已完成 项目日期:2016.9.6 C(类别) C(内容) S(开始时间) ST(结束时间) I(耽误时间) △(实际时间) 分析 需求 ...