函数定义
方法:def 函数名(参数列表)
不显示指定函数返回值
>>> def fib(n):
... """print a fibonacci series up to n"""
... a, b = 0, 1
... while a < n:
... print(a, end=' ')
... a, b = b, a+b
... print()
...
>>> fib(2000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597复制
说明:
1、函数体的第一行为函数说明文档(可选)。查看文档:函数名.__doc__如下:
>>> fib.__doc__
'print a fibonacci series up to n'复制
2、函数名可赋值给另一个变量,该变量可用于函数调用
>>> fib
<function fib at 0x01959F18>
>>> f = fib
>>> f(50)
0 1 1 2 3 5 8 13 21 34复制
3、python中,定义函数时,不用声明函数参数类型
4、不显示指定函数返回值的函数,其返回值为:None(内置的),如下
>>> def fn():
... pass
...
>>> print(fn())
None复制
显示指定函数返回值
>>> def add():
... a = 3
... b = 5
... print("a added to b = %d" % (a+b))
... return a+b
...
>>> add()
a added to b = 8
8复制
返回list
>>> def fib2(n): # return Fibonacci series up to n
... """Return a list containing the Fibonacci series up to n"""
... result = []
... a, b = 0, 1
... while a < n:
... result.append(a)
... a, b = b, a+b
... return result
...
>>> f100 = fib2(100)
>>> f100
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]复制
指定缺省参数值
为一个或多个参数指定缺省参数值。
为一个或多个参数指定缺省参数值。
>>> def ask_ok(prompt, retries=4, complaint="yes or no, please!"):
... while True:
... ok = input(prompt)
... if ok in ('y', 'ye', 'yes'):# in 关键词,测试一个序列是否包含某个值
... return True
... if ok in('n', 'no', 'nop', 'nope'):
... return False
... retries = retries - 1
... if retries < 0:
... raise IOError('uncooperative user')
... print(complaint)
...
>>> ask_ok('Do you really want to quit?')
Do you really want to quit?y
True
>>> ask_ok('Do you really want to quit?', 2)
Do you really want to quit?y
True复制
注意:
1.缺省参数值可以是定义的变量,如下
>>> i = 5
>>> def f(arg = i):
... print(arg)
... i = 6
...
>>> f()
5
>>> f(7)
7复制
2.当参数默认值为可变对象,如list,dictionary,类的实例时要特别注意,如果函数修改可变对象,那么参数默认值也被修改,如下:
>>> def f(a, list=[]):
... list.append(a)
... return list
...
>>> f(1)
[1]
>>> f(2)
[1, 2] # 注意以下输出值在不断变化复制
要避免这种情况,则应使用None作为默认值,并在函数中手动判断,如下
>>> def f(a, List=None):
... if List is None:
... List = []
... List.append(a)
... return List
...
>>> f(1)
[1]
>>> f(2)
[2]复制
函数定义-关键词参数
>>> def testfn(arg1, arg2="i", arg3="show"):
... print("arg1:", arg1)
... print("arg2:", arg2)
... print("arg3:", arg3)
...
>>> testfn(100) #一个位置参数
arg1: 100
arg2: i
arg3: show
>>> testfn(100, "ai", "shouke") #全为位置参数
arg1: 100
arg2: ai
arg3: shouke
>>> testfn(arg1=100) #一个关键词参数
arg1: 100
arg2: i
arg3: show
>>> testfn(arg1=100, arg2="ai") #两个全为关键词参数
arg1: 100
arg2: ai
arg3: show
>>> testfn(100, arg2="ai") #一个位置参数,一个为关键词参数
arg1: 100
arg2: ai
arg3: show复制
注意:关键词参数后面不允许出现非关键词参数,即位置参数
>>> testfn(100, arg2="i", "shouke")
File "<stdin>", line 1
SyntaxError: non-keyword arg after keyword arg复制
函数定义-任意参数之*args,**kwarg
*args参数
通过在函数定义中指定*args形式的参数来接收任意个位置参数,*args接收形参列表除外的所有位置参数
>>> def concat(*args, seperator=","):
... return seperator.join(args)
...
>>> concat("earth", "mars", "venus", seperator=".")
'earth.mars.venus'
>>> concat(*["earth", "mars", "venus"], seperator=".")
'earth.mars.venus'复制
注意:从左往右,*args以前的参数只能为position参数,而之后只能为keyword参数,如下
>>> concat("earth", "mars", "venus", seperator="t", "position_arg")
File "<stdin>", line 1
SyntaxError: positional argument follows keyword argument
>>> def testfn(arg1, *position_args, **keyword_args):
... print("arg1:", arg1)
... print("arg2:", position_args)
... print("arg3:", keyword_args)
...复制
**kwargs参数
>>> def testfn(arg1, *position_args, **keyword_args):
... print("arg1:", arg1)
... for arg in position_args:
... print(arg)
... print("-" * 40)
... keys = sorted(keyword_args.keys())
... for key in keys:
... print(key, ":", keyword_args[key])
...
>>> testfn("value1", "value21", "value22", "value23", key="keyvalue1",
... key2 ="keyvalue2")
arg1: value1
value21
value22
value23
----------------------------------------
key : keyvalue1
key2 : keyvalue2复制
注意:
1.*args
必须出现在**kwargs
前面,即**kwargs
为最后一个形参
**kwargs
接收的是字典型参数,包含除与形参对应外的所有关键词参数。
解压参数列表
用*
操作符解压获取列表或元组存储的参数。
>>> args = [3, 6]
>>> for i in range(*args):
... print(i)
...
3
4
5复制
可用**
操作符解压存放在字典中的keyword参数:
>>> def testfn(arg1, arg2="i", arg3="shou"):
... print("arg1: ", arg1)
... print("arg2: ", arg2)
... print("arg3: ", arg3)
...
>>> value = {"arg1":"value1", "arg2":"value2", "arg3":"value3"}
>>> testfn(**value)
arg1: value1
arg2: value2
arg3: value3复制
注意:如上,字典中的item的key名称要和函数参数名保持一致,否则会出错
嵌套函数
>>> def func1():
... """ create nested function"""
... print("create nested function")
... def nestedfun():
... a, b = 3, 1
... print("a added to b = %d" % (a+b))
...
>>> func1()
create nested function复制
调用嵌套函数
>>> def func1():
... """ create nested function"""
... print("create nested function")
... def nestedfun():
... a, b = 3, 1
... print("a added to b = %d" % (a+b))
... nestedfun()
...
>>> func1()
create nested function
a added to b = 4复制
匿名函数之Lambda表达式
lambda arg1, agr2, ..., argN:expression
或者lambda:expression
expression
在语法上限制为单一表达式,不能使用类似if…elsif…else这样的结构。lambda返回匿名函数的地址,arg1~argN为匿名函数的参数,expression为匿名函数的函数体
lambda常用于内置函数map和filter中。
例1:返回3个参数的和
>>> f = lambda x, y, z: x+y+z
>>> f(1, 2, 3)
6复制
例2:匿名函数可以没有参数
>>> def g(n):
... return lambda:1 #可以无参数
...复制
例3:返回匿名函数
>>> def g(n):
... return lambda c: n+1
...
>>> g(1)
<function g.<locals>.<lambda> at 0x02535C00>复制
说明例中return返回lambd表达式返回的匿名函数地址
>>> f = g(1)
>>> f()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: <lambda>() missing 1 required positional argument: 'c'
>>> f(3) #调用匿名函数,3传递给参数c
2复制
注意参数的对应关系
例4:把返回的匿名函数当作参数传递
>>> pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
>>> pairs.sort(key=lambda pair:pair[1]) #sort按key排序,key根据list中每个元素中索引为1的参数
>>> pairs
[(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
>>>pairs.sort(key=lambda pair:pair[0]) # lambda pair:pair[0]把list每个元素的第1个参数作返回为key
>>> pairs
[(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]复制
说明:list中每个元素对应的key仅计算一次且用于整个排序过程。.
例5:
>>> filter_me = [1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 14, 15, 19, 22]
>>> result = filter(lambda x:x%2 == 0, filter_me)
>>> print(*result)
2 4 6 8 12 14 22
>>> print(*filter(str.isdigit,'s5678tring'))
5 6 7 8复制
说明:
filter(function, iterable)
复制
利用iterable中的元素构造一个列表。iterable 可以是序列,或者支持迭代操作的容器,或则是一个迭代器. 如果iterable为字符串、元组,结果类型和iterable类型相同,否则为一个列表.
filter(function, iterable) 等价于
[item for item in iterable if function(item)] 如果function不为None
[item for item in iterable if item] 如果function为None
例6:
>>> map_me = ["s", "h", "o", "u"]
>>> result = map(lambda x:"the letter is %s" % x, map_me)
>>> result
<map object at 0x0251F850>
>>> print(*result)
the letter is s the letter is h the letter is o the letter is u
>>> map_me_again = [[1,2], [3, 4], [5, 6]]
>>> result = map(lambda list:[list[1], list[0]], map_me_again)
>>> print(*result)
[2, 1] [4, 3] [6, 5]复制
说明:map函数主要用于需要对列表中的每个元素执行一个指定的操作
文档字符串
第一行应该是关于对象用途的简介。简短起见,不用明确的陈述对象名或类型,因为它们可以从别的途径了解到(除非这个名字碰巧就是描述这个函数操作的动词)。这一行应该以大写字母开头,以句号结尾
如果文档字符串有多行,第二行应该空出来,与接来下的描述明确分离。接下来的文档应该有一或多段描述对象的调用约定、边界效应等。
Python的解释器不会从多行的文档字符串中去除缩进,所以必要的时候应当自己清除缩进。第一行之后的第一个非空行决定了整个文档的缩进格式。(我们不用第一行是因为它通常紧靠着起始的引号,缩进格式显示的不清楚。)
以下是一个多行文档字符串的示例
>>> def my_function():
... """Do nothing,bug document it.
... #空出第二行
... No, really, it doesn't do anything.
... """
... pass
...
>>> print(my_function.__doc__)
Do nothing,bug document it.
No, really, it doesn't do anything.复制
函数注释(function annotations)
>>> def f(ham:42, eggs: int = 'spam') -> "Nothing to see here":
... print("Annotations:", f.__annotations__)
... print("Arguments:", ham, eggs)
...
>>> f('wonderful')
Annotations: {'return': 'Nothing to see here', 'ham': 42, 'eggs': <class 'int'>}
Arguments: wonderful spam
def twoSum(num1: int, num2: int=100) -> int:
sum = num1 + num2
return sum复制
函数参数中的冒号是参数的类型建议符,告诉程序员希望传入的实参的类型。函数后面跟着的箭头是函数返回值的类型建议符,用来说明该函数返回的值是什么类型、或者其它
编码风格
空格缩进,无tab键
每行不超过79个字符
使用空行分隔函数与类,以及函数内部大代码块
如果可以,注释单独占一行
使用文档字符串
操作符前后及逗号后面使用空格,括号符除外:a = f(1, 2) + g(3, 4)。
类及函数命名要一致。通常对类形如:CameClass,对函数:lower_case_with_underscores,且方法总是用self作为第一个方法参数的参数名
不要使用花销的编码。Python缺省为UTF-8,或任何情况下都适用的纯ASCII
如果仅有少部分人使用别的语言,不要使用非ASCII字符,
普通变量,小写字母,单词之间用_分割