python入门--02 函数

Posted 快乐崇拜234

tags:

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

正文在下面,先打个广告:

函数定义def

def bijiao(param):
     if param > 0:
        return True
     elif param < 0:
        return False
     else:
        return "0"

print(bijiao(0)) #输出结果为0

返回多个值(其实是tuple)

def move(x, y):
    x = x + 10
    y = y+20
    return x, y

print(move(1,2))  # 结果为  (11, 22)

函数的参数

位置参数

即上面出现的普通参数

默认参数

def param(x, y, m=8, n=9):
    print('x =', x)
    print('y =', y)
    print('m =', m)
    print('n =', n)
param(1, 2, 4) # 按顺序传参
print('--')
param(1, 2, n=4) #如果不按顺序,需要明确指定参数名

结果:

x = 1
y = 2
m = 4
n = 9
--
x = 1
y = 2
m = 8
n = 4

注意:

  • 必选参数在前,默认参数在后
  • 当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数。
  • 默认参数一定要是不变对象

例:

def param(x, y = []):
    y.append(45)
    print(y)
param(1)
param(1)
param(1)

结果:

[45]
[45, 45]
[45, 45, 45]

可见 调用多次的时候执行结果会不一致。解决办法就是使用不可变对象。这里可以使用def param(x, y = None)来解决。

def param(x, y = None):
    if(y is None):
        y = []
    y.append(45)
    print(y)

输出

[45]
[45]
[45]

可变参数(动态传参)

格式定义: def param(*number)

def param(*number):
    print('length =', len(number))
    sum = 0
    for i in number:
        sum += i
    return sum

print(param(1,2,3))
print(param(*list(range(101))))  #Python允许你在list或tuple前面加一个`*`号,把list或tuple的元素变成可变参数传进去

结果:

length = 3
6
length = 101
5050

关键字参数

函数定义: def param(name, **student)

def param(name, **student):
    print('name = %s , other = %s' % (name, student))

param(1)
param(1,age=23, score = 456)
a = "age":"22", "score":"100"
param(1, **a)

结果:

name = 1 , other = 
name = 1 , other = 'age': 23, 'score': 456
name = 1 , other = 'age': '22', 'score': '100'

命名关键字参数

*不是参数,只是分隔符,表示后面的是命名关键字参数

def param(name, age, *, city='北京', job):
    print('name = %s , age = %s, city = %s, job = %s' % (name, age, city, job))

param(1, 10, job='coder')
param(1, 10, city = '杭州',job='coder')

结果:

name = 1 , age = 10, city = 北京, job = coder
name = 1 , age = 10, city = 杭州, job = coder

参数组合

在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用,除了可变参数无法和命名关键字参数混合。但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数/命名关键字参数和关键字参数

def f1(a, b, c=0, *args, **kw):
    print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)

def f2(a, b, c=0, *, d, **kw):
    print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)

f1(1, 2)
f1(1, 2 , c = 3)
f1(1, 2, 3, 'a', 'b' , x=99 , y=9 , z = 90)
f1(1, 2 , sss = 3)
print('--------')
f2(1, 2, 3, d=1111, x=10, y=20, z=30)
f2(1, 2, d=1111, x=10, y=20, z=30)

结果:

a = 1 b = 2 c = 0 args = () kw = 
a = 1 b = 2 c = 3 args = () kw = 
a = 1 b = 2 c = 3 args = ('a', 'b') kw = 'z': 90, 'y': 9, 'x': 99
a = 1 b = 2 c = 0 args = () kw = 'sss': 3
--------
a = 1 b = 2 c = 3 d = 1111 kw = 'z': 30, 'y': 20, 'x': 10
a = 1 b = 2 c = 0 d = 1111 kw = 'z': 30, 'y': 20, 'x': 10

对于任意函数,都可以通过类似func(*args,**kw) ( 通过一个tuple和dict ) 的形式调用它,无论它的参数是如何定义的

def f1(a, b, c=0, *args, **kw):
    print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)

def f2(a, b, c=0, *, d, **kw):
    print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)

args = (1, 2, 3, 4); kw = 'd': 99, 'x': '#'
f1(*args, **kw)
args = (1, 2, 3); kw = 'd': 88, 'x': '#'
f2(*args, **kw)

结果:

a = 1 b = 2 c = 3 args = (4,) kw = 'd': 99, 'x': '#'
a = 1 b = 2 c = 3 d = 88 kw = 'x': '#'

函数参数小结

  • 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的习惯写法,当然也可以用其他参数名,但最好使用习惯用法。
  • 命名的关键字参数是为了限制调用者可以传入的参数名,同时可以提供默认值。
  • 定义命名的关键字参数不要忘了写分隔符*,否则定义的将是位置参数。

递归函数

def fact(x):
    if(x == 1):
        return 1
  return x * fact(x - 1)
  
print(fact(100))

结果:
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

注:递归调用的次数过多,会导致栈溢出。不信试试print(fact(1000))
解决办法就是使用尾递归优化,但是这依赖于编译器优化,可惜大部分都没有进行优化,包括Python解释器
尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。

将上述计算阶乘的程序改成尾递归:

def fact(n):
return fact_iter(n, 1)

def fact_iter(num, product):
if num == 1:
return product
return fact_iter(num - 1, num * product)

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

python入门--02 函数

Python入门 —— 02基础语法

Python 函数的形态

OpenCV最详细入门-python(代码全部可以直接运行)

Python入门-6面向对象编程:02类的定义-类和对象的关系-构造函数-实例属性-实例方法

Python入门-5函数:02形参和实参-文档字符串-函数注释-返回值详解