函数的一些简单笔记

函数

数学定义:y=f(x),y是x的函数,x是自变量

Python函数:
    1、有若干个语句组成的语句块、函数名称、参数列表构成,它是组织代码的最小单元
    2、完成一定的功能
    
函数的作用:
    1、结构化编程对代码的基本的封装,一般按照功能组织一段代码
    2、封装的目的为了复用,减少冗余代码
    3、代码更加简洁美观、可读易懂

函数的分类:
    1、内建函数,如max()、reversed()等
    2、库函数,如math.ceil()等

函数定义、调用

def语句定义函数:
    def 函数名(参数列表):
        函数体(代码块)
        [return 返回值]
        
    1、函数名就是标识符,命名要求一样
    2、语句块必须缩进,约定4个空格
    3、Python的函数没有return语句,隐式会返回一个None值
    4、定义中的参数列表成为形式函数,只是一种符号表达,简称形参

调用:
    1、函数定义,只是声明了一个函数,它不会被执行,需要调用
    2、调用的方式,就是函数名加上小括号,括号内写上参数
    3、调用时写的参数是实际参数,是实实在在传入的值,简称实参

函数举例
    def add(x,y):
        result = x+y
        return result
    out = add(4,5)
    print(out)
    
    1、上面只是一个函数的定义,有一个函数叫做add,接收2个参数
    2、计算的结果,通过返回值返回
    3、调用通过函数名add加2个参数,返回值可使用变量接收
    4、定义需要在调用前,也就是说调用时,已经被定义过了,否则抛NameError异常
    5、函数是可调用对象,callable()

函数参数:
    参数调用时传入的参数要和定义的个数相匹配(可变参数例外)
    
    位置参数:
        1def f(x,y,z)调用使用f(1,3,5)
        2、按照参数定义顺序传入实参
        
    关键字参数:
        1def f(x,y,z)调用使用f(x=1,y=3,z=5)
        2、使用形参的名字来传入实参的方式,如果使用了形参名字,那么传参顺序就可和定义顺序不同
        
        f(z=None,y=10,x=[1])
        f((1),z=6,y=4.1)
        备注:要求位置参数必须在关键字参数之前传入,位置参数是按位置对应的
    
    参数默认值:
        1、定义时,在形参后跟上一个值
        2def add(x=4,y=5):
               return x+y
        add(6,10),add(5,y=9),add(x=3),add(),add(y=8),add(x=1,y=2),add(y=2,x=100)
        
        举例:
            定义一个函数login,参数名称为host、port、username、password
            def login(host='127.0.0.1',port='80',username='eric',password='123456'):
                print('{}:{}@{}/{}'.format(host,port,username,password))
            login()
            login('127.0.0.1',80,'eric','123456')
            
            login('localhost',username='root')
            
            login('localhost',port=3306,password='123456')
            
            login(port=80,password='123456',host='172.16.15.100')
            
    可变参数:
        累加求和的问题
        def add(nums):
            sum = 0
            for x in nums:
                sum += x
            return sum
        add([1,3,5])
        add((2,4,6))
        传入一个可迭代对象,迭代元素求和
        
        一个形参可以匹配任意个参数
        
    位置参数的可变参数:
        有多个数,需要累加求和
        def add(*nums):
            sum = 0
            print(type(nums))
            for x in nums:
                sum += x
            print(sum)
        In [68]: add(3,6,9)
        <class 'tuple'>
        18 
    在形参前使用*表示该形参是可变参数,可以接收多个实参

函数的返回值

举例:
def showplus(x):
    print(x)
    return x+1
showplus(5)
执行结果为:5

def showplus(x):
	if x > 3:
			return ">3"
	else:
			return "<=3"
print(showplus(5))
返回:>3


例子:
def showplus(x):
	if x > 3:
			return x
	else:
			print("{} is not greater than 3".format(x))
print(showplus(2))
返回:
2 is not greater than 3
None


def showplus(x):
	if x > 3:
			return x
	else:
			print("{} is not greater than 3".format(x))
print(showplus(5))
返回值为:5

总结:
    1、Python函数使用return语句返回“返回值”
    2、所有函数都有返回值,如果没有return语句,隐式调用return None
    3return语句并不一定是函数的语句块的最后一条语句
    4、一个函数可以存在多个return语句,但是只有一条可以被执行。如果没有一条return语句被执行到,隐式调用return None
    5、如果有必要,可以显示调用return None,可以简写为return
    6、如果函数执行了return语句,函数就会返回,当前被执行的return语句之后的其它语句就不会被执行了
    7、作用:结束函数调用、返回值

返回多个值:

def showplus():
	return [1,3,5]
showplus()
print(showplus())
打印出:[1,3,5]

def showplus():
	return 1,3,5
showplus()
print(showplus())
打印出:(1, 3, 5)

1、函数不能同时返回多个值
2return[1,3,5]是指明返回一个列表,是一个列表对象
3return 1,3,5看似返回多个值,隐式的被Python封装成了一个元组

使用解构提取出来,将更加方便和明白
def showplus():
	return 1,3,5
x,y,z = showplus()
print(x,y,z)
打印结果为:1 3 5

函数嵌套

在一个函数中定义了另外一个函数
def fn():
	def add():
			print("add")
	print("fn")
	add()
fn()
打印结果为:
    fn
    add

def fn():
	def add():
			print("add")
	print("fn")
	add()
fn()
add()#这个是会报错的,因为函数有可见范围,也就是作用域,内部的函数不能被外部直接使用,会抛出NameError异常

作用域

1、一个标识符的可见范围,这就是标识符的作用域。一般常说的是变量的作用域

x = 6
def fn():
	print(x)
fn()
返回值打印结果为:6

x = 6
def fn():
	#x = 3
	x += 1
	print(x)
fn()
注:如果把x=3注释掉,就会报语法错误
原因:x += 1其实就是x = x + 1,相当于在fn内部定义一个局部变量x,那么fn内部所有x都是这个局部变量x了,但是这个x还没有完成赋值,就被拿来做加1操作了

全局作用域:
    在整个程序运行环境中都可见

局部作用域:
    1、在函数、类等内部可见
    2、局部变量使用范围不能超过其所在的局部作用域

嵌套解构

def fn():
	o =65
	def add():
			print("add{}".format(o))
			print(chr(o))
	print("fn{}".format(o))
	add()
fn
打印结果:
    fn65
    add65
    A

def fn():
	o =65
	def add():
			o = 97
			print("add{}".format(o))
			print(chr(o))
	print("fn{}".format(o))
	add()
fn()
打印结果为:
    fn65
    add97
    a
从以上嵌套的例子可以看出:
    1、外层变量作用域在内层作用域可见
    2、内层作用域中add,如果定义了o=97,相当于当前作用域中重新定义了一个新变量o,但是这个o并没有覆盖外层作用域fn中的o
    
    
例子:
    x = 6
    def fn():
	    #x = 4
	    y = x + 1
	    #x += 1
	    print(x)
    fn()
    注:如果把x += 1前面的#号取消掉,同样还是报错,是因为x还没有完成赋值,就被拿来做加1操作了
    
全局变量global:
    x = 6
    def fn():
	    global x
	    x += 1
    fn()
    print(x)
    返回值:7
    
原因:使用global关键字的变量,将fn内的x声明为使用外部的全局作用域中定义的x;全局作用域中必须有x的定义

#x = 6
def fn():
	global x
	x = 10
	x += 1
	print(x)
fn()
print(x)
返回结果为:
    11
    11
原因:使用global关键字的变量,将fn内的声明为使用外部的全局作用域中定义的x;但是,x=10赋值即定义,x在内部作用域为一个外部作用域的变量赋值,所以x+=1不会报错,但是需要注意的是,这里的x作用域还是全局的。

global总结

x += 1这种是特殊形式产生的错误,先引用,后赋值,而python动态语言是赋值才算定义,才能被引用。在语句之前加上x=0之类赋值语句,或者使用global告诉内部作用域,去全局作用域查找变量定义。

内部作用域使用x=5之类的赋值语句会重新定义局部作用域使用的变量x,但是,一旦这个作用域中使用global声明x为全局的,那么x=5相当于在为全局作用域的变量x赋值。

global使用原则:
    1、外部作用域变量在内部最用于可见,但也不要在这个内部的局部作用域中直接使用,因为函数的目的就是为了封装,尽量与外界隔离。
    2、如果函数需要使用外部全局变量,请使用函数的形参传参解决
    3、一句话:不用global。学习知识为了深刻理解变量作用域

本文来自投稿,不代表Linux运维部落立场,如若转载,请注明出处:http://www.178linux.com/87818

(0)
上一篇 2017-10-15 18:00
下一篇 2017-10-16 08:48

相关推荐

  • Python第二周小结

    不知不觉已经正式学习接触Python两周了,第二周主要开始了Python内置数据结构的学习,包括从一开始的列表list,元组tuple,字符串string,再到后来的bytes, bytearray, 以及最后的集合set。这些数据结构可以说Python最为基础的几种类型,想要用Python写出漂亮的代码离不开对他们的熟练掌握与深刻理解。这几个结构各有各的特…

    Python笔记 2018-03-31
  • 正则表达式

    正则表达式 分类 BRE:基本正则表达式,grep,sed,vi等软件支持,vim有扩展 ERE:扩展正则表达式,egrep,grep -E ,sed  r等 PCRE:几乎所有的高级语言都是PCRE的方言或则变种, 基本语法 元字符metacharater .  匹配除换行符外任意一个字符 [abc]字符集合,只能表示一个字符的位置,匹配所包含的任意一个字…

    Python笔记 2018-05-07
  • DevOps 风向标!DevOps国际峰会6月29日正式启航!

    DOIS 大会为您呈现互联网公司与海外企业的实践经验与工具技术,聚焦 DevOps 在金融、电信、零售等行业的系统性实践。在这里我们不空谈、不务虚,实实在在的专注DevOps落地。

    2018-05-16
  • 递归函数

    递归函数 def foo(b,b1=3):print(“foo1 called “,b,b1)def foo2(c):foo3(c)print(“foo2 called”,c)def foo3(d):print(“foo3 called”)def mian():print(“…

    2018-04-16
  • 函数

    函数、参数、参数解构
    返回值、作用域
    递归函数
    匿名函数、
    生成器

    2018-04-16
  • 【福利贴-招聘】- python运维开发工程师

    职位描述  岗位职责: 1、负责公司CMDB的建设,包括资产管理、dns、工单系统、ngnix自动化、监控等的开发 2、帮助运维团队和业务团队提高自动化效率 3、维护和开发持续化集成环境; 4、负责公司运维系统的规划、选型、部署上线和日常维护管理工作; 5、负责CMDB团队的建设、管理和人才培养机制…

    Linux干货 2015-04-03