1.python中函数定义:函数是逻辑结构化和过程化的一种编程方法。(完成某一种特定的功能)
def test02():
#""
msg = 'hello WuDaLang'
return msg
test02()
t1 = test02()
print(t1)
def:在python中定义函数的关键字。
test02:函数名
():内可定义形参(可以传参也可以不传参)
"":文档描述(非必要,但是强烈建议为你的函数添加描述信息)
泛指代码块或程序处理逻辑
return:定义返回值
return语句用于表示函数执行到此结束,并且返回return后面的对象;
有时候,函数不需要返回任何值,此时可以不需要return语句,它在后台默认给你返回个None,并且不给任何提示;
但是更多的时候我们还是需要return一些东西。一旦函数执行过程遇到return语句,那么之后函数体内的所有代码都会被忽略,直接跳出函数体;
那怕你现在正在一个循环内。
return可以返回些什么?
return可以返回什么?
什么都不返回,仅仅return:return数字/字符串/任意数据类型: return 'hello'一个表达式:return 1+2一个判断语句:return 100 > 99一个变量:returna
一个函数调用:returnfunc()
甚至是返回自己!:returnself
多个返回值,以逗号分隔:return a, 1+2, "hello"简而言之,函数可以return几乎任意Python对象。
View Code
怎么接受函数的返回值?
在调用函数的时候,可以将函数的返回值保存在变量中;所以如果有多个函数返回值的时候需要用多个变量接收,变量之间用逗号连接。
调用运行:可以带参数也可以不带
函数名()
函数的优点:减少代码的重复率,利于修改,可扩展。2.函数和过程
过程:就是没有返回值的函数
def test01():
pass
def test02():
return 1
def test03():
return 1,2,3,"df",[12,"sd"],{"name":"小明"}
t1 = test01()
t2 = test02()
t3 = test03()
print(t1)
print(t2)
print(t3)
#None
#1
#(1, 2, 3, 'df', [12, 'sd'], {'name': '小明'})
总结:返回值=0,返回None;
返回值=1,返回该object;
返回值>1,返回元祖。
3.参数的传递
Python的函数参数传递的是实际对象的内存地址。
Python的数据类型分可变数据类型和不可变数据类型。
形参和实参
(1)形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量;
(2)实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值。
def test01():
a=1
b=2
return a+b
def test02(x,y):
return x+y
t1 = test01()
t2 = test02(3,8)
print(t1)
print(t2)
#3
#11
【注意:要确认函数调用时候实参的顺序和函数定义中形参的顺序一致】
(2)关键字实参——明确指出实参相对应的形参,指出之后顺序任意。
defpet(pet_type,name,age):print("我养的宠物是"+pet_type+",他叫"+name+",有"+age+"岁了!")
pet(pet_type="乌克兰小乳猪",age="30",name="彭昌云")############################
我养的宠物是乌克兰小乳猪,他叫彭昌云,有30岁了!
View Code
(3)默认值——-———————————————在编写函数的时候给每个形参指定默认值。
使用默认值时,先要列出没有默认值的形参,然后再列出有默认值的形参。
def pet(name,age,pet_type="乌克兰小乳猪"):print("我养的宠物是"+pet_type+",他叫"+name+",有"+age+"岁了!")
pet(age="30",name="彭昌云")#####################
我养的宠物是乌克兰小乳猪,他叫彭昌云,有30岁了!
View Code
(4)传递任意数量的实参和认识数量的关键字实参
*x中的*创建的是一个名为x的空元祖,并将所有收到的值都存在这个元祖中;
**x——在需要接受任意数量的实参,但是预先不知道传递给函数的是什么样的值,可将函数编写成能够接受任意数量的键—值对
def pet(*pet_features):for item inpet_features:print("小猪猪的特征:"+item)
pet("name","age","high","wegth")def build_profile(first,last,**user_info):
profile={}
profile["first_name"]=first
profile["last_name"]=lastfor key,value inuser_info.items():
profile[key]=valuereturnprofile
user_profile=build_profile("彭","昌云",another_name="傻逼",feather="二货")print(user_profile)#########################
小猪猪的特征:name
小猪猪的特征:age
小猪猪的特征:high
小猪猪的特征:wegth
{'first_name': '彭', 'feather': '二货', 'last_name': '昌云', 'another_name': '傻逼'}
View Code
4、变量
a=1 #看到赋值语句,首先把注意力放在等号的右侧
在python中
变量和数据是分开存放的;
数据保存在内存中的一个位置;
变量中保存着数据在内存中的地址;
变量中记录着数据的地址,就叫做引用;
使用id()函数可以查看变量中保存数据所在的内存地址;
如果变量已经被定义,当给一个变量赋值的时候,本质上是修改了数据的引用;
变量不在对之前的数据引用,变量改为对新赋值的数据引用。
局部变量和全局变量
(1)在子程序中定义的变量称为局部变量,局部变量作用域是定义该变量的子程序。
(2)在程序的一开始定义的变量称为全局变量,全局变量作用域是整个程序,顶头写。
(3)当全局变量与局部变量同名时:
在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用。
(4)首先在自己的作用域找,找不到的话往外面找,直到找到为止,找不到的话就编红。
######## 全局变量变量名大写
######## 局部变量变量名小写
# 如果函数中无global关键字,优先读取局部变量,能读取全局变量,无法对全局变量重新赋值,
但是对于可变类型(列表,字典),可以对内部元素进行操作(增删改)
# 如果函数中有global关键字,变量本质上就是全局的那个变量,可读取可赋值
(5)nonlocal,指定上一级变量,如果没有就继续往上直到找到为止
name = "阿萨德"
def weihou():
name = "共和国"
print(name)
def weiweihou():
nonlocal name # nonlocal,指定上一级变量,如果没有就继续往上直到找到为止
name = "云集" # 该处则是对上一级name = "共和国"重新赋值为name = "云集"
print(name)
weiweihou()
print(name) # 所以在该处name为"云集"
print(name)
weihou()
print(name)
#阿萨德
共和国
云集
云集
阿萨德
5.总结
(1)变量查找顺序: LEGB,作用域局部>外层作用域>当前模块中的全局>python内置作用域;
(2)只有模块、类、及函数才能引入新作用域;
(3)对于一一个变量,内部作用域先声明就会覆盖外部变量,不声明直接使用,就会使用外部作用域的变量;
(4)内部作用域要修改外部作用域变量的值时,全局变量要使用global关键字,嵌套作用域变量要使用nonlocal关键字。nonlocal是python3新增的关键字,
有了这个关键字,就能完美的实现闭包了。
使用nonlocal关键字!它可以修改嵌套作用域(enclosing 作用域,外层非全局作用域)中的变量。
a=1
print('————a1————',id(a))defouter():
a=2
print('————a2————',id(a))definner():
a=3
print('————a3————',id(a))
inner()print("————a2————", id(a))
outer()print("————a1————", id(a))
————a1————1503749216————a2————1503749232————a3————1503749248————a2————1503749232————a1————1503749216
View Code
a = 10
deftest():
a+= 1
print(a)
test()
Traceback (most recent call last):
File"E:/NewPython/demo1_base.py", line 227, in test()
File"E:/NewPython/demo1_base.py", line 225, intest
a+= 1UnboundLocalError: local variable'a'referenced before assignment
为什么呢?
a+= 1相当于a = a + 1,按照赋值运算符的规则是先计算右边的a+1。但是,Python的规则是,如果在函数内部要修改一个变量,那么这个变量需要是内部变量,除非你用global声明了它是外部变量。很明显,我们没有在函数内部定义变量a,所以会弹出局部变量在未定义之前就引用的错误。
View Code
a=1
print('————a1————',id(a))defouter():
a=2
print('————a2————',id(a))definner():globala
a=3
print('————a3————',id(a))print('把最外面的全局变量的a改变了')
inner()print("————a2————", id(a))
outer()print("————a1是最外面的变量————", id(a))
————a1————1503749216————a2————1503749232————a3————1503749248把最外面的全局变量的a改变了
————a2————1503749232————a1是最外面的变量————1503749248
View Code
a=1
print('————a1————',id(a))defouter():
a=2
print('————a2————',id(a))definner():
nonlocal a
a=3
print('————a3————',id(a))
inner()print("————a2————", id(a))
outer()print("————a1是最外面的变量————", id(a))
————a1————1503749216————a2————1503749232————a3————1503749248————a2————1503749248————a1是最外面的变量————1503749216
View Code
6.递归调用
在python中,在函数内部,可以调用其他函数。如果在调用一个函数的过程中直接或间接调用自身本身,那其为递归调用。
注意:必须要有一个结束条件,不然就是死循环。
递归效率不高。
7.返回值————————————return
返回一个结果,当调用函数的时候就会返回return后面表达式的结果,那么就可以对这个返回结果进行任意的操作;
函数可返回任何类型的值,包括列表和字典等较复杂的数据结构;
return在函数里面相当于一个结束符号,代表函数到此为止;
小猪猪的特征:name
小猪猪的特征:age
小猪猪的特征:high
小猪猪的特征:wegth
{'first_name': '彭', 'feather': '二货', 'last_name': '昌云', 'another_name': '傻逼'}################
{'last': '彭', 'age': '100', 'first': '小猪猪'}
{'last': '小哥哥', 'first': '乌克兰小乳猪x'}
View Code
python 函数递归一次增加一次变量_python基础之函数 返回值 局部变量 全局变量 递归(继续补充不定长参数)...