betway必威-betway必威官方网站
做最好的网站

betway必威官方网站函数介绍及使用,学习笔记4

一、函数定义

1 def name( parameters):   #没有参数括号内可以为空
2     "函数描述"                   #其实就是注释
3     <代码块>              
4     return [expression]   #没有返回值可以不加[]内容,也可以省略return

def是定义函数的关键字,name是函数名,parameters是形参

函数描述可以省略,但建议要有

expression是返回值,可以没有返回值,也可以没有retrun。

函数在return处结束。

1.编程方式分:面向对象、面向过程、函数式编程

【函数介绍及使用】

二、传参过程

这里需要了解几个名词:位置参数、关键参数、默认参数

1.位置参数:按照函数形式参数的顺序传递参数

def func(x,y):
    print("x={0} y={1}".format(x,y))

func(3,4)
func(4,3)

#输出:
x=3 y=4
x=4 y=3

可以发现,位置参数的使用相当于C语言当中的函数调用方式。

2.关键参数:指的是在传递参数时,不必考虑形式参数的具体先后顺序,以“形式参数=实际参数”的形式传参。

def func(x,y):
    print("x={0} y={1}".format(x,y))

func(y=3,x=4)

#输出结果:
x=4 y=3

3.默认参数:如果函数有默认参数,允许调用函数时不对默认参数传参(这时形参为默认值)

def text2(x,y=2):#y为默认参数,非必须传递
    print(x,y)

text2(1)   #可以这样调用
text2(1,3) #也可以这样调用

#输出结果:
1 2
1 3

 

为什么要用函数?

  1、减少代码量

  2、保持一致性

  3、易维护

4.参数组

如何向函数传递一个元组呢?

需要参数组

def text3(*args):
    print(args)

text3(1,2,3)  #当使用参数组时,调用函数可以不传参
#输出:
(1,2,3)

形参中*args是参数组,可以接收数量不固定的参数,也可以接收0个参数,并将这些参数组成一个元组在函数中使用。

参数组可以在参数个数不确定的情况下使用。

2.区分
面向对象----》类----》class
面向过程----》过程----》def
函数式编程----》函数----》def

一、函数的定义和使用

1
2
3
4
5
6
def test(参数):
        
    ...
    函数体
    ...
    return 返回值

函数的定义:

    def:表示函数的关键字

    函数名:以后可以根据函数名调用函数,test可以作函数名

    函数体:中间可以做一系列的运算

    参数:为函数提供数据

    返回值(return):当函数执行完毕后,可以给调用者返回数据。 多个返回元组形式,单个为原形式

betway必威官方网站 1betway必威官方网站 2

def test(x):       # x代表形参
    '''
    2*x 1
    :param x:整形数字
    :return:返回计算结果
    '''
    y = 2*x 1
    return y
print(test)     # 打印test的内存地址
p = test(3)     # test()表示运行,函数名加小括号,要重新赋值变量
print(p)

View Code

形参和实参

      形参不占用内存空间,调用时才会占用内存,在调用结束后,才会被释放。实参是给实参进行赋值

 1 def test(x):       # x代表形参
 2     '''
 3     2*x 1
 4     :param x:整形数字
 5     :return:返回计算结果
 6     '''
 7     y = 2*x 1
 8     return y
 9 p = test(3)     # test()表示运行名为test函数,3代表实参,给x进行赋值
10 print(p)

 

    位置参数:位置要一一对应,不能缺也不能多且不能给同一个形参赋予多个值(会报错)

    关键字参数:位置无需固定,但是缺一不行多一也不行  

 

      位置参数必须在关键字参数的左边

 1 def test(x,y,z):#x=1,y=2,z=3
 2     print(x)
 3     print(y)
 4     print(z)
 5 
 6 # 位置参数,必须一一对应,缺一不行多一也不行
 7 test(1,2,3)
 8 
 9 # 关键字参数,无须一一对应,缺一不行多一也不行
10 test(y=1,x=3,z=4)
11 
12 # 位置参数必须在关键字参数左边
13 test(1,y=2,3)#报错
14 test(1,3,y=2)#报错
15 test(1,3,z=2)
16 test(1,3,z=2,y=4)#报错
17 test(z=2,1,3)#报错
18 
19 位置参数和关键字参数一起也不能给同一参数赋多个值(会报错)
20 不能缺也不能多

    默认参数  如果之前给了一个值一个参数,再赋予这个值一个参数,则这个值原有的参数会被覆盖掉

def handle(x, type='mysql'):
    print(x)
    print(type)

handle('hello')                # 调用handle函数,x赋值为hello,type有了默认参数
handle('hello', type='sqlite') # x赋值,type用关键字重新赋值   
handle('hello', 'sqlite')      # 用位置一一对应关系赋值,覆盖type原来的值

结果

hello
mysql                   
hello
sqlite
hello
sqlite    

    参数组(*args列表,**kwargs字典) 非固定长度参数  *args是以元祖的形式表达

def test(x, *args):
    print(x)
    print(args)


test(1)                 # 只传入x的值,*args默认为空,元组形式
test(1, 2, 3, 4, 5)           # 传入x的值后,位置关系对应后,2 3 4 5对应*args以元组形式表达
test(1, {"name": "alex"})       # 传入x的值后,有一个字典,整体传入
test(1, ["x", "y", "z"])       # 传入x的值后,有一个列表,整体传入 
test(1,*["x","y","z"])         # 传入x的值后,列表前面加了个*,则表示遍历,逐一出现表达
test(1,*("x","y","z"))        # 同上,注意表现形式

结果

1            
()              
1
(2, 3, 4, 5)
1
({'name': 'alex'},)
1
(['x', 'y', 'z'],)
1
('x', 'y', 'z')
1
('x', 'y', 'z')

     **kwargs

def test(x, **kwargs):
    print(x)
    print(kwargs)       以字典的形式表达

test(1, y=2, z=3)     #y,z为key 后面均为值
test(1,y=2,z=3,z=4)   #会报错:一个参数不能传俩个值

结果
1
{'y': 2, 'z': 3}     

     *args,**kwargs同时存在,扩展性

def test(x,*args,**kwargs):
    print(x)
    print(args,args[-1])
    print(kwargs,kwargs.get('y'))
# test(1,1,2,1,1,11,1,x=1,y=2,z=3)   #报错,x传了多个值
test(1, 1, 2, 1, 1, 11, 1, y=2, z=3) #1传给x,中间位置参数给*args,关键字参数给**kwargs
test(1,*[1,2,3],**{'y':1})           #1传给x,*[1,2,3]传给*args遍历传,**{'y':1}传给**kwargs

结果
1                                    
(1, 2, 1, 1, 11, 1) 1
{'y': 2, 'z': 3} 2
1
(1, 2, 3) 3
{'y': 1} 1

    全局变量(大写)

    定义:没有缩进的变量

    局部变量(小写)

    定义:子程序下定义的变量

betway必威官方网站 3betway必威官方网站 4

name = 'lhf'                 # 这里就指全局变量


def change_name():
    name = '帅了一比'      # 这里就指局部变量
    print('change_name', name)


change_name()
print(name)    

结果
change_name 帅了一比
lhf

View Code

 global声明是全局变量,nolocal指定上一级变量

      如果函数的内容无global关键字

      - 有声明局部变量

betway必威官方网站 5betway必威官方网站 6

NAME = ["产品经理","廖波湿"]
def qupengfei():
    NAME = "自己"
    print('我要搞', NAME)
qupengfei()

结果
我要搞 自己

View Code

      - 无声明局部变量

betway必威官方网站 7betway必威官方网站 8

NAME = ["产品经理","廖波湿"]
def qupengfei():
     NAME.append('XXOO')
     print('我要搞', NAME)
qupengfei()

View Code

 如果函数的内同有global关键字

      - 有声明局部变量

betway必威官方网站 9betway必威官方网站 10

NAME = ["产品经理","病毒尖儿"]
def qupengfei():
    global NAME
    NAME = "自己"
print('我要搞', NAME)
qupengfei()
结果
我要搞 ['产品经理', '病毒尖儿']
# 错误示例
NAME = ["产品经理","病毒尖儿"]
def qupengfei():
    NAME = "自己"            # 有局部变量,报错 
    global NAME               # 不能在下面
print('我要搞', NAME)
qupengfei()

View Code

betway必威官方网站 11betway必威官方网站 12

NAME = ["产品经理","病毒尖儿"]
def qupengfei():
    global NAME
    NAME = "自己"
print('我要搞', NAME)
qupengfei()
结果
我要搞 ['产品经理', '病毒尖儿']
# 错误示例
NAME = ["产品经理","病毒尖儿"]
def qupengfei():
    NAME = "自己"            # 有局部变量,报错 
    global NAME               # 不能在下面
print('我要搞', NAME)
qupengfei()

View Code

      - 无声明局部变量

betway必威官方网站 13betway必威官方网站 14

NAME = ["产品经理", "病毒尖儿"]


def qupengfei():
    global NAME
    NAME = ["三毛"]
    NAME.append('XXOO')
    print('我要搞', NAME)


qupengfei()

结果
我要搞 ['三毛', 'XXOO']

View Code

优先读取局部变量,能读取全局变量,但无法对全局变量重新赋值NAME=“fff”,但是对于可变类型,可以对内部元素进行操作

      如果函数中有glabal关键字,变量本质上就是全局的那个变量,可读取可赋值 NAME=“fff”

5.字典的传递

def text5(**kwargs):#向函数传递字典
    print(kwargs)
text5()                   #调用函数时可以不传参
text5(name="liuwei",sex="man",index=3) #标准的传参传字典过程

#输出结果:
{“name”:"liuwei","sex":"man","index":3} #3是int型

这种传参方式很容易和关键参数混淆。

 

  递归函数

    自己调用自己的函数,则为递归

    特性:必须有一个明确的结束条件

       每次进入深一层递归时,问题规模都应有所减少

def calc(n):
    print(n)
    if int(n / 2) == 0:
        return n # 当上面的条件成立后一个真值,返回到函数
    res = calc(int(n / 2))    
    print(n,res) 
    return res # 返回res的值,要将真值一层一层传递回去

calc(10)                                                

     匿名函数   用lambda去定义

例1:

betway必威官方网站 15betway必威官方网站 16

def calc(x):
    return x 1
res=calc(10)
print(res)          # 输出结果
print(calc)         # 输出calc这个函数的内存地址
print(lambda x:x 1)# 输出lambda这个表达式的内存地址
func = lambda x:x 1# x代表形参,x 1为返回值
print(func(10))     # 给lambda表达式传入值,输出结果

"""
结果
11
11
<function <lambda> at 0x000001F6D84897B8>
11
"""

View Code

例2:

betway必威官方网站 17betway必威官方网站 18

name = "alex"
def change_name(x):
    return name "_sb"
res = change_name(name)
print(res)

func = lambda x:x "_sb"
res = func(name)
print(res)

View Code

    函数式编程

      函数接收的参数是一个函数名

    高阶函数

      1、把函数当作一个参数传给另一个函数

      2、返回值中包含参数

betway必威官方网站 19betway必威官方网站 20

def bar():
    print('from bar')
def foo():
    print('from foo')
    return bar
n = foo()
n()

返回值中包含函数

 

 

6.多种类型参数传递和优先级问题

def text6(a,b=2,*args,**kwargs):
    print(a)
    print(b)
    print(args)
    print(kwargs)
text6("woo",3,sex="m",hobby="aa")

#输出结果:
woo
3
()
{'sex': 'm', 'hobby': 'aa'}

在定义函数时,形参应当遵循 普通参数-->默认参数-->参数组-->字典参数 的顺序

在调用函数时,实参应当遵循 位置参数-->关键参数-->参数组-->字典参数 的顺序

这样做为的是避免混淆。

3.编程语言中函数的定义:

7.如何传递列表

(1)位置参数

betway必威官方网站 21betway必威官方网站 22

def func(names):
    print(names)
    names[1] = 'jujinyi'

names = ['aaron','jim']
func(names)
print(names)

#输出:
['aaron', 'jim']
['aaron', 'jujinyi']

View Code

永久性改变了列表的值。如果想要对列表附件操作,可以用切片的方式

betway必威官方网站 23betway必威官方网站 24

def func(names):
    print(names)
    names[1] = 'jujinyi'

names = ['aaron','jim']
func(names)
print(names)

#输出:
['aaron', 'jim']
['aaron', 'jim']

View Code

(2)关键参数

本质上和位置参数是一样的,没有什么区别

(3)元组传递

将传进去的元组使用list函数

betway必威官方网站 25betway必威官方网站 26

def func(*toppings):
    toppings = list(toppings)
    print(toppings)

func('mushrooms','extra','cheese')
func('mushrooms','extra')

#输出:
['mushrooms', 'extra', 'cheese']
['mushrooms', 'extra']

View Code

函数是逻辑结构化和过程化的一种编程方法

三、返回值

可以返回任何类型。基本数据类型(字符、整型等),列表(元组),字典,集合,甚至函数名也可以被返回

如果返回多个值,所有的返回值会被封装成一个元组返回

 

四、局部变量和全局变量

4.过程是没有返回值的函数

1.定义 

全局变量是定义在函数体外面的变量,局部变量是定义在函数体内的变量

全局变量的作用域和生命周期从被定义开始直到程序结束,而局部变量则是从被定义到所在的函数结束。

 

2.全局变量的使用

全局变量当然可以在函数体外随意使用,在函数体内还会一样吗?

a=6
c=[1,2,3,4,5]
def text():
    a=5
    b=10
    c[1]=0
    print("a={0},b={1},c={2}".format(a,b,c))

text()
print("a={0},b={1},c={2}".format(a,b,c))

运行结果报错,问题出在最后一行:NameError: name 'b' is not defined。因为变量b是局部变量,只存在于函数内,在函数外已经不存在了。

改一下:

print("a={0},c={1}".format(a,c))

#输出结果:
a=5,b=10,c=[1, 0, 3, 4, 5]
a=6,c=[1, 0, 3, 4, 5]

发现了什么问题?a和c同为全局变量,都在函数内经过了修改,但是c被永久性的修改,a只是在函数内被修改,出来后被复原了。

这是因为列表c在函数内外都是原件,而整型a在函数内修改,修改的是函数拷贝的临时变量,保证了全局变量的安全性。

因此,可以用函数直接对列表、字典、集合等复杂类型的全局变量进行操作,但是无法在函数内对基本类型(如int,str,float等)的全局变量进行修改。

5.使用函数的优点:

3.如何在函数内修改基本类型的全局变量?

Python提供了global关键字来进行声明

a=6
def text():
    global a #声明要在函数内修改全局变量
    a=10
    print(a)

text()
print(a)

#运行结果:
10
10

这样,全局变量就被修改了。

虽然有这种方法,但是如果没有这种强烈需求的话,尽量不要这么做。

1)代码可重复使用
2)代码可保持一致性
3)可扩展性

五、高阶函数和嵌套函数

1.以下两个条件满足其一就可称之为高阶函数:

(1)把函数名当做实参传递给另一个函数

(2)返回值中包含函数名

2.函数可以嵌套,即函数体内可以定义函数

 

六、递归

定义:如果在函数内部可以调用自己,那么就称之为递归函数

 

递归需要满足的特性:

1.必须有一个明确的结束条件 (python内有预定的最大递归层数:999,程序的保护机制)
2.每深入一层时,问题的规模应该减小
3.递归的效率不高,递归层次过多容易导致栈溢出

 

6.

当一个函数/过程没有使用return显示的定义返回值时,python解释器会隐式的返回None,所以在python中即便是过程也可以算作函数。

 

7.返回值
返回值的数等于0,返回None
返回值的数等于1,返回object
返回值的数大于1,返回tuple

本文由betway必威发布于编程开发,转载请注明出处:betway必威官方网站函数介绍及使用,学习笔记4

TAG标签: betway必威
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。