Python之函数的参数

Python之函数的参数

传参的方式只有两种:位置和关键字。

位置参数在默认参数的左边。

参数是可以是任何数据类型。

可以传递0个或多个参数。

一、形参和实参

实参:函数调用的时候传入的参数值

形参:函数定义的时候,定义的参数名

def mylen(s) 里的s是形参

leng = mylen("adfadsfasfasd") 里的adfasdfasdf是实参

def mylen(s):   #参数的接收
    """
    计算字符串的长度                  ===函数的功能
    参数s:要计算的字符串              ===参数的信息
    :return:返回要计算的字符串的长度    ===返回值的信息
    """
    length = 0
    for i in s:
        length += 1
    return length

# mylen()的括号里可以写参数,这里是参数传入的地方
leng = mylen("1234455666787")
print(leng)

二、位置参数

在调用函数时,传参数:

  按照位置传参

  按照关键字传参

在传参的角度:按顺序定义参数 

def my_max(a,b):
    """
    返回两个值之间的最大值
    :return:
    """
    if a > b:
        return a
    else:
        return b
print(my_max(40,3))

关键字参数

def my_max(a,b):
    """
    返回两个值之间的最大值
    :return:
    """
    if a > b:
        return a
    else:
        return b
my_max(a=40,b=1)
def lonin(user,passwd):                       
    if user == "george" and passwd == "123":  
        return True                           
    else:                                     
        return False                          
                                              
ret = lonin('george','13')                    
if ret:                                       
    print('ok')                               
else:                                         
    print('no')                               
                                              

三、默认参数

默认参数可以不传值,但是,如何给默认参数传值,新的值就会覆盖定义好的旧的值。

def login(name,sex = 'male'):                  
    print('name:%s,sex:%s'%(name,sex))         
                                               
login('george')                                
                                                     
def login(name,sex = 'male'):                        
    print('name:%s,sex:%s'%(name,sex))               
                                                     
login('george')                                      
login('george','man')                                
                                                     
s = 'man'                                 
def login(name,sex=s):                    
    print('name:%s,sex:%s'%(name,sex))    
                                          
s='male'  #不影响定义时sex的值                                
login('george')                           

默认参数:首先不要设置可变类型的默认参数

      对于变化小额参数可以设置默认参数

      默认的参数可以不传,不传的时候用的就是默认值

      如果传,就会覆盖默认值

      默认值是在定义函数的时候,就已经确定了的。

b = []
def func(a = []): #不要设置可变数据类型的默认参数
    a.append(1)
    print(a)
# func()
# func()
# func()
# func()

# func([])
# func([])
# func([])
# func([])

四、动态参数(*args,**kwargs)

*args:接收列表类型或元组类型

**kwargs:接收字典类型

位置传参,是a和b相加,而args就是一个空的元组。

def func(a,b,*args):        
    print(a,b,args)         
    return a+b              
                            
print(func(3,1))            

同样位置传参,是a和b相加,但是args就是一个有值的元组。

def func(a,b,*args):          
    print(a,b,args)           
    return a+b                
                              
print(func(1,2,3))            
                              

按关键字传参数,c和d是关键字传参kwargs

def dun(a,b,**kwargs):    
    print(a,b,kwargs)     
                          
dun(a=1,b=2,c=333,d=333)  

*args和**kwargs合用

def f(a,b,*args,**kwargs):
    print(a,b,args,kwargs)

f(1,2,3,4,5,6,7,c=1,d=4)

参数的放置位置:位置参数,*args,默认参数,**kwargs

def fun(*args):    # *args代表把散列的元素拼成元组
    print(args)
t = (1,2,3,4)
l = [1,2,3,4]
fun(*t)    # *代表把一个元组、列表拆了
fun(*l)    # *代表把一个元组、列表拆了
def fun(**kwargs):  # **kwargs代表把关键字传来的参数拼成字典
    print(kwargs)

fun(a=1,b=2)  
d={'a':1,'b':2}
fun(**d)      # **kwargs代表把一个字典拆了

参数在调用函数的角度看:

  1.按照位置传参

  2.按照关键字传参

  3.动态传参 *tuple **dic

调用函数的规则:

1.函数名()
    函数名后面+圆括号就是函数的调用。
2.参数:
    圆括号用来接收参数。
    若传入多个参数:
        应按先位置传值,再按关键字传值
        具体的传入顺序应按照函数定义的参数情况而定
3.返回值
    如果函数有返回值,还应该定义“变量”接收返回值
    如果返回值有多个,也可以用多个变量来接收,变量数应和返回值数目一致

无返回值的情况:
函数名()

有返回值的情况:
变量 = 函数名()

多个变量接收多返回值:
变量1,变量2,... = 函数名()

总结:

  参数:

    实参:调用函数的时候传入的参数。

    形参:定义函数的时候用于接收参数的字母。

    位置参数:必须传值

      def test(a,b):

        print(a,b)

      test(1,2)

    默认参数:可以不传值

      def test(x=10):

        print(x)

      test()

      test(20)

    动态参数:*args,**kwargs     

      *args:

        def ccc(*args):#1,2,3,4,5
          print(args)

        ccc(1,2,3,4,5)#按位置传参数

        t = (1,2,3,4,5)
        ccc(t) ((1, 2, 3, 4, 5),)
        ccc(*t) (1, 2, 3, 4, 5)

      **kwargs:

        def ddd(**kwargs):
          print(kwargs)

        ddd(k = 'a',j = 'b')#按关键字传参数

        def eee(*args,**kwargs):
          print(args,kwargs)

        eee(12,123) #先按位置传参,再按关键字传参

        def ccc(*args):
          print('ccc:',args) #(1,2,3,4,5)
        def inner(a,b,c,d,e):
          print('inner',a,b,c,d,e)
        inner(*args) #*(1,2,3,4,5) 打散

        def inner(a,b,c,d,e):
          print('inner',a,b,c,d,e)
        ccc(1,2,3,4,5)
        inner(1,2,3,4,5)

      

============================================

函数的形参与实参:

#形参即变量名,实参即变量值,函数调用时,将值绑定到变量名上,函数调用结束,解除绑定
 1 #1、位置参数:按照从左到右的顺序定义的参数
 2         位置形参:必选参数
 3         位置实参:按照位置给形参传值
 4 
 5 #2、关键字参数:按照key=value的形式定义的实参
 6         无需按照位置为形参传值
 7         注意的问题:
 8                 1. 关键字实参必须在位置实参右面
 9                 2. 对同一个形参不能重复传值
10 
11 #3、默认参数:形参在定义时就已经为其赋值
12         可以传值也可以不传值,经常需要变得参数定义成位置形参,变化较小的参数定义成默认参数(形参)
13         注意的问题:
14                 1. 只在定义时赋值一次
15                 2. 默认参数的定义应该在位置形参右面
16                 3. 默认参数通常应该定义成不可变类型
17 
18 
19 #4、可变长参数:
20         可变长指的是实参值的个数不固定
21         而实参有按位置和按关键字两种形式定义,针对这两种形式的可变长,形参对应有两种解决方案来完整地存放它们,分别是*args,**kwargs
22 
23         ===========*args===========
24         def foo(x,y,*args):
25             print(x,y)
26             print(args)
27         foo(1,2,3,4,5)
28 
29         def foo(x,y,*args):
30             print(x,y)
31             print(args)
32         foo(1,2,*[3,4,5])
33 
34 
35         def foo(x,y,z):
36             print(x,y,z)
37         foo(*[1,2,3])
38 
39         ===========**kwargs===========
40         def foo(x,y,**kwargs):
41             print(x,y)
42             print(kwargs)
43         foo(1,y=2,a=1,b=2,c=3)
44 
45         def foo(x,y,**kwargs):
46             print(x,y)
47             print(kwargs)
48         foo(1,y=2,**{'a':1,'b':2,'c':3})
49 
50 
51         def foo(x,y,z):
52             print(x,y,z)
53         foo(**{'z':1,'x':2,'y':3})
54 
55         ===========*args+**kwargs===========
56 
57         def foo(x,y):
58             print(x,y)
59 
60         def wrapper(*args,**kwargs):
61             print('====>')
62             foo(*args,**kwargs)
63 
64 #5、命名关键字参数:*后定义的参数,必须被传值(有默认值的除外),且必须按照关键字实参的形式传递
65 可以保证,传入的参数中一定包含某些关键字
66         def foo(x,y,*args,a=1,b,**kwargs):
67             print(x,y)
68             print(args)
69             print(a)
70             print(b)
71             print(kwargs)
72 
73         foo(1,2,3,4,5,b=3,c=4,d=5)
74         结果:
75             2
76             (3, 4, 5)
77             3
78             {'c': 4, 'd': 5}
此乃重点

 

定义函数的时候,我们把参数的名字和位置确定下来,函数的接口定义就完成了。对于函数的调用者来说,只需要知道如何传递正确的参数,以及函数将返回什么样的值就够了,函数内部的复杂逻辑被封装起来,调用者无需了解。

Python的函数定义非常简单,但灵活度却非常大。除了正常定义的必选参数外,还可以使用默认参数、可变参数和关键字参数,使得函数定义出来的接口,不但能处理复杂的参数,还可以简化调用者的代码。

 定义默认参数要牢记一点:默认参数必须指向不变对象!

 *接受列表和元组,**接受字典

小结

Python的函数具有非常灵活的参数形态,既可以实现简单的调用,又可以传入非常复杂的参数。

默认参数一定要用不可变对象,如果是可变对象,程序运行时会有逻辑错误!

要注意定义可变参数和关键字参数的语法:

*args是可变参数,args接收的是一个tuple;

**kw是关键字参数,kw接收的是一个dict。

以及调用函数时如何传入可变参数和关键字参数的语法:

可变参数既可以直接传入:func(1, 2, 3),又可以先组装list或tuple,再通过*args传入:func(*(1, 2, 3))

关键字参数既可以直接传入:func(a=1, b=2),又可以先组装dict,再通过**kw传入:func(**{'a': 1, 'b': 2})

使用*args**kw是Python的习惯写法,当然也可以用其他参数名,但最好使用习惯用法。

命名的关键字参数是为了限制调用者可以传入的参数名,同时可以提供默认值。

定义命名的关键字参数在没有可变参数的情况下不要忘了写分隔符*,否则定义的将是位置参数。

1、写函数,,用户传入修改的文件名,与要修改的内容,执行函数,完成批了修改操作

 1 def modify_file(filename,old,new):
 2     import os
 3     with open(filename,'r',encoding='utf-8') as read_f,
 4         open('.bak.swap','w',encoding='utf-8') as write_f:
 5         for line in read_f:
 6             if old in line:
 7                 line=line.replace(old,new)
 8             write_f.write(line)
 9     os.remove(filename)
10     os.rename('.bak.swap',filename)
11 
12 modify_file('/Users/George/PycharmProjects/Python/a.txt','George','NB')
View Code


2、写函数,计算传入字符串中【数字】、【字母】、【空格] 以及 【其他】的个数

 1 def check_str(msg):
 2     res={
 3         'num':0,
 4         'string':0,
 5         'space':0,
 6         'other':0,
 7     }
 8     for s in msg:
 9         if s.isdigit():
10             res['num']+=1
11         elif s.isalpha():
12             res['string']+=1
13         elif s.isspace():
14             res['space']+=1
15         else:
16             res['other']+=1
17     return res
18 
19 res=check_str('hello name:George passowrd:111')
20 print(res)
View Code

3、写函数,判断用户传入的对象(字符串、列表、元组)长度是否大于5。

4、写函数,检查传入列表的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。

1 def func1(seq):
2     if len(seq) > 2:
3         seq=seq[0:2]
4     return seq
5 print(func1([1,2,3,4]))
View Code

5、写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其作为新列表返回给调用者。

1 def func2(seq):
2     return seq[::2]
3 print(func2([1,2,3,4,5,6,7]))
View Code

6、写函数,检查字典的每一个value的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。
dic = {"k1": "v1v1", "k2": [11,22,33,44]}
PS:字典中的value只能是字符串或列表

1 def func3(dic):
2     d={}
3     for k,v in dic.items():
4         if len(v) > 2:
5             d[k]=v[0:2]
6     return d
7 print(func3({'k1':'abcdef','k2':[1,2,3,4],'k3':('a','b','c')}))
View Code
原文地址:https://www.cnblogs.com/george92/p/8509189.html