python 函数参数的类型

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 函数参数的类型相关的知识,希望对你有一定的参考价值。

我想函数的参数是列表类型该怎么定义呢,求教。例如 def airfoil(a,b): a,b能是列表么?

1. 不同类型的参数简述
#这里先说明python函数调用得语法为:

复制代码
代码如下:

func(positional_args,
keyword_args,
*tuple_grp_nonkw_args,
**dict_grp_kw_args)

#为了方便说明,之后用以下函数进行举例
def test(a,b,c,d,e):

print a,b,c,d,e

举个例子来说明这4种调用方式得区别:

复制代码
代码如下:

#
#positional_args方式
>>>
test(1,2,3,4,5)
1 2 3 4 5

#这种调用方式的函数处理等价于
a,b,c,d,e = 1,2,3,4,5
print a,b,c,d,e

#
#keyword_args方式
>>>
test(a=1,b=3,c=4,d=2,e=1)
1 3 4 2 1

#这种处理方式得函数处理等价于
a=1
b=3
c=4
d=2
e=1
print a,b,c,d,e

#
#*tuple_grp_nonkw_args方式
>>>
x = 1,2,3,4,5
>>> test(*x)
1 2 3 4
5

#这种方式函数处理等价于

复制代码
代码如下:

a,b,c,d,e = x
print
a,b,c,d,e
#特别说明:x也可以为dict类型,x为dick类型时将键传递给函数
>>> y
'a': 1,
'c': 6, 'b': 2, 'e': 1, 'd': 1
>>> test(*y)
a c b e d

#
#**dict_grp_kw_args方式
>>>
y
'a': 1, 'c': 6, 'b': 2, 'e': 1, 'd': 1
>>> test(**y)
1 2 6
1 1

#这种函数处理方式等价于
a = y['a']
b = y['b']
... #c,d,e不再赘述
print
a,b,c,d,e

2.
不同类型参数混用需要注意的一些细节
  接下来说明不同参数类型混用的情况,要理解不同参数混用得语法需要理解以下几方面内容.

  首先要明白,函数调用使用参数类型必须严格按照顺序,不能随意调换顺序,否则会报错. 如 (a=1,2,3,4,5)会引发错误,;
(*x,2,3)也会被当成非法.

  其次,函数对不同方式处理的顺序也是按照上述的类型顺序.因为#keyword_args方式和**dict_grp_kw_args方式对参数一一指定,所以无所谓顺序.所以只需要考虑顺序赋值(positional_args)和列表赋值(*tuple_grp_nonkw_args)的顺序.因此,可以简单理解为只有#positional_args方式,#*tuple_grp_nonkw_args方式有逻辑先后顺序的.

  最后,参数是不允许多次赋值的.

  举个例子说明,顺序赋值(positional_args)和列表赋值(*tuple_grp_nonkw_args)的逻辑先后关系:

复制代码
代码如下:

#只有在顺序赋值,列表赋值在结果上存在罗辑先后关系
#正确的例子1
>>> x =
3,4,5
>>> test(1,2,*x)
1 2 3 4 5
#正确的例子2
>>>
test(1,e=2,*x)
1 3 4 5 2

#错误的例子
>>> test(1,b=2,*x)
Traceback (most recent call
last):
File "<stdin>", line 1, in <module>
TypeError: test()
got multiple values for keyword argument 'b'

#正确的例子1,处理等价于
a,b = 1,2 #顺序参数
c,d,e = x #列表参数
print a,b,c,d,e

#正确的例子2,处理等价于
a = 1 #顺序参数
e = 2 #关键字参数
b,c,d = x #列表参数

#错误的例子,处理等价于
a = 1 #顺序参数
b = 2 #关键字参数
b,c,d = x
#列表参数
#这里由于b多次赋值导致异常,可见只有顺序参数和列表参数存在罗辑先后关系

函数声明区别

  理解了函数调用中不同类型参数得区别之后,再来理解函数声明中不同参数得区别就简单很多了.

1. 函数声明中的参数类型说明

  函数声明只有3种类型, arg, *arg , **arg 他们得作用和函数调用刚好相反.
调用时*tuple_grp_nonkw_args将列表转换为顺序参数,而声明中的*arg的作用是将顺序赋值(positional_args)转换为列表.
调用时**dict_grp_kw_args将字典转换为关键字参数,而声明中**arg则反过来将关键字参数(keyword_args)转换为字典.
特别提醒:*arg
和 **arg可以为空值.

以下举例说明上述规则:

复制代码
代码如下:

#arg, *arg和**arg作用举例
def
test2(a,*b,**c):
print a,b,c
#
#*arg 和
**arg可以不传递参数
>>> test2(1)
1 ()
#arg必须传递参数
>>>
test2()
Traceback (most recent call last):
File "<stdin>", line 1,
in <module>
TypeError: test2() takes at least 1 argument (0 given)

#
#*arg将顺positional_args转换为列表
>>>
test2(1,2,[1,2],'a':1,'b':2)
1 (2, [1, 2], 'a': 1, 'b': 2)

#该处理等价于
a = 1 #arg参数处理
b = 2,[1,2],'a':1,'b':2 #*arg参数处理
c =
dict() #**arg参数处理
print a,b,c

#
#**arg将keyword_args转换为字典
>>>
test2(1,2,3,d=1:2,3:4, c=12, b=1)
1 (2, 3) 'c': 12, 'b': 1, 'd': 1: 2, 3:
4
#该处理等价于
a = 1 #arg参数处理
b= 2,3 #*arg参数处理
#**arg参数处理
c =
dict()
c['d'] = 1:2, 3:4
c['c'] = 12
c['b'] = 1
print
a,b,c

2. 处理顺序问题

  函数总是先处理arg类型参数,再处理*arg和**arg类型的参数.
因为*arg和**arg针对的调用参数类型不同,所以不需要考虑他们得顺序.

复制代码
代码如下:

def test2(a,*b,**c):
print
a,b,c
>>> test2(1, b=[1,2,3], c=1:2, 3:4,a=1)
Traceback (most
recent call last):
File "<stdin>", line 1, in
<module>
TypeError: test2() got multiple values for keyword argument
'a'
#这里会报错得原因是,总是先处理arg类型得参数
#该函数调用等价于
#处理arg类型参数:
a = 1
a = 1
#多次赋值,导致异常
#处理其他类型参数
...
print a,b,c

>>> def foo(x,y):
... def bar():
... print
x,y
... return bar
...
#查看func_closure的引用信息
>>> a =
[1,2]
>>> b = foo(a,0)
>>>
b.func_closure[0].cell_contents
[1, 2]
>>>
b.func_closure[1].cell_contents
0
>>> b()
[1, 2] 0

#可变对象仍然能被修改
>>> a.append(3)
>>>
b.func_closure[0].cell_contents
[1, 2, 3]
>>> b()
[1, 2, 3] 0
参考技术A python的变量只有在使用的时候才有类型。参数类型是可以随你的使用变化的。python里面,一切皆对象 参考技术B isinstance(object, class)函数,检查某个对象是不是某个类里的
例如:
>>>isinstance(1,int)
True
但是这个能不用就不用,毕竟你只要某个对象有某个方法就好,这样破坏的对象“多态”的特征。
参考技术C 可以是列表。实际上,"参数可以是什么类型"取决于函数体中定义的操作。只要该类型支持这个过程就可以。

比如

def dummy(a):
return a*2

可以接受整数或列表作为参数,因为列表也可以实现乘法。

想要每个元素乘2的话,

a = [i * 2 for i in a]本回答被提问者和网友采纳
参考技术D 当然可以是列表追问

我这个a,b就可以在主函数中以列表代入么?另外,列表中每个数多乘以2,可以直接用a[:] =a[:]*2么
还是一定要循环?

追答

看推荐答案吧。是正确的。

Python参数类型以及实现isOdd函数,isNum函数,multi函数,isPrime函数

Python参数类型以及实现isOdd函数,isNum函数,multi函数,isPrime函数

 

一、Python参数类型

形参:定义函数时的参数变量。

实参:调用函数时使用的参数变量。

 

参数传递的过程,就是把实参的引用传递给形参,使用实参的值来执行函数体的过程。

Python 中,函数的实参/返回值都是是靠引用来传递的。

在调用函数时,通常会传递参数,不同的参数处理不同的数据。一般有普通参数、默认参数、可变位置参数、可变关键字参数等。

 

1.普通参数:按照参数位置,依次传递参数。

def add(x,y):
    return x + y

print(add(3,4))

 

 

2.默认参数:定义函数时,可以给某个参数赋一个默认值。

调用函数时,如果没有传入默认参数的值,则在函数内部使用参数默认值。

要使用最常见的值作为默认值,从而简化函数的调用。

如果一个参数的值不能确定,则不应该设置默认值,具体的数值在调用函数时由外界传递。在调用函数时,如果有多个默认参数,需要指定参数名,这样解释器才能够知道参数的对应关系。

 

def add(x,y=1):
    return x+y

print(add(2))
print(add(2,3))

 

当一个参数有默认值时,调用时如果不传递此参数,会使用默认值。

注意:带默认值参数必须在不带默认值参数之后,否则会报错。

 

 

3.可变位置参数

定义参数时参数前面加一个*,表示这个参数是可变的,可以接受任意多个参数,这些参数构成一个元组,只能通过位置进行参数传递。实例如下:

 

求一组数字的最大值,最小值,参数个数:

def max(*a):
    m=n=a[0]
    for x in a:
        if x>=m:
            m=x
        else:
            n=x
    return m,n,len(a)

b=input(\'输入若干数字,用空格隔开:\').split()
print(max(*b))

 

运行结果:

 

 

关于最后一行:print(max(*b))*b的作用是解包,否则传递的是整个列表

如果不加*,则输出结果如下:

 

 

 

4.可变关键字参数

定义参数时,在前面加**,表示这个参数可变,可以接受任意多个参数,这些参数构成一个字典,只能通过关键字参数传递

 

参数的混合使用:

#位置参数可以和关键字参数一起使用。
#当位置可变参数和关键字可变参数一起使用的时候,可变位置参数必须在前。

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

fn(1,2,3,x=4,y=5)

 

 

#普通参数可以和可变参数一起使用,但是传参的时候必须匹配 

def fn(x,y,*args,**kwargs):
    print(x)
    print(y)
    print(args)
    print(kwargs)

fn(1,2,3,4,5,a=6,b=7)

 

 

#关键字可变参数不允许在普通参数之前
#下面的方式定义会出错

def fn(**kwargs,x):
    print(x)

fn(a=1,2)

 

 

#默认参数可以在可变位置参数之前

def fn(x=5,*args):

    print(x)

fn()

 

 

参数解构(拆包)

参数解构发生在函数调用的时候,可变参数发生在函数定义的时候。

 

解构有两种形式:

1.解构符号:*,解构的对象:可迭代对象。解构后的结果:位置参数。

2.解构符号:**,解构的对象:字典。解构的结果:关键字参数。

 

关键字参数解构,key必须是str类型

def add(a,b):
    return a+b

data = [4,3]
print(add(*data))#位置参数解构
data1 = {\'a\':3,\'b\':4}
print(add(**data1))#关键字参数解构

 

 

 

 

 二、程序练习题

 

5.2 实现 isOdd()函数,参数为整数,如果整数为奇数,返回True,否则返回False

 

实现代码如下:

def isOdd(num):

    if num%2!=0:

        return True

    else:

        return False


s=eval(input("请输入一个整数:"))

print(isOdd(s))        

 

运行结果:

 

 

 

 

 

5.3 实现 isNum()函数,参数为一个字符串,如果这个字符串属于整数、浮点数或复数的表示,则返回True,否则返回False

 

实现代码如下:

def isNum(num):

    try:        

        n=type(eval(num))

        if n==type(1):#输入为整型

            return True

        elif n==type(1.0):#输入为浮点型

            return True

        elif n==type(1+1j):#输入为复数

            return True       

    except:

        return False


n=input("请输入一个字符串:")

print(isNum(n))

 

运行结果:

 

 

 

 

 

 

 

 

 

5.4 实现 multi()函数,参数个数不限,返回所有参数的乘积。

 

实现代码如下:

def multi(s):

    m = 1

    for i in s:

        m *= int(i)

    return m


n=input("请输入若干整数:").split()

print(multi(n))

 

运行结果:

 

 

 

5.5 实现 isPrime()函数,参数为整数,要有异常处理。如果整数是质数,返回True,否则返回False

 

实现代码如下:

def isPrime(num):   

    try:

        num = eval(num)

        if type(num) == type(1):#判断输入是否为整型

            if num<=1:#判断一个数字是否是质数:质数是一个只能被自己和1整除的大于1的正整数。注意1不是质数。

                return False

            elif num==2:#2是质数,这里单独作为一个条件是为了与下面的判断条件区分

                return True

            else:

                for i in range(2,num):#这里考虑的是大于2的正整数num,将这个数依次除以从2到num-1的整数进行取模运算,只要有一个数使它余数为0就说明它不是质数

                    if num % i == 0:

                        return False

                    else:

                        return True                     

        else:
    
            raise ValueError#引发ValueError异常

    except ValueError:#传入参数异常处理

        return "输入有误!请输入整数!"#这里没有使用print语句,如果没有给定return一个返回值,则函数的返回值为None

    except:#其他异常处理

        return "输入有误!请输入整数!"


n = input("请输入一个整数:")

print(isPrime(n))        

 

运行结果:

 

 

 

 

 

 

 

 

以上是关于python 函数参数的类型的主要内容,如果未能解决你的问题,请参考以下文章

Python参数类型

Python函数的参数类型

python-函数可变参数类型

Python函数参数类型及用法

python函数参数类型:位置参数默认参数动态参数

Python参数类型以及实现isOdd函数,isNum函数,multi函数,isPrime函数