第五章、python的函数

5.1.python的函数

5.1.1函数的作用

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

函数能提高应用的模块性,和代码的重复利用率。python提供了许多内建函数,比如print(),我们自己也能创建函数

这被叫做用户自定义函数

5.1.2函数的定义、调用、参数、返回

~~定义和调用

函数的定义是这样:

def foo():
     print('bar')
     print('bar2')

**注意函数体里面的语句要缩进

如果函数体内容特别少,甚至可以一行定义

def foo():   print('bar')

调用函数是这样,通过一个括号跟在变量后面,表示调用函数。括号是函数操作符。python解释器看到一个变量符号后面跟在一个()符号,就知道代码是想执行一个函数了

(当然括号在python中可以表示类的实例化)

foo()

调用函数其实就是执行函数定义里面的代码块。

 

关键字参数(函数调用)

关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。使用关键字参数允许函数调用时参数的顺序与声明时不一致,

因为python解释器能够用参数名匹配参数值。在函数调用中,关键字的参数必须跟随在位置参数的后面。传递的所有关键字参数必须与函数形参相

匹配。顺序并不重要

def add(a,b):
    return a+b

print(add(b=12,a=18))

运行结果如下:

 

 

~~函数的参数

函数经常需要有参数的。函数的参数都是放在函数定义的括号里面的。参数的命名规则基本和变量的命名规则一样。参数可以没有,也可以是多个

def foo1(x):
    print(x)

def foo2(x,y):
    print(x,y)

def foo3(name,address):
    print(name,address)

参数让函数的实现更加的灵活多变。

函数是一个独立的功能体,参数是这个功能体的输入

5.1.3.必须参数

调用add()函数时,必须参数须以正确的顺序传入函数,数量必须和声明时一样,数据类型与函数体要求一致,不然会出现类型错误

def add(a,b):
      return a+b
print(add(67))

运行结果如下:

5.1.4.默认参数

调用函数时,如果没有传递参数,则会使用默认值参数。以下实例中如果没有传入b参数,则使用默认值。如果传入参数,则使用新值。定义函数时

默认参数必须定义在位置参数之后

def add(a,b=10):
    return a+b
print(9)
print(add(b=12,a=18))

运行结果如下:

任何参数都不可以被多次赋值,默认也是只被赋值一次

i = [1,15,30]
def demo1(arg=i):
    print(arg)   
i = [4,5]

demo1()

运行结果如下:

 

 当默认值时可变对象时会有所不同,比如列表、字典。例如,下面的函数在后续调用过程中会累积(前面)传递给它的参数:

def demo2(x,a=[]):
    a.append(x)   
    print(a)

demo2(1)
demo2(3)
demo2(5)

运行结果如下:

 

5.1.5.可变参数

当你需要一个函数能处理比当初声明时更多的参数时,就可以使用可变参数;和上述2中参数不同,声明时不会命名。直接在变量名前面加上星号(*)来存放所有未命名的变量参数,返回的vartuple数据类型就是元组。如果在函数调用时没有指定参数,它就是一个空元组。我们也可以不向函数传递未命名的变量

def printinfo(argc,*vartuple):
     print("this:")
     print(argc)
     for var in vartuple:
        print("*************")
        print(var)
     return
     
printinfo(4)
printinfo(7,'woniuxy',20)

运行结果如下:

 **可变参数使用的是python组包的特性

(1)组包:python解释器自动将多个数据组长到一个容器中。

给a同时赋3个值,此时解释器就将3个值组装到一个容器中(元组)。所以并不会报错。同样的,有组包就会有解包

(2)解包:将容器中的多个数据拆出来

通过print(*a)的方式,又可以将容器中的元素逐个取出。

5.1.7.关键字可变参数

上面定义的无名的可变参数函数,在调用的时候,我们不需要也不能执行参数的名称

python还提供了一种关键字可变参数,允许在调用函数时,传入任意个含参数名的参数

def register_student(name,age,**kargs):
    print('name:',name,'age:',age,'other:',kargs)

 

函数register_student除了必选参数name和age外,还接受关键字参数kargs。在调用该函数时,可以只传入必填参数

def register_student(name,age,**kargs):
    print('name:',name,'age:',age,'other:',kargs)
 
register_student('augus',14)

#执行结果
name: augus age: 14 other: {}

也可以加上任意个数的关键字参数:

def register_student(name,age,**kargs):
    print('name:',name,'age:',age,'other:',kargs)

#方式一:
register_student('augus',14,area='beijing')
#执行结果
name: augus age: 14 other: {'area': 'beijing'}

#方式二
register_student('lrin',18,gender='m',job='Engineer')
#执行结果
name: augus age: 14 other: {'gender': 'm','job':'Engineer'}

python会在调用的时候,把这些关键走参数存到一个dict中,传给kargs.

关键字可变参数有什么作用呢?他可以扩展函数的功能。比如,在这个注册学生的函数里,我们必须要有name和age这两个参数

但是,如果调用者愿意提供更多的参数,我们也可以存储下来

类似的,如果我们已经有一个dict里面存储了注册学生的信息,我们可以这样调用:

 

def register_student(name,age,**kargs):
    print('name:',name,'age:',age,'other:',kargs)
 
students = {'city':'beijing','job':'Engineer'}
register_student('lrin',18,**students)

#执行结果如下
name: lrin age: 18 other: {'city': 'beijing', 'job': 'Engineer'}

 

综合起来

在python中定义函数,可以用必填参数、缺省参数、可变参数和关键字参数,这4中参数可以一起使用,或者只用其中某些,但是请注意,参数定义的顺序应该是:必填参数、缺省参数、可变参数和关键字可变参数

其中缺省参数可以在可变参数的后面,但是不能再关键字可变参数的后面

def func(a,b,c=0,*args,**kw):
    print('a=',a,'b=',b,'c=',c,'args=',args,'kw=',kw)

在函数调用的时候,python解释器自动按照参数位置和参数名把对应的参数传进入

>>>func(1,2)
a=1 b=2 c=0 args=() kw={}

>>>func(1,2,c=3)
a=1 b=2 c=3 args=() kw={}

>>>func(1,2,3,'a','b','c')
a=1 b=2 c=3 args=('a','b','c') kw={}

>>>func(1,2,3,'a','b',name='root',pw=123456)
a=1 b=2 c=3 args=('a','b') kw={'name':'root','pw':123456}

 

5.1.8.返回值

函数也可以有返回值,也可以没有返回值。(取款机出钞)

当然有的函数不需要返回值,就好像一个文件粉碎机,我们投入文件,就可以,不需要得到什么返回的东西,我们只要知道文件能被粉碎就行了

如果我们需要函数返回写结果,就需要使用return关键字,例子如下:

def  demo(x):
     return x*x

y = demo(100)

 这个例子里面返回的是输入的参数的平方值。返回值赋值给了变量y

但是,有时候我们需要多个返回值

def demo2(x):
     return x*x,x*x*x

y,z = demo2(4)
print(y)
print(z)

上述例子中返回的是输入的参数的平方值和立方值。注意返回值赋值给了变量y和z.

 

函数返回值的对象可以是任何对象

def demo3():
     return  ['xyz',78904,-45.32]

5.1.9 函数里面调用函数

我们可以在函数里面调用其他函数。但是和其他高级语言一样,python不允许我们在定义函数之前就调用它如下:

def demo1():
    print('in foo()')
    bar()
demo1()

这样子定义,解释器并不会报错。但是如果我们,条用了这个函数,就会报错,说bar函数没有定义

但是如果我们提前定义了,看会不会还是报错:

def bar():
    print("this is top")

def demo1():
    print('in foo()')
    bar()
demo1()

其实,我们把bar()函数的定义,放在demo1()函数后面的定义 

def demo1():
    print('in foo()')
    bar()
    
def bar():
    print("this is top")    
    
demo1()

这是因为我们在定义demo1函数的时候,并没有调用它,它里面的代码其实还没有执行。我们在最后调用demo1函数的时候,里面的bar函数已经定义了。

5.1.10函里面定义函数

我们还可以在函数里面定义另一个函数,像这样

def demo1():
    def bar():
        print('bar()called')
    print('foo() called')
    bar()

demo1()

 执行效果和外部定义一样。

区别在于,函数A内部定义的函数B,只能在函数A的内部使用

5.1.10python内置函数

python中内置了许多函数,我们之间调用他们即可

>>>len([1,2,3,4,5])
5
>>>max([1,2,3,4,5])
5
>>>min([1,2,3,4,5])
1
>>>len((1,2,3,4,5))
5
>>>max([1,2,3,4,5])
5
>>>min((1,2,3,4,5))
1

5.1.11变量的作用域

下面是一段代码,注意这段代码中有一个函数funcx(),在函数的前面也有一个变量x=2

x = 2
def funcx():
    x=9
    print('this x is in the funcx:-->',x)
funcx()
print("_____________________")
print("_____________________")

运行结果如下:

从输出看,运行funcx(),输出了funcx()里面的变量x值为9

然后执行代码最后一行,输出了funcx()外面的变量值为2

特别要关注的是,前一个x输出的是函数内部的变量x;后一个x输出的是函数外面的变量x.

两个变量彼此没有互相影响,虽然都是x。从这里看出,两个x各自在各自的领域内起作用,函数

里面的变量称之为局部变量。函数外面的那个变量我们称之为全局变量

 

如果我们要在函数里面使用外面定义的全局变量,可以这样:

x = 2
def funcx():
    global x 
    x = 9
    print("this x is in the funcx:-->",x)
    
funcx()
print("____________________")
print("this x is out of funcx:-->",x)

以上两段代码的不同之处在于,后者在函数内多了一个global x,这句话的意思是在声明x是全局变量,也就是说这个x跟函数外面的那个x是同一个,接下来将x的引用对象变成了9。所以就出现了下面结果

 

posted @ 2019-07-21 21:27  酒剑仙*  阅读(513)  评论(0编辑  收藏  举报