python基础之函数、返回值,局部变量、全局变量,递归(继续补充不定长参数)

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

一个变量:return a

一个函数调用:return func()

甚至是返回自己!:return self

多个返回值,以逗号分隔: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)关键字实参——明确指出实参相对应的形参,指出之后顺序任意。

def pet(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 in pet_features:
        print("小猪猪的特征:"+item)
pet("name","age","high","wegth")

def build_profile(first,last,**user_info):
    profile={}
    profile["first_name"]=first
    profile["last_name"]=last
    for key,value in user_info.items():
        profile[key]=value
    return profile
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))
def outer():
    a=2
    print('————a2————',id(a))
    def inner():
        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
def test():
    a += 1
    print(a)
test()



Traceback (most recent call last):
  File "E:/NewPython/demo1_base.py", line 227, in <module>
    test()
  File "E:/NewPython/demo1_base.py", line 225, in test
    a += 1
UnboundLocalError: local variable 'a' referenced before assignment


为什么呢?
a += 1相当于a = a + 1,按照赋值运算符的规则是先计算右边的a+1。但是,Python的规则是,如果在函数内部要修改一个变量,那么这个变量需要是内部变量,除非你用global声明了它是外部变量。很明显,我们没有在函数内部定义变量a,所以会弹出局部变量在未定义之前就引用的错误。
View Code
a=1
print('————a1————',id(a))
def outer():
    a=2
    print('————a2————',id(a))
    def inner():
        global a
        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))
def outer():
    a=2
    print('————a2————',id(a))
    def inner():
        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

 






posted @ 2018-08-30 01:36  小猪猪猪  阅读(210)  评论(0)    收藏  举报