位置参数
# 计算x^2,参数x就是一个位置参数
def power(x):
return x * x
# 计算x的n次方, 上面的函数不能实现, 修改为以下方式
def power(x, n):
s = 1
while n > 0:
n = n - 1
s = s * x
return s
默认参数
- 一是必选参数在前,默认参数在后
- 二是如何设置默认参数。
当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数。 - 三 默认参数必须指向不变对象!
def power(x, n=2):
s = 1
while n > 0:
n = n - 1
s = s * x
return s
print(power(3))
可变参数
def calc(numbers):
# numbers 必须要传递list[]或是tuple整体
sum = 0
for n in numbers:
sum = sum + n * n
return sum
print(calc([1,2,3]),calc((1,2,3)))
使用可变参数改造
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
print(calc(1,2,3,4)) # 可以传递任意位参数
li = [1,2,3] ; tup = (1,2,3)
print(calc(*li),calc(*tup)) # 也可以传递listh或tuple
关键字参数
可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。 而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
person('zhangsan',18,hair='blue',car='bwm')
extra = {'city': 'Beijing', 'job': 'Engineer'}
# 注意kw获得的dict是extra的一份拷贝,对kw的改动不会影响到函数外的extra。
person('lance',25,**extra)
person('lance',25,city=extra['city'])
命名关键字参数
对于关键字参数,函数的调用者可以传入任意不受限制的关键字参数。至于到底传入了哪些,就需要在函数内部通过kw检查。 和关键字参数**kw不同,命名关键字参数需要一个特殊分隔符*,*后面的参数被视为命名关键字参数。
def person(name, age, *, city, job):
print(name, age, city, job)
person('wolf',20,city='chengdu',job='python developer')
# person('wolf',20,city='chengdu',la='python developer')
# 函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*
def person(name, age, *args, city, job):
print(name, age, args, city, job)
# 命名关键字参数, 默认参数参数, 简化传参
def person(name, age, *, city='Beijing', job):
print(name, age, city, job)
参数组合
参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。 虽然可以组合多达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)
args = (1, 2, 3, 4)
kw = {'d': 99, 'x': '#'}
f1(*args, **kw)
测试
def mul(*args):
mul = 1
for num in args:
mul *= num
return mul
print('mul(5, 6) =', mul(5, 6));
print('mul(5, 6, 7) =', mul(5, 6, 7))
print('mul(5, 6, 7, 9) =', mul(5, 6, 7, 9))
if mul(5) != 5:
print('测试失败!')
elif mul(5, 6) != 30:
print('测试失败!')
elif mul(5, 6, 7) != 210:
print('测试失败!')
elif mul(5, 6, 7, 9) != 1890:
print('测试失败!')
else:
print(mul())
递归
# fact(n)=n!=1×2×3×???×(n?1)×n=(n?1)!×n=fact(n?1)×n
def fact(n):
if(n ==1):
return n
return n * fact(n-1)
print(fact(10))
- 所有的递归函数都可以写成循环的方式
- 使用递归函数需要注意防止栈溢出。 fact(10000)
- 尾递归优化:解决递归调用栈溢出的方法是通过尾递归优化
- 在函数返回的时候,调用自身本身,并且,return语句不能包含表达式
这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况 - Python标准的解释器没有针对尾递归做优化,任何递归函数都存在栈溢出的问题。
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)
|