首页 > 代码库 > 函数(二)

函数(二)

 

上节回顾:

 

1.为何用函数:


解决代码重用问题
提高代码可维护性
程序的组织结构清晰,可读性强


2.定义函数


!!!先定义,后使用
def funcname(arg1,arg2,...):
"""描述信息"""
函数体
return value
无参,
def foo():
print(‘foo‘)

有参,
def my_sum(x,y):
return x+y


3.调用函数


语句形式:foo()
表达式形式:res=my_sum(1,2)
函数调用作为另外一个函数的参数:print(my_sum(1,2))

 

4.函数返回值


不写return -->None
return 一个值 -->这个值
return 多个值 --> 由这多个值组成的元组

 

5.函数的参数


形参和实参
def my_sum(x,y):
return x+y
my_sum(1,2)

从实参的角度:
按位置传值my_sum(1,2)
按关键字传值my_sum(y=1,x=2)
混合传值my_sum(1,y=2) #不能对形参重复赋值

从形参角度:
位置参数def foo(x,y,z) #位置参数必须在默认参数左边
默认参数def foo(x,y=1) #定义时变化少的定义成默认参数

什么时候用?
位置参数: 每次调用的时候值都需要变化的
默认参数:定义时变化少的定义成默认参数

二者的特性:
调用时位置参数必须传值,默认参数可传可不传

*args 定义时以元组形式 def foo(x,*args) 调用时多余的值拼成元组给args
foo(1,2,3,4,5)
**kwargs def foo(x,**kwargs) 多余的按关键字传值的拼成字典给kwargs
foo(x=1,y=3,z=3)

 

函数(二)

 

 

1.名称空间和作用域

 

名称空间
#内置名称空间
#全局名称空间
#局部名称空间

 

内置名称空间:系统解释器自带的
import builtins
dir(builtins) 看
全局名称空间: 没缩进定格写的
定义完了,全局在哪里都可以用

 

局部名称空间: 在函数内部定义的

 

全局作用域:
#内置名称空间
#全局名称空间

 


局部作用域:
#局部名称空间

 

找的时候:先找局部,再全局,再内置

 

def foo():
print(‘from foo‘)
bar()

 

def bar():
print(‘from bar‘)
foo()

 


globals 都是针对文件全局

locals 文件局部 和内建文件的局部(定义值)

 

 

 

2.函数的嵌套

1.嵌套调用

def my_max(x,y):    res=x if x > y else y    return resprint(my_max(10,100))def my_max4(a,b,c,d):    res1=my_max(a,b)    res2=my_max(res1,c)    res3=my_max(res2,d)    return res3print(my_max4(1,20,3,4))

  

100
20

 

2.嵌套定义

 

def f1():    print(----->f1)def f2():    print(----->f2)f2()f1()----->f2----->f1

 

 

 

x=11111111def f1():       print(‘------->f1‘,x)def f2():    x=2    print(‘----->f2‘,x)def f3():    x=3    print(‘--->f3‘,x)f3()f2()f1()--->f3 3----->f2 2------->f1 11111111

  

 

 

 

3.函数对象与闭包

 

 

函数是第一类对象


#函数可以被赋值


f=foo
print(f)
f()

 

def foo():
  print(foo)

 

 

#函数可以被当成参数传递

 

f=foo
print(f)
f()

 

 

def bar(func):
  print(func)

 

bar(foo)

bar(foo())       则是None

##打印的都是foo的内存地址

 

 

#把函数当成返回值


def bar(func):
  print(func)
  return func
f=bar(foo)
print(f)
f()

 

 

def search():
print(‘function ------>search‘)
def add():
print(‘function ------>add‘)
def delete():
print(‘ function------->delete‘)
def change():
print(‘ function-------->change‘)

def tell_msg():
msg=‘‘‘
search: 查询
add:添加
delete:删除
change:修改
create:新建
‘‘‘
print(msg)
def create():
print(‘function ------->create‘)
cmd_dic={
‘search‘:search,
‘add‘:add,
‘delete‘:delete,
‘change‘:change,
‘create‘:create
}

while True:
tell_msg()
choice=input(‘please input your choice:‘).strip()
#print(cmd_dic[choice])
cmd_dic[choice]()

 

 

x=10000def f1():    x=1    def f2():        print(x)    return f2f=f1()print(f)x=123123123f()<function f1.<locals>.f2 at 0x00000000009EE268>1

  

 

f() 返回f2,找f2的x

 

 

闭包

 

内部函数的代码包括对外部作用域名字的引用,但一定不是对全局名字的引用
#首先必须是内部定义的函数,该函数包含对外部作用域而不是全局作用域名字的应用

 

 

 

x=1def f1():    x=2
   y=1 def f2(): print(x)
     y return f2f=f1()f()print(f._closure_[0].cell_contents)print(f._closure_[1].cell_contents)

2
2
1

返回f2

  

#print(f.closure_) #验证是不是闭包
print(f._closure_[0].cell_contents) #查看内容
print(f._closure_[1].cell_contents)

 


def f1(x):
#x=2
def f2():
print(x)

 

return f2
f=f1(100000000)
f()
#print(f.closure_) #验证是不是闭包
print(f._closure_[0].cell_contents) #查看内容
print(f._closure_[0].cell_contents)

 


pip install requests 下载模块 #验证闭包的用途
import requests

 

requests.get(‘http://requests.get(‘http://www.baidu.com‘)
requests.get(‘http://requests.get(‘http://www.baidu.com‘).txt

 

import urlopen
from urllib.requests import urlopen
def get(url):
return urlopen(url).read()

 

print(get(‘http://www.python.org‘))

 

 

 

闭包的演变
from urllib.requests import urlopen
def f1(url):
def f2():
print(urlopen(url).read())

 

return f2

 

f=f1(‘http://www.python.org‘)

 

f()

 

函数(二)