Python笔记(四):函数

定义

  函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需要调用其函数名即可。

特性:

  1、减少重复代码

  2、使程序变得可扩展

  3、使程序变得易维护

语法定义:

1 def sayhi():    # 函数名
2     print("hello,I'm nobody!")
3 
4 sayhi()     # 调用函数

函数参数

  参数可以让函数更灵活,不止能做死的动作,还可以根据调用时传参的不同来决定函数内部的执行流程

1 def calc(x,y):
2     res = x**y
3     return res  # 返回函数执行结果
4 
5 a,b = 3,5
6 c = calc(a,b)   # 结果赋值给c变量
7 print(c)

形参变量:

  只有只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元,因此,形参只在函数内部有效。

  函数调用结束返回主调用函数后则不能再使用该形参变量

实参:

  可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,他们都必须有确定的值,以便把这些值传给形参

  因此,应预先用赋值、输入等办法使参数获得确定值

def calc(x,y):      # x,y 是形参
    res = x**y
    return res

a,b = 3,5
c = calc(a,b)   # a,b 是实参
print(c)

默认参数:

 1 def stu_register(name,age,country,course):
 2     print("------注册学生信息--------")
 3     print("姓名:", name)
 4     print("age:", age)
 5     print("国籍:", country)
 6     print("课程:", course)
 7 
 8 stu_register("望山跑",22,"CN","python_develop")
 9 stu_register("张三",21,"CN","linux")
10 stu_register("刘老根",25,"CN","linux")
11 
12 # 参数country基本都是“CN”,就可以把country设为默认参数
13 
14 def stu_register(name,age,course,country="CN"):
15     print("------注册学生信息--------")
16     print("姓名:", name)
17     print("age:", age)
18     print("国籍:", country)
19     print("课程:", course)
20 
21 stu_register("望山跑",22,"python_develop")     # 调用时不指定,默认就是CN
22 stu_register("张三",21,"linux")
23 stu_register("刘老根",25,"linux",country="U.S.")   # 调用时指定,就是指定值

关键参数:

  正常情况下,给函数传参数要按顺序,不想按顺序就可以用关键参数,只需要指定函数名即可(指定了参数名的参数就叫关键参数)

  关键参数必须放在位置参数(以位置顺序确定对应关系的参数)之后

 1 def stu_register(name,age,course="PY",country="CN"):
 2     print("------注册学生信息--------")
 3     print("姓名:", name)
 4     print("age:", age)
 5     print("国籍:", country)
 6     print("课程:", course)
 7 
 8 stu_register("zhang",23,course="python",country="DE")
 9 stu_register("张三",country="KSA",course="linux",age=22)
10 # stu_register("张三",country="UK",22,course="linux")   # 报错 关键参数在位置参数之前
11 # stu_register("zhangsan",22,age=22,country="KOR")  # 报错 给age赋两次值

非固定参数:

  若函数定义时不确定用户想传入多少个参数,可以使用非固定函数

 1 def stu_register(name,age,*args):   # *args会把多传入的参数变成一个元组形式
 2     print(name,age,args)
 3 
 4 stu_register("alex",22)
 5 # 输出
 6 # alex 22 ()    # 最后这个()就是args,因为没传值,所以是空
 7 
 8 stu_register("Jack",23,"CN","linux")
 9 # 输出
10 # Jack 23 ('CN', 'linux')
11 
12 
13 def stu_register(name,age,*args,**kwargs):  # *kwargs会把多传入的参数变成一个dict
14     print(name,age,args,kwargs)
15 
16 stu_register("alex",22)
17 # 输出
18 # alex 22 () {} # 后面的{}就是kwargs,因为没值,所以为空
19 
20 stu_register("jack",23,"CN","python",sex="male",province="shandong")
21 # 输出
22 # jack 23 ('CN', 'python') {'sex': 'male', 'province': 'shandong'}

返回值

  函数外部的代码要想获取函数的执行结果,就可以在函数里用return语句把结果返回

 1 def stu_register(name,age,course="PY",country="CN"):
 2     print("------注册学生信息--------")
 3     print("姓名:", name)
 4     print("age:", age)
 5     print("国籍:", country)
 6     print("课程:", course)
 7     if age > 22:
 8         return False
 9     else:
10         return True
11 
12 registriation_status = stu_register("zhang",23,course="linux",country="UK")
13 
14 if registriation_status:
15     print("注册成功")
16 else:
17     print("too old to be a student....")

注意:

  1、函数在执行过程中只要遇到return语句,就会停止执行并返回结果,可以理解为return语句代表着函数的结束

  2、如果未在函数中指定return,那这个函数的返回值为None

全局与局部变量

 1 name = "Alex Li"
 2 
 3 def change_name(name):
 4     print("before change:",name)
 5     name = "金角大王"
 6     print("after change:",name)
 7 
 8 change_name(name)
 9 
10 print("在外面看看name改了吗?",name)
11 
12 # 输出
13 # before change: Alex Li
14 # after change: 金角大王
15 # 在外面看看name改了吗? Alex Li
 1 # 不用传name值到函数里,也可以在函数里调用外面的变量
 2 name = "Alex Li"
 3 
 4 def change_name():
 5     name = "金角大王"
 6     print("after change:",name)
 7 
 8 change_name()
 9 
10 print("在外面看看name改了吗?",name)
11 
12 # 输出
13 # after change: 金角大王
14 # 在外面看看name改了吗? Alex Li

函数内部对变量的更改对函数外的变量无影响

  在函数中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量

  全局变量作用域是整个程序,局部变量作用域是定义该变量的函数

  当全局变量与局部变量同名时,在定义局部变量的函数内,局部变量起作用;在其他地方,全局变量起作用

作用域(scope):

  程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域

如何在函数里修改全局变量

 1 name = "Alex Li"
 2 
 3 def change_name():
 4     global name
 5     name = "金角大王"
 6     print("after change:",name)
 7 
 8 change_name()
 9 
10 print("在外面看看name改了吗?",name)
11 
12 # 输出
13 # after change: 金角大王
14 # 在外面看看name改了吗? 金角大王
15 
16 # global name 的作用就是要在函数里声明全局变量name,意味着最上面的name = "Alex Li"即使不写,程序最后面的print也可以打印name

嵌套函数

  在最外层无法调用内层函数

 1 name = "alex"
 2 
 3 def change_name():
 4     name = "alex2"
 5 
 6     def change_name2():
 7         name = "alex3"
 8         print("第3层打印:",name)
 9 
10     change_name2()  # 调用内层函数
11     print("第2层打印:",name)
12 
13 change_name()
14 print("最外层打印:",name)
15 
16 # change_name2()    # NameError: name 'change_name2' is not defined
17 
18 # 输出
19 # 第3层打印: alex3
20 # 第2层打印: alex2
21 # 最外层打印: alex

匿名函数

  匿名函数就是不需要显式的指定函数名,主要和其他函数搭配使用

1 def calc(x,y):
2     return x**y
3 
4 print(calc(2,5))
5 
6 # 匿名函数
7 
8 calc = lambda x,y:x**y
9 print(calc(2,5))
1 # 和其他函数搭配
2 res = map(lambda x:x**2,[1,3,5,7,9])
3 for i in res:
4     print(i)

高阶函数

  变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称为高阶函数

满足以下任意一个条件,既是高阶函数:

  接受一个或多个函数作为输入

  return返回另外一个函数

1 def add(x,y,f):
2     return f(x) + f(y)
3 
4 res = add(3,-6,abs)
5 print(res)

递归

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

 1 def calc(n):
 2     print(n)
 3     if int(n/2) == 0:
 4         return n
 5     return calc(int(n/2))
 6 
 7 calc(10)
 8 
 9 # 输出
10 # 10
11 # 5
12 # 2
13 # 1
 1 def calc(n):
 2     v = int(n/2)
 3     print(v)
 4     if v > 0:
 5         calc(v)
 6     print(n)
 7 
 8 calc(10)
 9 
10 # 输出
11 # 5
12 # 2
13 # 1
14 # 0
15 # 1
16 # 2
17 # 5
18 # 10

递归特性:

  1、必须有一个明确的结束条件

  2、每次进入更深一层递归时,问题规模相比上次递归都应有所减少

  3、递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以递归调用的次数过多,会导致栈溢出)

递归用途:

  解决很多算法问题,把复杂的问题分成一个个小问题,一一解决

# 二分查找

data = [1,3,4,6,7,9,11,13,14,18,21,23,25,27,30,32,37]

def binary_search(dataset,find_num):
    print(dataset)

    if len(dataset) > 1:
        mid = int(len(dataset)/2)
        if dataset[mid] == find_num:    # find it
            print("找到数字",dataset[mid])
        elif dataset[mid] > find_num:   # 要找的数比中间数小,即,在mid左边
            print("\033[31;1m找的数在mid[%s]左面\033[0m" % dataset[mid])
            return binary_search(dataset[0:mid],find_num)
        else:   # 找的数在mid右面
            print("\033[32;1m找的数在mid[%s]右面\033[0m" % dataset[mid])
            return binary_search(dataset[mid+1:],find_num)
    else:
        if dataset[0] == find_num:  # find it
            print("找到数字啦",dataset[0])
        else:
            print("没得分了,要找的数字[%s]不在列表里" % find_num)


# binary_search(data,66)
binary_search(range(101),66)
 1 # 阶乘
 2 # n! = n * (n-1)!   # 任何大于1的自然数n阶乘表示方法
 3 
 4 def factorial(n):
 5     # if n > 0:
 6     #     return n * factorial(n-1)
 7     # else:
 8     #     return 1
 9     if n == 0:  # 是0的时候,就运算完了
10         return 1
11     return n * factorial(n-1)   # 每次递归相乘,n值都较之前小1
12 
13 print(factorial(5))

 内置函数

 

  详解:    https://docs.python.org/3/library/functions.html?highlight=built#ascii

  1 # help()     # 帮助
  2 
  3 # all(i)      # iterable    如果i中所有值都为真,返回True,如果i为空,返回True
  4 print(all([0,1]))   # False
  5 # any(i)      # 如果i中任一值为真,返回True,如果i为空,返回False
  6 print(any([0]))     # False
  7 
  8 # ord('a')    # 返回表示该字符的Unicode代码点的整数
  9 # chr(97)     # 由ASCII对应位置找到元素
 10 # ascii(o)      # 非ASCII码会转成Unicode
 11 
 12 # hex()   # 把一个数转成十六进制
 13 # oct()   # 转成八进制
 14 # bin()   # 二进制
 15 
 16 # dict()  # 转换成字典
 17 # bool()  # 判断一个值的真假
 18 # int()
 19 # str()
 20 # float()
 21 # tuple()
 22 # list()
 23 # set()
 24 # frozenset()   # 不可变集合
 25 # bytes()
 26 # id()
 27 # format()
 28 # len()
 29 # type()
 30 
 31 # abs(n)      # 返回绝对值
 32 # min()   # 列表里取最小值
 33 # max()   # 最大值
 34 # complex()   # 变成复数
 35 print(complex(3,5))     # (3+5j)
 36 # round()     # 保留几位小数
 37 print(round(1.832433))    # 2
 38 print(round(1.832433,3))  # 1.832
 39 # sum()   # 求和
 40 # divmod(x,y)     # 返回元组(商,余数)
 41 print(divmod(10,3))     # (3, 1)
 42 # pow(x,y)   # x**y
 43 
 44 # range()
 45 # enumerate   # 枚举
 46 # hash()    # 哈希
 47 
 48 # dir()   # 打印当前程序所有变量
 49 # vars()    # 当前所有变量,和变量的值
 50 # locals()    # 一般函数内部使用,打印函数的局部变量
 51 # globals()   # 打印全局变量
 52 
 53 # slice()     # 切片
 54 >>>l = list(range(10))
 55 >>>s = slice(1,7,2)
 56 >>>l[s]    # 相当于预先制定好切片规则
 57 
 58 # sorted()  # 排序
 59 # reversed()  # 默认反转
 60 l = [1,3,6,4,9,2]
 61 print(sorted(l))
 62 
 63 d = {}
 64 for i in range(20):
 65     d[i] = i-50
 66 print(d)
 67 
 68 d[10] = 99
 69 print(sorted(d.items(),key=lambda x:x[1]))  # 按value排序
 70 print(sorted(d.items(),key=lambda x:x[1],reverse=True))
 71 
 72 # input()
 73 # print()     # print(self, *args, sep=' ', end='\n', file=None)
 74 for i in range(5):
 75     print(i)
 76     print(i,end=',')    # 0,1,2,3,4,
 77 
 78 print('abc','123')  # abc 123 默认是' '
 79 print('abc','123',sep='--')     # abc--123
 80 
 81 msg = "又回到最初的起点"
 82 f = open('print_test','w',encoding='utf-8')
 83 print(msg,"jiyizhong你青涩的脸",sep='|',end='',file=f)
 84 print(msg,"jiyizhong你青涩的脸",sep='|',end='',file=f)
 85 
 86 # open()
 87 
 88 # eval()  # 处理单行代码  可以拿到返回值
 89 f = "1+3/2"
 90 print(eval(f))
 91 # exec()  # 可以处理多行代码 但拿不到返回值
 92 
 93 # memoryview()    # 大数据copy用
 94 # bytearray() # 字符串变成bytearrary后,可以修改
 95 s = 'abcd路飞'
 96 print(s[0])     # a
 97 # s[0]='f'    TypeError: 'str' object does not support item assignment
 98 s2 = bytearray(s.encode('utf-8'))
 99 print(id(s2))   # 2309116684920
100 print(s2[0])    # 97
101 s2[0]=65
102 print(s2)   # bytearray(b'Abcd\xe8\xb7\xaf\xe9\xa3\x9e')
103 s2[4]=235   
104 print(s2.decode())  # Abcd뷯飞
105 print(id(s2))   # 2309116684920
106 
107 # map()   #
108 # filter()    # 过滤
109 # reduce()    # 在functools中
110 s = map(lambda x:x*x,[1,2,3,4,5])
111 print(list(s))  # [1, 4, 9, 16, 25]
112 s = filter(lambda x:x>3,[1,2,3,4,5])
113 print(list(s))  # [4, 5]
114 
115 import functools
116 s = functools.reduce(lambda x,y:x+y,[1,3,45,34,7,8])    # 98
117 s = functools.reduce(lambda x,y:x*y,[1,3,45,34,7,8])    # 257040
118 print(s)
119 s1 = functools.reduce(lambda x,y:x+y,[1,3,45,34,7,8],9)     # 107
120 print(s1)
121 
122 # callable()  # 判断是否可调用  给一个变量,判断是否是函数
123 def f():
124     pass
125 
126 print(callable(f))  # True
127 
128 # repr()  
129 
130 # zip()
131 a = [1,3,5,0,-2]
132 b = ['a','b','c']
133 print(list(zip(a,b)))   # [(1, 'a'), (3, 'b'), (5, 'c')]
134 
135 # setattr()   # 后面讲
136 # getattr()
137 # hasattr()
138 # delattr()
139 # next()
140 # object()
141 # staticmethod()
142 # isinstance()
143 # issubclass()
144 # super()
145 # iter()
146 # property()
147 # classmethod()
148 # compile()   # 编译代码用
149 # __import__()    # 模块用
View Code
 

猜你喜欢

转载自www.cnblogs.com/wuyinglianjianjue/p/10332195.html