函数空间:
1.当函数名和内置函数重命名时程序会运行自定义函数
2.内置名字空间>全局的名字空间>局部的名字空间(先在本级区域里找,找不到后再在上一级找)
3.函数名加括号就是一个函数的执行,去掉括号就是内存地址。(函数名----->函数内存地址),id(xx):可以查看xx的地址
作用域:
1.全局作用域—包含内置和全局空间中的名字
2.局部作用域—包含局部
3.对于不可变数据类型在局部可以查看全局作用域的变量,但不能直接修改。若要修改,需要在程序一开始添加global声明。
例:
a = 1
def func():
a += 1
fun() #...........................这个就会报错
4.locals():可以查看局部作用空间的名字(locals()得放在局部域中,放在全局和globals()一样),globals()可查看全局作用空间的名字而且可看到内置空间的名字(放在哪都一样)
5.一般global不使用在程序中,可用传参和返回值来解决3中的问题
函数嵌套调用
1.函数的嵌套定义使用
def max(a,a):
return a if a>b else b
def the_max(x,y,z):
c = max(x,y)
return max(c,z)
num = the_max(2,8,7)
print(num)
2.内部函数可以使用外部函数的变量
3.局部的global不能改变全局的变量
4.nonlocal(只能用于局部变量):声明了上层局部变量,只能找最近上一层的变量,若上层没有就找上上层但不会找到全局中。
5.函数名可以赋值:
def outer():
def inner():
print('inner')
inner()
print('outer')
outer()
outer2 = outer
outer2()
6.函数名可以做函数的参数,也可以做返回值:
def func()
print(123)
def wahaha(f):
f()
return()
qqxing = wahaha(func)
qqxing()
7.函数名可做容器变量的元素:L = [func,wahaha]
def outer():
def inner():
print('inner')
inner()
print('outer')
outer()
闭包:嵌套函数内部函数调用外部函数变量.
def outer():
a = 1
def inner():
print(a)
inner()
print(inner.__closure__) #是闭包
outer()
print(out.__closure__) #不是闭包
@常用于外部使用内部函数
def outer():
a = 1
def inner():
print(a)
return inner #返回内部函数名
print(inner.__closure__)
inn = outer()
inn() #使用了内部函数
print(
out.__closure__)
@闭包的简单应用(获取网络源码)
from urllib.request import urlopen
def get_url():
url = 'http://www.xiaohua100.cn/index.html'
def get():
ret = urlopen(url).read()
print(ret)
return get
getfun = get_url()
getfun()
作业:
1.编写函数接收n数字,求这些参数数字的和
def sum_fun(*args):
total = 0
for i in args: #接受到的是元组
total += i
return total
print(sum_fun(1,2,3,4,5,6,7,8))
2.读代码,回答:代码中打印出的a,b,c分别是什么?为什么?
a = 10
b = 20
def test(a,b):
print(a,b)
c = test(b,a) #test(20,10)
print(c) #无返回值所以是None
输出结果:
20 10
None
3.读代码,回答:代码中打印出的a,b,c分别是什么?为什么?
a = 10
b = 20
def test1(a,b):
a = 3 #20--->3
b = 5 #10--->5
print(a,b)
c = test1(b,a) #test1(20,10)
print(c)
输出结果:
3 5
None
作业:
必做题
1、整理函数相关知识点,画思维导图,写博客
2、写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素并将其作为新 列表返回给调用者。
def func(L):
return L[1::2] #切片
reg = func([1,2,3,4,5,6,7])
print(reg)
3、写函数,判断用户传入的对象(字符串、列表、元组)长度是否大于5。
def func(x):
return len(x) > 5
print(func([1,2,3,4,5,6,7]))
4、写函数,检查传入列表的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。
def func(x):
return x[:2] #数组长度若大于切片长度则切到切片长度
print(func([1]))
5、写函数,计算传入字符串中【数字】、【字母】、【空格]以及【其他】的个数,并返回结果。
def func(s):
dic = {'num':0,'alpha':0,'space':0,'other':0} # num:计算数字 alpha:计算字母 space:计算空格 other:其他
for i in s:
if i.isdigit(): #判断是否为数字
dic['num'] += 1
elif i.isalpha(): #判断是否为字母
dic['alpha'] += 1
elif i.isspace(): #判断是否为空格
dic['space'] += 1
else:
dic['other'] += 1
return dic
print(func('jsjdasdjhgd27782378 '))
6、写函数,检查用户传入的对象(字符串、列表、元组)的每一个元素是否含有空内容,并返回结果。
def func(x):
if type(x) is str and x: #and x:判断本身不为空
for i in x:
if i == '':
return True
elif x and type(x) is list or type(x) is tuple:
for i in x:
if not i:
return True
elif not x: #本身为空
return True
print(func([1,'']))
7、写函数,检查传入字典的每一个vale的长度如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者dic={“kl”:“vlvl”,“k2”:[12,3,44]} PS:字典中的vale只能是字符串或列表
def func(dic):
for k in dic:
if len(dic[k]) > 2:
dic[k] = dic[k][:2]
return dic
dic={"kl":"vlvl","k2":[12,3,44]}
print(func(dic))
8、写函数,接收两个数字参数,返回比较大的那个数字。
三元运算(必须要有结果,必须要有if和else): 条件返回Ture的结果 if 条件 else 条件返回False的结果
def func(a,b):
return a if a>b else b
print(func(5,7))
选做题
9、写函数,用户传入修改的文件名,与要修改的内容,执行函数,完成整个文件的批量修改操作(进阶)。
import os
def func(filename,old,new):
with open(filename,encoding='utf-8') as f,open('%s.bak'%filename,'w',encoding='utf-8') as f1:
for line in f:
if old in line:
line = line.replace(old,new)
f1.write(line)
os.remove(filename) #删除文件
os.rename('%s.bak'%filename,filename) #重命名文件
func('first.txt','我好','你好')