Python学习之路--函数

初识函数

可读性,复用性强

定义之后,可以在任何需要它的地方调用

所有函数 只定义不调用不会执行

先定义后调用

def  函数名(): #

    函数体

    return 返回值

函数调用

函数名()不接收返回值

有返回值 返回值 = 函数名 接收返回值

返回值

return

三种情况

    没有返回值  1、不写return,2、只写return,3、return None

def func():
l = ['大老板','廖小胖']
for i in l:
print(i)
return #出现return,后面内容不执行,即结束一个函数
re = func()
print(re)
#大老板
# 廖小胖
# None

    返回1个值

def func():
return {'k':'v'}
print(func())

    可以返回任意数据类型

    只要返回了,就可以接收到

    如果在一个程序中有多个return,只执行第一个

    多个返回值

       多个返回值用多个变量接收,有多少返回值就用多少变量接收

def func():
return 1,2
r1,r2 = func()
print(r1,r2)#1 2

        可以用一个变量接收,得到的是一个元组

def func():
return 1,2,3
r = func()
print(r)#(1, 2, 3)

函数参数

s = '大老板廖小胖'
def m_len(s): #接收参数 ,接收参数,形式参数,形参
i = 0
for k in s:
i += 1
return i
l = m_len(s)
print(l) # 6

def m_len(s): #接收参数
i = 0
for k in s:
i += 1
return i
l = m_len(s)
r = m_len([12,34,4])
print(l) # 6
print(r) #传递参数,传参,实际参数,实参
# 6
# 3

没有参数

        定义函数和调用函数时括号里不写内容

    有一个参数

        传什么是什么

    多个参数

站在实参角度:        

    按位置传参

def my_sum(a,b):
res = a + b
return res
re = my_sum(1,2)
print(re)
默认参数
def qq(l = []):                   
    l.append(1)                   
    print(l)                      
qq()  #[1]                        
qq([]) # [1]                      
qq()#[1,1]                        
View Code

如果默认参数的值是一个可变数据类型

那么每一次调用函数的时候,如果不传值就公用这个数据类型的资源

    按关键字传 def my_sum(a,b):    print(a,b)

    res = a + b
return res
re = my_sum(b=2,a=1)
print(re)
可以混用,但必须先按位置传参,再按照关键字传参
不能给同一个变量,传多个值
站在形参的角度:
位置参数:必须传,有几个参数就传几个值
默认参数:可以不传,使用默认的参数,如果传,就用传递的参数
def classmate(name,sex=''):
    print('%s:%s'%(name,sex))
classmate('大老板')
classmate('北路')
classmate('挥挥','')
# 大老板:男
# 北路:男
# 挥挥:女

   调用函数的时候

       按照位置传:直接写参数的值

       按照关键字:关键字 = 值

   定义函数的时候:

       位置参数:直接定义参数

       默认参数: 关键字参数:参数名 =‘默认的值’

       动态参数:可以接受任意多个参数def 函数(*args) 、(**kwargs)

       *args:接收的是按照位置传参的值,组织成一个元组

def sum(*args):
    n = 0
    for i in args:
        n += i
    return n
print(sum(1,2))
print(sum(1,2,3))
# 3
# 6
def func(*args,l =[]):
print(args,l)
func(1,2,3,l=[1,2])

     **kwargs:接收的是按照关键字传参的值,组织成一个字典

def func(**kwargs):
    print(kwargs)
func(a=1,b=3,c=1)
func(a=2,b=1)
# {'a': 1, 'b': 3, 'c': 1}
# {'a': 2, 'b': 1}
两者一起使用,必须先接收位置参数,再接收关键字参数即*args,必须在**kwargs之前
def func(*args,**kwargs):
print(args,kwargs)
func(1,2,3,4,a = 'aaa',b='bbb')
# (1, 2, 3, 4) {'a': 'aaa', 'b': 'bbb'}

动态参数的另一种传参方式
def func(*args):
print(args)
func(1,2,3,4,5)
l =[1,2,3,4,5]
func(*l)
# (1, 2, 3, 4, 5)
# (1, 2, 3, 4, 5)
站在实参的角度上,给一个序列加上*,就是将这个序列按照顺序打散
站在形参的角度上,给变量加上*,就是组合所以传来的值
def func(**kwargs):
print(kwargs)
func(a=1,b=2)
d = {'a':1,'b':2}
func(**d)
# {'a': 1, 'b': 2}
# {'a': 1, 'b': 2}

     顺序: 必须先定义位置参数,后定义默认参数,*args默认参数

函数的注释

def func():
'''
这个函数实现了什么功能
参数说明
:return:
'''
pass

函数的进阶

命名空间

内置命名空间---python解释器

    python解释器一启动就可以使用的名字存储在内置命名空间中,内置的名字在启动解释器的时候      被加载进内存里

 

全局命名空间 ---自己写的代码但不是函数里的代码

    在程序从上到下被执行的过程中依次加载进内存的,放置自己设置的所有变量名和函数名

局部命名空间---函数

    在函数内部定义的名字,当调用函数时,才产生这个命名空间,这个命名空间就消失了

 

在局部:可使用全局、内置命名空间中的名字

在全局:可使用内置命名空间的名字,不能使用局部的

在内置:不能使用局部、全局

内置>全局>局部

依赖倒置原则,上层模块依赖下层依赖。局部依赖全部,全部依赖内置

在正常情况下,直接使用内置名字

当在全局定义了和内置命名空间相同的名字时,会使用全局的名字

当自己有的时候,不找上级要,如果上级没有再找上级要,找到内置也没有,就会报错

def max(l):
    print('in th max')
print(max([1,2,3]))
# in th max
# None

作用域

全局作用域 作用于全局  globals()

局部作用域  作用于局部  使用locals()查看局部变量的名字

对于不可变数据类型,在局部可以查看全局作用域中的变量,如想要修改,在变量前加上global

如果在局部内声明一个global变量,则这个变量在局部所有操作将对全局有效

函数的嵌套  

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,2,3)) #3
函数的嵌套定义

内部函数可以使用外部函数的变量
def outer():
def inner():#函数定义后必须调用才会执行
print('inner')
inner()
outer()#inner
 
def outer():
    a =1
    def inner():
        b = 2
        print(a)
        print('inner')
        def inner2():
            print(a,b)
            print('inner2')
        inner2()
    inner()
outer()
# 1
#  inner
#  1 2
#  inner2
View Code
a = 1
def outer():
    a =1
    def inner():
        b = 2
        print(a)
        print('inner')
        def inner2():
            global a
            a += 1
            print('inner2')
        inner2()
    inner()
    print('**',a)
outer()
print('全局:',a)
# 1
# inner
# inner2
# ** 1
# 全局: 2
View Code

nonlocal 声明一个上层最近的局部变量,只能用于局部变量,声明了nonlocal的内部函数变量修改会影响到离当前函数最近一层的局部变量,对全局无效

a = 1
def outer():
    a =1
    def inner():
        b = 2
        print(a)
        print('inner')
        def inner2():
            nonlocal a
            a += 1
            print('inner2')
        inner2()
    inner()
    print('**',a)
outer()
print('全局:',a)
# 1
# inner
# inner2
# ** 2
# 全局: 1
View Code

函数名的本质

第一类对象

函数名就是内存地址

def func():
print(123)
func()
func2 =func
func()
# 123
# 123 函数名可以赋值

函数名可以作为容器类型的元素
def func():
    print(123)
func()
func2 =func
l = [func,func2]
print(l)
for i in l:
    print(i)
    # 123
    #     #     # [ < function
    #     #     # func
    #     #     # at
    #     #     # 0x000001EA9DA91A60 >, < function
    #     #     # func
    #     #     # at
    #     #     # 0x000001EA9DA91A60 >]
    #     #     # < function
    #     #     # func
    #     #     # at
    #     #     # 0x000001EA9DA91A60 >
    #     #     # < function
    #     #     # func
    #     #     # at
    #     #     # 0x000001EA9DA91A60 >
View Code

函数名可以作为函数的参数

def func():
    print(123)

def hh(f):
    f()

hh(func)#123
View Code

函数名可以作为函数的返回值

def func():
    print(123

def hh(f):
    f()
    return f
qq = hh(func)
qq()
# 123
# 123
View Code

闭包

嵌套函数,且内部函数调用外部函数的变量

def outer():
    a = 1
    def inner():
        print(a)
    return inner
inn = outer()
inn() #1
View Code
def outer():
    a = 1
    def inner():
        print(a)
    return inner
inn = outer()
inn() #1
View Code
from urllib.request import urlopen
def get_url():
    url = 'http://www.baidu.com'
    def get():
        ret = urlopen(url).read()
        print(ret)
    return  get
get_fu = get_url()
get_fu()
View Code

猜你喜欢

转载自www.cnblogs.com/rssblogs/p/10922162.html