关闭

Python学习笔记三:函数

255人阅读 评论(0) 收藏 举报
分类:


1、返回多个值


函数可以返回多个值,其实是将它们作为一个元组:


return x,y其实返回的是(x,y)。


2、函数的默认参数


>>> def add_end(L=[]):
...     L.append('END')
...     return L
... 
>>> add_end()
['END']
>>> add_end()
['END', 'END']
>>> add_end()
['END', 'END', 'END']


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


def add_end(L=None):
    if L is None:
        L = []
    L.append('END')
    return L

3、可变参数


如下定义:
def calc(*numbers):
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum
调用时可以提供0个或任意个数字作为参数:


calc(1,2)
calc()
nums = [1, 2, 3]
calc(*nums)


这样调用时将多个数字组装成一个元组,而如果参数本身是元组,调用时前面加*。


4、关键字参数


关键字参数在函数内部自动组装为一个dict。


def person(name, age, **kw):
    print('name:', name, 'age:', age, 'other:', kw)


调用时可以只输入必选参数:
>>> person('Michael', 30)
name: Michael age: 30 other: {}


也可以输入其他可变参数:
>>> person('Adam', 45, gender='M', job='Engineer')
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}


还可以将一个字典作为可变参数:
>>> extra = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, **extra)
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}


5、命名关键字参数


如果要限制关键字参数的名字,可以使用命名关键字参数:


def person(name, age, *, city, job):
    print(name, age, city, job)
注意:name、age是位置参数,*不是参数而是位置符号,city、job是命名关键字参数。
调用如下:
>>> person('Jack', 24, city='Beijing', job='Engineer')
Jack 24 Beijing Engineer
命名关键字参数必须传入参数名。


6、函数定义的例子


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)
a = 1 b = 2 c = 0 args = () kw = {}
>>> f1(1, 2, c=3)
a = 1 b = 2 c = 3 args = () kw = {}
>>> f1(1, 2, 3, 'a', 'b')
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {}
>>> f1(1, 2, 3, 'a', 'b', x=99)
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99}
>>> f2(1, 2, d=99, ext=None)
a = 1 b = 2 c = 0 d = 99 kw = {'ext': None}


神奇的调用:
>>> args = (1, 2, 3, 4)
>>> kw = {'d': 99, 'x': '#'}
>>> f1(*args, **kw)
a = 1 b = 2 c = 3 args = (4) kw = {'d': 99, 'x': '#'}
>>> args = (1, 2, 3)
>>> kw = {'d': 88, 'x': '#'}
>>> f2(*args, **kw)
a = 1 b = 2 c = 3 d = 88 kw = {'x': '#'}


7、生成器yield


对于斐波拉契数列(Fibonacci):
1, 1, 2, 3, 5, 8, 13, 21, 34, ...
可以这样打印出来:
def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        print(b)
        a, b = b, a + b
        n = n + 1
    return 'done'
使用生成器:
def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return


使用next调用:
>>> fib(6)
<generator object fib at 0x7fe7ba7719b0>
>>> o=fib(6)
>>> next(o)
1
>>> next(o)
1
>>> next(o)
2
>>> next(o)
3
>>> next(o)
5
>>> next(o)
8
>>> next(o)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration


正常的调用:


>>> o=fib(6)
>>> def p(o):
...     while True:
...         try:
...             x=next(o)
...             print(x)
...         except StopIteration as e:
...             print('StopIteration')
...             break
... 
>>> p(o)
1
1
2
3
5
8
StopIteration




8、返回函数


>>> def lazy_sum(*args):
...     def sum():
...         ax = 0
...         for n in args:
...             ax=ax+n
...         return ax
...     return sum
... 
>>> f=lazy_sum(1,3,5,7,9)
>>> f
<function sum at 0x7fe7ba7867d0>
>>> f()
25


9、匿名函数lambda


>>> list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
[1, 4, 9, 16, 25, 36, 49, 64, 81]


10、装饰器


以输出日志为例:


不带参数的装饰器:


import functools


def log(func):
    @functools.wraps(func)
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper

带参数的装饰器:


import functools


def log(text):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            print('%s %s():' % (text, func.__name__))
            return func(*args, **kw)
        return wrapper
    return decorator


@functools.wraps(func)语句的功能是使func.__name__的值保持不变。


11、偏函数


>>> def func(a,b):
...     return a+b
... 
>>> func('what\'s ','up')
"what's up"
>>> func(1,2)
3


>>> import functools
>>> func2=functools.partial(func,b='end')
>>> func2('it\'s ')
"it's end"
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:67737次
    • 积分:1428
    • 等级:
    • 排名:千里之外
    • 原创:74篇
    • 转载:19篇
    • 译文:2篇
    • 评论:2条
    最新评论