python(五)——函数

函数定义:
		def 函数名( 参数) :
				函数内容
				return 返回值
函数调用:
			函数名()
1.return 可以没有,返回值就默认为None
2.可以return 多个值,以元组形式返回
def function(a,b):
    return a + b 
    
if __name__ == '__main__':
    print(function(12,16))#28

函数参数

形参	def function(**a,b**)
实参	function(**12,16**)

参数的传递:
1.按位置传递参数
2.按关键字传参
3.混合传参

函数中参数类型:function(a,b)
1.普通参数
2.默认参数
3.可变参数
4.关键字的可变参数
5.keyword-only参数

参数传递顺序一般为:位置参数,可变参数,默认参数,可变的关键字参数
def function(a,b):#按位置传递普通参数
    print(a)#20
    print(b)#10


def f():
    a = 10
    b = 20 
    function(b,a)	#function(20,10)
    '''
    参数个数必须一致
	'''
def function(a,b):#按关键字传递普通参数
    print(a)
    print(b)


def f():
    a = 10
    function(a,b=15)#function(位置参数,关键字参数)
    '''
    1.位置参数要在关键字参数之前,否则报错
    2.同一个参数不能传递2次
    	function(10,a=10)
    	10已经按照位置传参的方式传给了a
    	又来一个关键字传参给a  所以会报错
    '''

默认参数:

def function(a='一'):#默认值参数,不给参数就使用默认参数
    print('今天是星期%s'%a)

function()

可变参数:

参数个数不确定,以元组形式存放,按位置接受
def function(a,*args):#按位置传递普通参数,可变参数
	print(args)#<class 'tuple'>
    num = 0
    for i in args:
        num += i
    print(num)#18
def f():  
    
    function(2,6,4,8)

关键字的可变参数:

def function(**args):#关键字的可变参数,以字典形式存放
    for i in args :#以字典形式存放,所以取出的都是key
        print(i)# a  b  c 
function(a=1,b=2,c=3)
'''
默认参数要在关键字参数之前
def function(args = True,**args):
'''

参数的解构:

对于list,dict作为参数时,可以将参数解构,一个一个的传入

def function(args):
	print(args)#[2, 3, 4, 5, 6]
    print(type(args))#<class 'list'>
li = [2,3,4,5,6]
function(li)

#参数解构
def f1(*args):
    print(args)#(2, 3, 4, 5, 6)
    print(type(args))#<class 'tuple'>

li = [2,3,4,5,6]
f1(*li)

python3新加入的keyword-only参数

在函数中,可变参数后面出现的普通参数是keyword-only参数,必须以关键字传参的方式传递
def f1(*args,a,b):
    return a+b
    
print (f1(2,3,5,a = 1,b =5))#6
'''
keyword-only参数必须在**args可变的关键参数之前,因为**args会拦截所有传入的关键字方式传参
def foo(a,*args,x,y,**kwargs)
'''

参数传递的陷阱问题:

def f1(l=[]):
    l.append(10)
    print(l)
 

f1()#[10]
l = []
f1(l)#[10]
f1()#[10, 10]
'''
f1(),无参数,就使用默认的[],此时输出[10]
f1(l)有参数,另一个[],此时输出[10]
f1(),无参数,继续使用默认的[],此时里面已经有一个10,所有结果为[10, 10]
'''

函数进阶

命名空间与作用域:

	内置命名空间:随python解释器启动而加载
	全局命名空间:程序从上至下执行时一次加载,存放了所有的全局变量,函数名
	局部命名空间:随函数的调用而传升,结束而消亡
	
	单纯的函数名指向一个内存地址
	函数名——》内存地址
	函数名()——》调用函数
#关键字global 
num = 9
def f1():
    if num%2 :	#报错,局部变量num未定义
        print('奇数')
   
'''
函数内部想引用全局的变量,需要关键字global
num = 9
def f1():
    global num
    if num%2 :
        print('奇数')
注意:global存在一些安全问题,尽量少用,需要的参数建议传参的方式传入
'''

```python
#关键字nonlocal
def f1():
    num = 123
    def f2():
        nonlocal num 
        num += 5
    f2()
    print(num)
f1()
'''
nonlocal	声明上一层的局部变量
只在局部中找上一层的变量,找不到再上一层,只在局部找
'''
查看全局,局部变量
name = '张三'
age = 23

def f():
    sex = '男'
    job = 'teacher'
    print(locals())#查看所有的局部变量
    
print(globals())#查看所有全局变量
f()
'''
globals():放在全局或局部都是输出所有全局变量
locals():放在全局,输出全局变量;放在局部,输出局部变量
变量都是key-value形式的字典
全局变量中的部门元素
'__name__': '__main__' 
	在当前正在运行的文件中,__name__的值为_main__
	调用的其他文件中有__name__,值为文件名(无后缀)
'__doc__': '....'
	存放的是所有的多行注解
'__file__': 'D:\\....'
	存放的是当前文件的地址
'''

函数名就是内存地址

	可以赋值
	可以作为容器的元素	例:globals()获取的字典中的元素 函数名 : 内存地址
	可以作为参数,作为返回值

	函数名是第一类对象
	第一类对象
			在运行期创建
			可以作为函数的参数或返回值
			可存入变量的实体(作为容器元素)

闭包

闭包:

	1.有嵌套函数
	2.内部函数调用外部函数的变量
	3.内部函数作为参数返回

例:

def function():
    num = 1
    def f():
        print(num)

    return f
ret = function()
print(ret.__closure__)#(<cell at 0x0000000001ED4558: int object at 0x000007FEEDE87100>,)
ret()
'''
内部函数的属性__closure__中包含内部函数所有引用的外部变量
值为None表示非闭包
'''

装饰器

	装饰器:在不修改原函数的前提下,在原函数执行前后添新功能

例:

def function(f):
    def inner(*args,**kwagrs):
        print('增强代码')
        ret = f(*args,**kwagrs)
        if type(ret) == str and ret.isalpha():
            return ret.upper()
        return ret
    return inner

def code(s):
    s += 's'
    return s

code = function(code)#将函数名code作为参数传入,将得到的返回值inner 赋值给code变量,会覆盖方法名code变量
#即code = inner 这是内部函数的函数名指向一个地址
ret = code('hello')#实质是调用是调用inner('hello'),内部函数执行,执行增强代码
print(ret)#HELLOS

例:获取程序运行时间

import time
def function(f):
    def inner(*args,**kwagrs):
        start = time.time()
        ret = f(*args,**kwagrs)
        end =time.time() - start
        print('程序运行时间为%.4f'% end)
        #print(type(end))
        return ret
    return inner

def code(n):
    for i in range(n):
        print(i)
    
code = function(code)
code(10000)

装饰器:

import time
def function(f):
    def inner(*args,**kwagrs):
        start = time.time()
        ret = f(*args,**kwagrs)
        end =time.time() - start
        print('程序运行时间为%.4f'% end)
        #print(type(end))
        return ret
    return inner
@function		#等价于code = function(code),改变了调用方式,增加了功能
def code(n):
    for i in range(n):
        print(i)
code(10000)
#在被装饰方法上加上@装饰器函数名
发布了16 篇原创文章 · 获赞 0 · 访问量 78

猜你喜欢

转载自blog.csdn.net/qq_31241107/article/details/103757973