本系列为作者在官网学习python时做的笔记,详见python官网
python标准库官方文档,查阅标准库相关的内容
python语言参考,查看python语法,该文档是简洁的,但试图做到准确和完整。非必要的内建对象类型和内建函数、模块的语义描述在 Python 标准库 中。
标准库和语言参考涵盖了python的所有内容,他们是互补的,如果在语言参考中没有找到需要的内容那么就一定在便准库文档中。
if 语句
if 语句包含零个或多个 elif 子句及可选的 else 子句。
for 语句
python中只有for in
1
2
3
4
5
6
7
8
|
>>> # Measure some strings:
... words = ['cat', 'window', 'defenestrate']
>>> for w in words:
... print(w, len(w))
...
cat 3
window 6
defenestrate 12
|
循环遍历该集合的副本或创建新集合
1
2
3
4
5
6
7
8
9
10
|
# Strategy: Iterate over a copy
for user, status in users.copy().items():
if status == 'inactive':
del users[user]
# Strategy: Create a new collection
active_users = {}
for user, status in users.items():
if status == 'active':
active_users[user] = status
|
range() 函数
内置函数 range()生成算术级数:
1
2
3
4
5
6
7
8
|
>>> for i in range(5):
... print(i)
...
0
1
2
3
4
|
给定的终止数值并不在要生成的序列
两个参数时,第一个参数是开始值,第二个参数是终止值
三个参数时,第三个参数是步长可以是负数
1
2
3
4
5
6
7
8
|
range(5, 10)
5, 6, 7, 8, 9
range(0, 10, 3)
0, 3, 6, 9
range(-10, -100, -30)
-10, -40, -70
|
range() 所返回的对象在许多方面表现得像一个列表,但实际上却并不是。我们称这样对象为 iterable
break 和 continue 语句,以及循环中的 else 子句
break 语句用于跳出最近的 for 或 while 循环.
else 子句在循环耗尽了可迭代对象 (使用 for) 或循环条件变为假值 (使用 while) 时被执行,但不会在循环被 break 语句终止时被执行。
continue 继续循环中的下一次迭代:
pass 语句
pass 语句什么也不做,这通常用于创建最小的类:
1
2
3
|
>>> class MyEmptyClass:
... pass
...
|
定义函数
1
2
3
4
5
6
7
8
9
10
11
|
>>> def fib(n): # write Fibonacci series up to n
... """Print a Fibonacci series up to n."""
... a, b = 0, 1
... while a < n:
... print(a, end=' ')
... a, b = b, a+b
... print()
...
>>> # Now call the function we just defined:
... fib(2000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
|
关键字 def 引入一个函数 定义。它必须后跟函数名称和带括号的形式参数列表。构成函数体的语句从下一行开始,并且必须缩进。
函数体的第一个语句可以(可选的)是字符串文字;这个字符串文字是函数的文档字符串或 docstring 。
函数的 执行 会引入一个用于函数局部变量的新符号表。函数中所有的变量赋值都将存储在局部符号表中;变量引用会首先在局部符号表中查找,然后是外层函数的局部符号表,再然后是全局符号表,最后是内置名称的符号表。 因此,全局变量和外层函数的变量不能在函数内部直接赋值(除非是在 global 语句中定义的全局变量,或者是在 nonlocal 语句中定义的外层函数的变量),但是它们可以被引用。
在调用函数时会将实际参数(实参)引入到被调用函数的局部符号表中;因此,实参是使用 按值调用 来传递的(其中的 值 始终是对象的 引用 而不是对象的值)。 当一个函数调用另外一个函数时,会为该调用创建一个新的局部符号表。
函数定义会将函数名称与函数对象在当前符号表中进行关联。 解释器会将该名称所指向的对象识别为用户自定义函数。 其他名称也可指向同一个函数对象并可被用来访问访函数:
1
2
3
4
5
|
>>> fib
<function fib at 10042ed0>
>>> f = fib
>>> f(100)
0 1 1 2 3 5 8 13 21 34 55 89
|
没有 return 语句的函数也会返回一个值,这个值称为 None (它是内置名称),可以通过print打印
1
2
3
|
>>> fib(0)
>>> print(fib(0))
None
|
函数定义的更多形式
参数默认值
对一个或多个参数指定一个默认值:
1
2
3
|
def ask_ok(prompt, retries=4, reminder='Please try again!'):
while True:
...
|
默认值在 定义
过程 中在函数定义处计算的,计算默认值只会执行一次(对于引用类型则指向的对象不变),所以下面这个实例会打印 5
1
2
3
4
5
6
7
|
i = 5
def f(arg=i):
print(arg)
i = 6
f()
|
1
2
3
4
5
6
7
|
def f(a, L=[]):
L.append(a)
return L
print(f(1))
print(f(2))
print(f(3))
|
这将打印出
1
2
3
|
[1]
[1, 2]
[1, 2, 3]
|
关键字参数
使用形如 kwarg=value 的 关键字参数 来调用
函数。
关键字参数必须跟随在位置参数(非关键字参数)的后面。传递的所有关键字参数必须与函数接受的其中一个参数匹配,它们的顺序并不重要。不能对同一个参数多次赋值。
最后一个形参为 **name
的时,它会接收一个字典 ,包含除了与已有形参相对应的关键字参数以外的所有关键字参数。 它可以与一个形式为 *name
,接收一个包含除了已有形参列表以外的位置参数的 元组 的形参组合使用 (*name
必须出现在 **name
之前。)
特殊参数
函数调用时的参数只有位置参数或是显式的关键字参数。
函数的定义看起来可以像是这样:
1
2
3
4
5
6
|
def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
----------- ---------- ----------
| | |
| Positional or keyword |
| - Keyword only
-- Positional only
|
/仅用于分割仅位置参数的形参,*仅用于分割仅关键字形参
*name
就是*
任意的参数列表
可变参数 将在形式参数列表的末尾,因为它们收集传递给函数的所有剩余输入参数。出现在 *args 参数之后的任何形式参数都是 ‘仅限关键字参数’,所以通常将 *后面的参数都设置为有默认值的形参:
1
2
3
4
5
6
7
|
>>> def concat(*args, sep="/"):
... return sep.join(args)
...
>>> concat("earth", "mars", "venus")
'earth/mars/venus'
>>> concat("earth", "mars", "venus", sep=".")
'earth.mars.venus'
|
解包参数列表
参数已经在列表或元组中,使用 * 操作符解包参数:
1
2
3
4
5
|
>>> list(range(3, 6)) # normal call with separate arguments
[3, 4, 5]
>>> args = [3, 6]
>>> list(range(*args)) # call with arguments unpacked from a list
[3, 4, 5]
|
同样的方式,字典可使用 ** 操作符 来提供关键字参数:
1
2
3
4
5
6
7
8
|
>>> def parrot(voltage, state='a stiff', action='voom'):
... print("-- This parrot wouldn't", action, end=' ')
... print("if you put", voltage, "volts through it.", end=' ')
... print("E's", state, "!")
...
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !
|
Lambda 表达式
可以用 lambda 关键字来创建一个小的匿名函数:
1
2
3
4
5
6
|
def make_incrementor(n):
# 用 :来分割参数和返回值
return lambda x: x + n
f = make_incrementor(42)
f(0)
|
函数标注
函数标注 是用户自定义函数中使用的类型的完全可选元数据信息。以字典的形式存放在函数的 annotations 属性中,并且不会影响函数的任何其他部分。
形参标注的定义方式是在形参名后加冒号,后面跟一个表达式,该表达式会被求值为标注的值。
返回值标注的定义方式是加组合符号 ->,后面跟一个表达式,该标注位于形参列表和表示 def 语句结束的冒号之间
1
2
3
4
5
6
7
8
9
|
>>> def f(ham: str, eggs: str = 'eggs') -> str:
... print("Annotations:", f.__annotations__)
... print("Arguments:", ham, eggs)
... return ham + ' and ' + eggs
...
>>> f('spam')
Annotations: {'ham': <class 'str'>, 'return': <class 'str'>, 'eggs': <class 'str'>}
Arguments: spam eggs
'spam and eggs'
|
对于要求传入迭代对象的参数
可以在调用函数的时候在实参中使用推导式以及lambda表达式来现场生成对象,比如
1
|
nx.draw_networkx(...,labels={n:prefix+n for n in G})
|
functools 模块应用于高阶函数,即参数或(和)返回值为其他函数的函数。详见官方文档
返回一个新的 部分对象,当被调用时其行为类似于 func 附带位置参数 args 和关键字参数 keywords 被调用。
官方文档
1
2
3
4
|
def f(m,n):
return m*n
re=partial(f,3)
print(re(4))#12
|