s1 = 'helloworld'
def my_len(s): #def定义一个函数的名字叫做my_len.传了一个参数s、函数名不能是关键字、不能已数字开头
sum = 0
for i in s: #s为参数的位置
sum += 1
return sum #返回sum的值
print(my_len(s1)) #调用函数并把s1传入函数中
返回值的三种情况:
1、没有返回值
2、返回一个值
可以返回任何数据类型
只要返回了,就可以接收到
如果在一个程序中有多个return,只执行第一个,后边的都不执行
3、返回多个值
返回多个值需要多少个变量去接收,多少个返回值就有多少个变量,多了不行,少了也不行
可以用一个变量去接收,变量的接收值为一个元祖
1、没有返回值
不写return
def func():
l = ['金老板','二哥']
for i in l:
print(i)
print(func())
只写return
def func():
l = ['金老板','二哥']
for i in l:
print(i)
return #函数中只要执行了return,则后边的所有操作都不执行
print(func())
返回一个值
def func1():
return {'k','v'}
print(func1())
返回多个值
def func2():
return 1,2
r1,r2 = func2()
print(r1,r2)
参数
没有参数,括号里不写任何数据
一个餐宿
多个参数
位置参数(有多少个参数,函数调用的时候就必须多少个元素,且必须按照参数的顺序来写)
按照关键字传参
def my_sum(a,b):
print(a,b)
res = a+b
return res
站在实参的角度上:
ret = my_sum(2,1) #按位置传参
ret = my_sum(b=1,a=2) #按照关键字传参
ret = my_sum(1,b=2) #可以混着用,但先必须按照位置传参,再按照关键字传参,不能给同一个变量传多个值
print(ret)
站在形参的角度上:
位置参数:必须传(多传少传都不行)
默认参数:可以不传的参数,如果不传就使用默认的参数,如果穿了就是用传的
动态参数有两种:(可以接受任意个参数)
*args :接收的是按照位置传参的值,组织成一个元祖
**kwargs : 接收的是按照关键字传参的值,组织成一个字典
def classmate(name,sex='男'): #默认参数
print('{}:{}'.format(name,sex))
classmate('二哥','男')
classmate('春哥')
classmate('张三','女')
def sum1(*args): #动态参数
n = 0
for i in args:
n += i
return n
print(sum1(1,2,3,4))
函数进阶
a = 1
def func():
print(a)
func()
命名空间和作用域
内置命名空间--Python解释器
就是Python解释器一启动就可以使用的名字,存储在内置的命名空间中
内置的名字在启动解释器的时候被加载进内存里
全局命名空间--我们写的代码,不是函数中的代码
是程序从上到下被执行的过程中一次加载进内存的
放置了我们设置的所有变量名和函数名
局部命令空间--函数
就是函数内部定义的名字
当调用函数的时候才会产生这个名称空间,随着函数执行的结束,这个命名空间就又消失了
在局部:可以使用全局命名空间中的名字、也可以使用内置命名空间的名字
在全局:可以使用内置命名空间中的名字、不能使用局部命名空间中的名字
在内置:不能使用全局和局部的名字
在正常情况下,直接使用内置的名字
当我们在全局定义了和内置命名空间中一样的名字,我们调用是会使用全局的名字
当我自己有的时候,我就不找我的上级要了
如果自己没有就找上级要
def input():
print('in input now')
def func():
input() #调用的全局命名空间中自己定义的input函数
func()
作用域有两种
全局作用域------作用在全局(包含内置和全局名字空间都属于全局作用域)---globals()
局部作用域------作用在局部-(函数)局部名字空间中的名字属于局部作用域--locals()
对于不可变数据类型,在局部可是查看全局作用域中的变量
但是不能直接修改
如果想要修改,需要再函数的一开始添加global声明,那么这个变量在局部的所有操作将对全局的变量生效
a = 1
def func():
global a #
a = 2
func()
print(a) #此刻a=2
a = 1
b = 2
def fun():
x='aaaa'
y='bbbbb'
print(locals())
print(globals())
fun()
print(globals())
print(locals())
关于globals 永远打印全局的名字
locals输出什么根据locals所在的位置,在全局 就输出全局,在局部就输出局部
函数嵌套:在函数体了去调用宁外一个函数,则叫函数嵌套
实例:比较三个数的大小
def max(a,b): #定义一个函数比较两个数的大小
return a if a > b else b #三元运算
def the_max(x,y,z):
c = max(x,y) #调用上边的函数先比较前两个数的大小
return max(c,z) #再把上边的结果和最后一个数比较,则返回出最大的数字
print(the_max(1,5,2))
函数的嵌套定义:
内部函数可以使用外部函数的变量
a = 1
def outer():
a = 1
def inner():
b = 2
print(a)
print('inner')
def inner2():
nonlocal a #nonlocal 声明了一个上层局部变量
a += 1
print(b)
print('inner2')
inner2()
inner()
print('局部的a:', a)
outer()
print('全局的a',a)
nonlocal 只能用于局部变量,找上层中离当前函数最近一层的局部变量
def func():
print('123')
func() #函数名就是内存地址
func2 =func #函数名可以复制
func2()
l = [func,func2] #函数名可以作为容器类型的数据
print(l)
for i in l:
i()
def func():
print(123)
def wahaha(f):
f()
return f #函数名可以作为函数的返回值
q = wahaha(func) #函数名可以作为函数的参数
print(q())
闭包
闭包一定是嵌套函数,切内部函数调用外部函数的变量
def outer():
a = 1
def inner(): #在这里inner就为一个闭包
print(a)
print(inner.__closure__)#打印某函数的closure,结果里边有cell,则该函数是一个闭包
outer()
import urllib #导入模块(一个Python文件)
from urllib.request import urlopen
# ret = urlopen('http://www.xiaohuar.com/').read()
# print(ret)
#用闭包
def get_url():
url = 'http://www.xiaohuar.com/'
def get():
ret = urlopen(url).read()
print(ret)
return get
get_func = get_url()
get_func()