什么是函数
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。
函数的定义与调用
def my_len():s = 'hello world'length = 0for i in s:length = length + 1print(length)my_len()
Python
Copy
定义:def 关键词开头,空格之后接函数名称和圆括号(),最后还有一个":"。def 是固定的,不能变,他就是定义函数的关键字。空格 为了将def关键字和函数名分开,必须空(四声),当然你可以空2格、3格或者你想空多少都行,但正常人还是空1格。函数名:函数名只能包含字符串、下划线和数字且不能以数字开头。虽然函数名可以随便起,但我们给函数起名字还是要尽量简短,并能表达函数功能括号:是必须加的,先别问为啥要有括号,总之加上括号就对了!注释:每一个函数都应该对功能和参数进行相应的说明,应该写在函数下面第一行。以增强代码的可读性。调用:就是 函数名() 要记得加上括号。
函数的返回值
def my_len():s = 'hello world'length = 0for i in s:length = length + 1return lengthstr_len = my_len()print(str_len)
Python
Copy
return 关键字的作用
- return 是一个关键字,这个词翻译过来就是“返回”,所以我们管写在 return 后面的值叫“返回值”。
- 不写 return 的情况下,会默认返回一个 None
- 一旦遇到 return,结束整个函数。
- 返回的多个值会被组织成元组被返回,也可以用多个值来接收
Pythondef ret_demo():return 1,2,'a',['hello','world']ret = ret_demo()print(ret)
Copy
函数的参数
带参数的函数
Pythondef my_len(s):length = 0for i in s:length += 1return lengthret = my_len('hello world!')print(ret)
Copy
实际的要交给函数的内容,简称实参。
在定义函数的时候它只是一个形式,表示这里有一个参数,简称形参。
按照位置传值:位置参数
def maxnumber(x,y):the_max = x if x > y else yreturn the_maxret = maxnumber(10,20)print(ret)
Python
Copy按照关键字传值:关键字参数。
def maxnumber(x,y):the_max = x if x > y else yreturn the_maxret = maxnumber(y = 10,x = 20)print(ret)
Python
Copy位置、关键字形式混着用:混合传参。
def maxnumber(x,y):the_max = x if x > y else yreturn the_maxret = maxnumber(10,y = 20)print(ret)
Python
Copy
位置参数必须在关键字参数的前面
对于一个形参只能赋值一次默认参数。
def stu_info(name,age = 18):print(name,age)stu_info('aaron')stu_info('song',50)
Python
Copy默认参数是一个可变数据类型
def demo(a,l = []):l.append(a)print(l)demo('abc')demo('123')
Python
Copy动态参数
def demo(*args,**kwargs):print(args,type(args))print(kwargs,type(kwargs))demo('aaron',1,3,[1,3,2,2],{'a':123,'b':321},country='china',b=1)#动态参数,也叫不定长传参,就是你需要传给函数的参数很多,不定个数,那这种情况下,你就用*args,**kwargs接收,args是元祖形式,接收除去键值对以外的所有参数,kwargs接收的只是键值对的参数,并保存在字典中。
Python
Copy
命名空间和作用域
代码在运行伊始,创建的存储“变量名与值的关系”的空间叫做全局命名空间;
在函数的运行中开辟的临时的空间叫做局部命名空间。
命名空间一共分为三种:
- 全局命名空间
- 局部命名空间
- 内置命名空间
取值顺序:
- 在局部调用:局部命名空间 -> 全局命名空间 -> 内置命名空间
- 在全局调用:全局命名空间 -> 内置命名空间
作用域
- 全局作用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效
- 局部作用域:局部名称空间,只能在局部范围内生效
globals 和 locals 方法
print(globals())print(locals())def func():a = 12b = 20print(globals())print(locals())func()
Python
Copy
global
- 声明一个全局变量。
在局部作用域想要对全局作用域的全局变量进行修改时,需要用到 global(限于字符串,数字)。
def func():global aa = 3func()print(a)count = 1def search():global countcount = 2search()print(count)
Python
Copy
对可变数据类型(list,dict,set)可以直接引用不用通过 globalli = [1,2,3]dic = {'name':'aaron'}def change():li.append(4)dic['age'] = 18print(dic)print(li)change()print(dic)print(li)
Python
Copy
nonlocal不能修改全局变量。
在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,并且引用的哪层,从那层及以下此变量全部发生改变。
def add_b():b = 1def do_global():b = 10print(b)def dd_nolocal():nonlocal b # 应用了上一层的变量bb = b + 20print(b) # 发生了改变dd_nolocal() # 调用函数,导致do_global的命名空间b也改变了print(b)do_global()print(b)add_b() # 最上面一层没有变化
Python
Copy
函数的嵌套和作用域链
def mymax(x,y):m = x if x > y else yreturn mdef maxx(a,b,c,d):res1 = mymax(a,b)res2 = mymax(res1,c)res3 = mymax(res2,d)return res3ret = maxx(23,453,12,-13)print(ret)
Python
Copydef f1():print("in f1")def f2():print("in f2")f2()f1()
Python
Copy
函数名的本质
函数名本质上就是函数的内存地址
可以被引用
def func():print('in func')f = funcprint(f)f()
Python
Copy可以被当作容器类型的元素
def f1():print('f1')def f2():print('f2')def f3():print('f3')l = [f1,f2,f3]d = {'f1':f1,'f2':f2,'f3':f3}#调用l[0]()d['f2']()
Python
Copy可以当作函数的参数和返回值
def f1():print('f1')def func(argv):argv()return argvf = func(f1)f()
Python
Copy
闭包
def func():name = 'aaron'def inner():print(name)return innerf = func()f()
Python
Copy
内部函数包含对外部作用域而非全剧作用域变量的引用,该内部函数称为闭包函数
判断闭包函数的方法 closuredef func():name = 'aaron'def inner():print(name)print(inner.__closure__)return innerf = func()f()# 最后运行的结果里面有cell就是闭包name = 'aaron'def func():def inner():print(name)print(inner.__closure__)return innerf = func()f()# 输出结果为None,说明不是闭包
Python
Copydef wrapper():money = 1000def func():name = 'apple'def inner():print(name,money)return innerreturn funcf = wrapper()i = f()i()
Python
Copydef func(a,b):def inner(x):return a*x + breturn innerfunc1 = func(4,5)func2 = func(7,8)print(func1(5),func2(6))
Python
Copyfrom urllib.request import urlopendef func():content = urlopen('http://myip.ipip.net').read()def get_content():return contentreturn get_contentcode = func()content = code()print(content.decode('utf-8'))content2 = code()print(content2.decode('utf-8'))
