Python3 高级实用手册 |【不定期更新】
本帖主要收集并展示:
实用(有效)的Python 3代码片段。
分为三部分:Python3新特性,入门级(Style ~ I/O)、高级(Regular Expression ~ C Extension)
鱼油可按照需求,拿来即用,就像酱紫:那些“diǎo diǎo”的内置函数
Python是瑞士军刀型的开源编程语言,被广泛应用于Web开发、爬虫、数据清洗、自然语言处理、机器学习和人工智能等方面。
Python语法简单,让许多初学者加入程序员大军,各行各业学多技术人员都开始转型使用Python。
本手册建立在大家有一定基础的前提下,基于Python 3.7,进行演示。
如果基础不好的鱼油,推荐一部良心(牛X、通俗易懂、欲罢不能)教程:
**** Hidden Message *****
虽然目前一些高校和开发者使用Python 2.7,但是Python官方团队将在2020年停止支持对Python 2.7的维护和更新。
Python 2.X 转向Python 3.X是大势所趋哈。
最后一个说明:
★后续帖子中,Pyhon 2简写为py2,Python 3简写为py3
★提供官方PEP Index中的具体索引传送门,例:PEP 3105
★演示代码中,>>>后为代码(01行),换行语句前有缩进(02-04行),结果靠右侧放在代码后(05行),例:
>>> for x in range(3):
print(x, end=' ')
else:
print()
0 1 2
欢迎鱼油交流补充完善{:10_330:}
如果喜欢,别忘了评分{:10_281:} :
http://xxx.fishc.com/forum/201709/19/094516hku92k2g4kefz8ms.gif
常用Python3 新特性
print 变为函数,PEP 3105
py2:
>>> print "print is a statement"
print is a statement
py3:
>>> print("print is a function")
print is a function
打印数字序列。
py2:
>>> for x in range(3):
print x,
0 1 2
py3:
>>> for x in range(3):
print(x, end=' ')
else:
print()
0 1 2
python 3中的字符串表示方法,PEP 3138
将UTF-8作为默认编码格式,PEP 3120
文本由unicode表示,为str类型;二进制数据由bytes (字节包)表示,为bytes类型。
支持非ASCII标识符,PEP 3131
py2:
>>> s = 'Café'# byte 字符串
>>> s
'Caf\xc3\xa9'
>>> type(s)
<type 'str'>
>>> u = u'Café' # unicode 字符串
>>> u
u'Caf\xe9'
>>> type(u)
<type 'unicode'>
>>> len()
5
py3:
>>> s = 'Café'
>>> s
'Café'
>>> type(s)
<class 'str'>
>>> s.encode('utf-8')
b'Caf\xc3\xa9'
>>> s.encode('utf-8').decode('utf-8')
'Café'
>>> len()
4
修改除法'/'操作符,PEP 238
py2:
>>> 1 / 2
0
>>> 1 // 2
0
>>> 1. / 2
0.5
#导入真除
>>> from __future__ import division
>>> 1 / 2
0.5
>>> 1 // 2
0
py3:
>>> 1 / 2
0.5
>>> 1 // 2
0
在函数中保留 ** kwargs 的顺序,PEP 468
保留类属性定义顺序,PEP 520
更紧凑的字典和更快的迭代,Issue 27350
py 3.5之前:
>>> import sys
>>> sys.getsizeof({str(i):i for i in range(1000)})
49248
>>> d = {'timmy': 'red', 'barry': 'green', 'guido': 'blue'}
>>> d # 无顺序保存
{'barry': 'green', 'timmy': 'red', 'guido': 'blue'}
py 3.6:
>>> import sys
>>> sys.getsizeof({str(i):i for i in range(1000)})
#36968
>>> d = {'timmy': 'red', 'barry': 'green', 'guido': 'blue'}
>>> d # 有顺序保存
{'timmy': 'red', 'barry': 'green', 'guido': 'blue'}
新添加的强制关键字参数,PEP 3102
py3:
>>> def f(a, b, *, kw):
print(a, b, kw)
>>> f(1, 2, 3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() takes 2 positional arguments but 3 were given
>>> f(1, 2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() missing 1 required keyword-only argument: 'kw'
>>> f(1, 2, kw=3)
1 2 3
新添加的super(),PEP 3135
super() 函数是用于调用父类(超类)的一个方法。
py2:
>>> class ParentCls(object):
def foo(self):
print "call parent"
>>> class ChildCls(ParentCls):
def foo(self):
super(ChildCls, self).foo()
print "call child"
>>> p = ParentCls()
>>> c = ChildCls()
>>> p.foo()
call parent
>>> c.foo()
call parent
call child
py3:
>>> class ParentCls(object):
def foo(self):
print("call parent")
>>> class ChildCls(ParentCls):
def foo(self):
super().foo()
print("call child")
>>> p = ParentCls()
>>> c = ChildCls()
>>> p.foo()
call parent
>>> c.foo()
call parent
call child
去除“<>”,不等号。
py2:
>>> a = "Python2"
>>> a <> "Python3"
True
等价于 !=
>>> a != "Python3"
True
py3:
>>> a = "Python3"
>>> a != "Python2"
不允许从模块内部导入"*"。
py3:
>>> def f():
from os import *
File "<stdin>", line 1
SyntaxError: import * only allowed at module level
添加非本地关键字,访问外部作用域中的变量,PEP 3104
py3:
>>> def outf():
o = "out"
def inf():
nonlocal o
o = "change out"
inf()
print(o)
>>> outf()
change out
可拓展的迭代解包,PEP 3132
py3:
>>> a, *b, c = range(5)
>>>print(a, b, c)
(0, , 4)
>>> for a, *b in [(1, 2, 3), (4, 5, 6, 7)]:
print(a, b)
1
4
附加的一般化解包方法,PEP 448
py2:
>>> def func(*a, **k):
print(a)
print(k)
>>> func(*, **{"foo": "bar"})
(1, 2, 3, 4, 5)
{'foo': 'bar'}
py3:
>>> print(*, 4, *)
1 2 3 4 5 6
>>> [*range(4), 4]
>>> {"foo": "Foo", "bar": "Bar", **{"baz": "baz"}}
{'foo': 'Foo', 'bar': 'Bar', 'baz': 'baz'}
>>> def func(*a, **k):
print(a)
print(k)
>>> func(*, *, **{"foo": "FOO"}, **{"bar": "BAR"})
(1, 4, 5)
{'foo': 'FOO', 'bar': 'BAR'}
函数注解,PEP 3107
类型标记(Type Hints),PEP 484
py3:
>>> import types
>>> generator = types.GeneratorType
>>> def fib(n: int) -> generator:
a, b = 0, 1
for _ in range(n):
yield a
b, a = a + b, b
>>>
#
函数注解语法可以让我们在定义函数的时候对参数和返回值添加注解。
n: int ,注解参数。
-> generator ,注解返回值。
为变量注解添加索引,PEP 526
py3:
>>> from typing import List
>>> x: List =
>>> x
>>> from typing import List, Dict
>>> class Cls(object):
x: List =
y: Dict = {"foo": "bar"}
>>> o = Cls()
>>> o.x
>>> o.y
{'foo': 'bar'}
支持键入模块(typing module)和泛型类型(generic types),PEP 560
py 3.7之前:
>>> from typing import Generic, TypeVar
>>> from typing import Iterable
>>> T = TypeVar('T')
>>> class C(Generic): ...
>>> def func(l: Iterable]) -> None:
for i in l:
print(i)
>>> func()
1
2
3
py 3.7:
>>> from typing import Iterable
>>> class C:
def __class_getitem__(cls, item):
return f"{cls.__name__}[{item.__name__}]"
>>> def func(l: Iterable]) -> None:
for i in l:
print(i)
>>> func()
1
2
3
将%操作符添加到字节和bytearray,PEP 461
py3:
>>> b'abc %b %b' % (b'foo', b'bar')
b'abc foo bar'
>>> b'%d %f' % (1, 3.14)
b'1 3.140000'
>>> class Cls(object):
def __repr__(self):
return "repr"
def __str__(self):
return "str"
'repr'
>>> b'%a' % Cls()
b'repr'
字符串插值,PEP 498
py3:
>>> py = "Python3"
>>> f'Awesome {py}'
'Awesome Python3'
>>> x =
>>> f'{x}'
''
>>> def foo(x:int) -> int:
return x + 1
>>> f'{foo(0)}'
'1'
>>> f'{123.567:1.3}'
'1.24e+02'
更多,待更新
命名
本章节主要科普一些官方推荐的命名方式,建议大家养成良好的创建变量习惯。
类(Class)
不推荐:
class fooClass: ...
class foo_class: ...
建议:
class FooClass: ...
函数(Function)
不推荐:
def CapCamelCase(*a): ...
def mixCamelCase(*a): ...
建议:
def func_separated_by_underscores(*a): ...
变量(Variable)
不推荐:
FooVar = "CapWords"
fooVar = "mixedCase"
Foo_Var = "CapWords_With_Underscore"
建议:
# 普通变量
var = "lowercase"
#官方变量
_var = "_single_leading_underscore"
# 避免和官方变量产生冲突
var_ = "single_trailing_underscore_"
# 私有变量
var = " __double_leading_underscore"
# 魔法方法
__name__
# 测试异常变量, ex: _, v = (1, 2)
_ = "throwaway"
实用(易忽略)的小技巧
在本章节主要收录一些经常使用的代码段,但是会被很多初学者忽略掉。
例如输出“Hello World的高级方法”,版本控制,循环分支...
(推荐:Hello World 程序的起源与历史)
Hello World
不管我们学习哪种编程语言,总是喜欢用“Hello World”来测试编译器环境的搭建成功。
在Python中,我们可以通过 _hello_ 等模块来打印这条著名的语句。
代码:
>>> print("Hello world!")
Hello world!
>>> import __hello__
Hello world!
>>> import __phello__
Hello world!
>>> import __phello__.spam
Hello world!
Python 版本
对于初学者来说,知道自己编译器中使用的是哪个版本的Python是非常重要的。
除了使用 python -v 来显示外,我们还可以使用 sys。
代码:
>>> import sys
>>> print(sys.version)
还可以使用 platform.python_version 来直接获得版本号:
>>> import platform
>>> platform.python_version()
'3.7.1'
此外我们还可以使用 sys.version_info 来动态检查版本是否高于(低于)指定版本:
>>> import sys
>>> sys.version_info >= (3, 6)
True
>>> sys.version_info >= (3, 7)
False
Ellipsis
Ellipsis对象用于表示索引查找[]中省略号(...)是否存在。
Ellipsis对象没有任何属性,等价于True。
在Python 3之后,用 ... 来表示该对象,代码:
>>> ...
Ellipsis
>>> ... == Ellipsis
True
>>> type(...)
<class 'ellipsis'>
还可以用 ... 来表示未实现的函数方法,代码:
>>> class Foo: ...
>>> def foo(): ...
...
if ... elif ... else
如果有多个判断条件,那可以通过 elif 语句添加多个判断条件,一旦某个条件为 True,那么将执行对应的表达式。
并在之代码执行完毕后跳出该 if-elif-else 语句块,往下执行。
代码:
>>> import random
>>> num = random.randint(0, 10)
>>> if num < 3:
print("less than 3")
elif num < 5:
print("less than 5")
else:
print(num)
less than 3
for...in
for..in语句是另一个循环语句,它用来迭代一个对象的序列,代码:
>>> for val in ["foo", "bar"]:
print(val)
foo
bar
当我们需要同时获取迭代对象的索引和值时,可以使用 enumerate ,该方法比 len(iterable) 更好用,代码:
>>> for idx, val in enumerate(["foo", "bar", "baz"]):
print(idx, val)
(0, 'foo')
(1, 'bar')
(2, 'baz')
while … else …
当用 while 语句进行循环时,还可以结合 else 实现当while循环中发生中断时,else不会运行,代码:
>>> n = 0
>>> while n < 5:
if n == 3:
break
n += 1
else:
print("no break")
长字符串
有的时候我们会写一个超长的字符串,可以考虑用多行字符串拼接的方法,代码:
# 长字符串
s = 'This is a very very very long python string'
# 用\拼接
s = "This is a very very very " \
"long python string"
# 括号拼接
s = (
"This is a very very very "
"long python string"
)
# 用+拼接
s = (
"This is a very very very " +
"long python string"
)
# 用'''拼接
s = '''This is a very very very \
long python string'''
列表
列表是我们用来存储对象的常用方式。
大多数情况下,程序员很关心对列表的如下操作:
获取、设置、搜索、过滤、排序。
接下来,针对列表将列举一些常见的操作和陷阱。
创建列表的通用方式
像如何创建,调用这些基础操作,不做介绍,直接上代码:
>>> a =
>>> 2 in a
True
>>> a
1
>>> a[-1]
5
>>> a
>>> a
>>> a
>>> a[::-1]
>>> a[:0:-1]
>>> a = 0
>>> a
>>> a.append(6)
>>> a
>>> a.extend()
>>> a
>>> del a[-1]
>>> a
>>> b =
>>> b
>>> a + b
初始化
如果列表中的值是固定的,我们可以通过 * 来完成批量操作:
>>> a = * 3
>>> a
>>> a = "foo"
>>> a
['foo', None, None]
复制
引用是指保存的值为对象的地址。
在 Python 语言中,一个变量保存的值除了基本类型保存的是值外,其它都是引用。
因此对于它们的使用就需要小心一些,代码:
>>> a=
>>> b=a
这种做法其实并未真正生成一个新的列表,b指向的仍然是a所指向的对象。
这样,如果对a或b的元素进行修改,a,b的值同时发生变化。
可行的复制:
>>> a=
>>> b=a[:]
这样修改a对b没有影响,修改b对a也没有影响。
但这种方法只适用于简单列表,也就是列表中的元素都是基本类型。
如果列表元素还存在列表的话,这种方法就不适用了。
原因就是:像 a[:] 这种处理,只是将列 表元素的值生成一个新的列表,如果列表元素也是一个列表。
如:a=],那么这种复制对于元素的处理只是复制的引用,而并未生成 的一个新的列表复制。
为了证明这一点,测试步骤如下:
>>> a=]
>>> b=a[:]
>>> b
]
>>> a.append(3)
>>> a
]
>>> b
]
可见,对a的修改影响到了b。
如果解决这一问题,可以使用copy模块中的 deepcopy 函数,修改测试如下:
>>> import copy
>>> a=]
>>> b=copy.deepcopy(a)
>>> b
]
>>> a.append(3)
>>> a
]
>>> b
]
有时候知道这一点是非常重要的,因为可能你的确需要一个新的列表,并且对这个新的列表进行操作,同时不想影响原来的列表。
切割列表
有些时候,像我们接受一个数据包,里面的数据可能会连成一个大段。
在这种情况下,我们要会切割对象,获取我们需要的数据:
>>> icmp = (
b"080062988e2100005bff49c20005767c"
b"08090a0b0c0d0e0f1011121314151617"
b"18191a1b1c1d1e1f2021222324252627"
b"28292a2b2c2d2e2f3031323334353637"
)
>>> head = slice(0, 32)
>>> data = slice(32, len(icmp))
>>> icmp
b'080062988e2100005bff49c20005767c'
列表解析式
Python中的列表解析式是个伟大的发明,但是要掌握好这个语法则有些难。
因为它们并是用来解决全新的问题:只是为解决已有问题提供了新的语法。
列表解析式是将一个列表(实际上适用于任何可迭代对象(iterable))转换成另一个列表的工具。
在转换过程中,可以指定元素必须符合一定的条件,才能添加至新的列表中。
这样每个元素都可以按需要进行转换,上代码:
>>>
>>> [(lambda x: x**2)(i) for i in range(10)]
>>>
>>>
>>> [(x, y) for x in range(3) for y in range(2)]
[(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1)]
每个列表解析式都可以重写为for循环,但不是每个for循环都能重写为列表解析式。
掌握列表解析式使用时机的关键,在于不断练习识别那些看上去像列表解析式的问题。
如果鱼油能将自己的代码改写成类似下面这个for循环的形式,那么也就可以将其改写为列表解析式:
new_things = []
for ITEM in A:
if condition_based_on(ITEM):
new_things.append("fishc " + ITEM)
改为列表解析式:
new_things = ["fishc " + ITEM for ITEM in A if condition_based_on(ITEM)]
列表解包
有时候为了代码可读性,我们会将列表拆包到某个变量。
在这种情况下,我们将N个变量作如下操作:
>>> arr =
>>> a, b, c = arr
>>> a, b, c
(1, 2, 3)
我们可以使用 * 将N个元素解包为中小于N的变量数。
例如一个数组有5个值,我们指定其中两个,剩下的都自动分给 *:
>>> arr =
>>> a, *b, c = arr
>>> a
1
>>> c
5
>>> b
指定其中三个:
>>> arr =
>>> a, b, *c, d = arr
>>> a, b, d
(1, 2, 5)
>>> c
枚举
枚举(enumerate)是一个内置函数,可以让我们在不使用 range(len(list)) 情况下获得索引和项值。
(range(5) <=> )
>>> for i, v in enumerate(range(3)):
print(i, v)
0 0
1 1
2 2
>>> for i, v in enumerate(range(3), 1): # start = 1
print(i, v)
1 0
2 1
3 2
zip()
使用zip()方法可以让我们一次迭代多个列表,只要其中一个列表迭代完成,整个迭代就会停止。
迭代的长度与最短列表相同:
>>> a =
>>> b =
>>> list(zip(a, b))
[(1, 4), (2, 5), (3, 6)]
>>> c =
>>> list(zip(a, b, c))
[(1, 4, 1)]
过滤
通过 filter 我们可以清楚掉我们不需要的项。
在 Python2 中 filter 返回一个 list,在 python3 中返回一个 object:
>>>
>>> l = ['1', '2', 3, 'Hello', 4]
>>> f = lambda x: isinstance(x, int)
>>> filter(f, l)
<filter object at 0x10bee2198>
>>> list(filter(f, l))
>>> list((i for i in l if f(i)))
栈
在python没有必要单独搞一个数据结构堆栈,因为列表中的 pop 和 append 方法可以让列表当作堆栈:
>>> stack = []
>>> stack.append(1)
>>> stack.append(2)
>>> stack.append(3)
>>> stack
>>> stack.pop()
3
>>> stack.pop()
2
>>> stack
模拟自定义类的成员测试
使用 __contains__ 方法完成类的成员测试:
class Stack:
def __init__(self):
self.__list = []
def push(self, val):
self.__list.append(val)
def pop(self):
return self.__list.pop()
def __contains__(self, item):
return True if item in self.__list else False
stack = Stack()
stack.push(1)
print(1 in stack) #True
print(0 in stack) #False
访问指定项
像列表一样对自定义类使用 get 和 set 操作,自定义 __getitem__ 和 __setitem__ 方法按照索引来检查和重写数据。
还可以通过 __len__ 方法来获取列表项数量:
class Stack:
def __init__(self):
self.__list = []
def push(self, val):
self.__list.append(val)
def pop(self):
return self.__list.pop()
def __repr__(self):
return "{}".format(self.__list)
def __len__(self):
return len(self.__list)
def __getitem__(self, idx):
return self.__list
def __setitem__(self, idx, val):
self.__list = val
stack = Stack()
stack.push(1)
stack.push(2)
print("stack:", stack) #stack:
stack = 3
print("stack:", stack) #stack:
print("num items:", len(stack)) #num items: 2
代理迭代
如果自定义容器类包列表然后我们想要对这个容器进行迭代,可以使用 __iter__ 方法将容器迭代委托给列表。
__iter__ 必须返回一个可迭代对象,不能直接返回列表:
class Stack:
def __init__(self):
self.__list = []
def push(self, val):
self.__list.append(val)
def pop(self):
return self.__list.pop()
def __iter__(self):
return iter(self.__list)
stack = Stack()
stack.push(1) #1
stack.push(2)#2
for s in stack:
print(s)
集合
使用set() 函数创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集、差集、并集等。
基本玩法:
>>> a =
>>> s = {x for x in a}
>>> s
set()
>>> s = {x for x in a if x > 3}
>>> s
set()
>>> s = {x if x > 3 else -1 for x in a}
>>> s
set()
结合list()方法:
>>> a =
>>> a
>>> ua = list(set(a))
>>> ua
两个set()连用:
>>> a = set()
>>> b = set()
>>> a | b
set()
>>> # or
>>> a =
>>> b =
>>> set(a + b)
set()
将项插入到集合:
>>> a = set()
>>> a.add(5)
>>> a
set()
>>> # or
>>> a = set()
>>> a |= set()
>>> a
set()
两个集合与操作:
>>> a = set()
>>> b = set()
>>> a & b
set()
找出两个集合中相同的项:
>>> a =
>>> b =
>>> com = list(set(a) & set(b))
>>> com
b包含a:
>>> a = set()
>>> b = set()
>>> a <=b
True
或者:
>>> a = set()
>>> b = set()
>>> b >= a
True
求差集(项在a中,但不在b中):
>>> a = set()
>>> b = set()
>>> a - b
set()
对称差集(项在a或b中,但不会同时出现在二者中):
>>> a = set()
>>> b = set()
>>> a ^ b
set()
字典
字典是另一种可变容器模型,且可存储任意类型对象。
字典的每个键值 key=>value 对用冒号 : 分割,每个键值对之间用逗号 , 分割,整个字典包括在花括号 {} 中 ,格式如下所示:
d = {key1 : value1, key2 : value2 }
键一般是唯一的,如果重复最后的一个键值对会替换前面的,值不需要唯一:
>>>dict = {'a': 1, 'b': 2, 'b': '3'}
>>> dict['b']
'3'
>>> dict
{'a': 1, 'b': '3'}
值可以取任何数据类型,但键必须是不可变的,如字符串,数字或元组。
一个简单的字典实例:
dict = {'Alice': '2341', 'Beth': '9102', 'Cecil': '3258'}
也可如此创建字典:
dict1 = { 'abc': 456 }
dict2 = { 'abc': 123, 98.6: 37 }
获得所有键:
>>> a = {"1":1, "2":2, "3":3}
>>> a.keys()
['1', '3', '2']
获得键和值:
>>> a = {"1":1, "2":2, "3":3}
>>> a.items()
找到相同键:
>>> a = {"1":1, "2":2, "3":3}
>>>
['3', '2']
>>> # better way
>>> c = set(a).intersection(set(b))
>>> list(c)
['3', '2']
>>> # or
>>>
['3', '2']
[('1', 1), ('3', 3), ('2', 2)]
更新字典:
>>> a = {"1":1, "2":2, "3":3}
>>> b = {"2":2, "3":3, "4":4}
>>> a.update(b)
>>> a
{'1': 1, '3': 3, '2': 2, '4': 4}
合并两个字典,py3.5之前(不包含3.5):
>>> a = {"x": 55, "y": 66}
>>> b = {"a": "foo", "b": "bar"}
>>> c = a.copy()
>>> c.update(b)
>>> c
{'y': 66, 'x': 55, 'b': 'bar', 'a': 'foo'}
3.5及以后:
>>> a = {"x": 55, "y": 66}
>>> b = {"a": "foo", "b": "bar"}
>>> c = {**a, **b}
>>> c
{'x': 55, 'y': 66, 'a': 'foo', 'b': 'bar'}
手动构造字典:
>>> class EmuDict(object):
... def __init__(self, dict_):
... self._dict = dict_
... def __repr__(self):
... return "EmuDict: " + repr(self._dict)
... def __getitem__(self, key):
... return self._dict
... def __setitem__(self, key, val):
... self._dict = val
... def __delitem__(self, key):
... del self._dict
... def __contains__(self, key):
... return key in self._dict
... def __iter__(self):
... return iter(self._dict.keys())
...
>>> _ = {"1":1, "2":2, "3":3}
>>> emud = EmuDict(_)
>>> emud# __repr__
EmuDict: {'1': 1, '2': 2, '3': 3}
>>> emud['1']# __getitem__
1
>>> emud['5'] = 5# __setitem__
>>> emud
EmuDict: {'1': 1, '2': 2, '3': 3, '5': 5}
>>> del emud['2']# __delitem__
>>> emud
EmuDict: {'1': 1, '3': 3, '5': 5}
>>> for _ in emud:
... print(emud, end=' ')# __iter__
... else:
... print()
...
1 3 5
>>> '1' in emud# __contains__
True
函数
定义函数功能文档:
def example():
"""这是一个神奇的函数,厉害到什么方法也木有"""
print("示例函数")
example.__doc__#这是一个神奇的函数,厉害到什么方法也木有
help(example) #输出上面的整个函数
默认参数:
>>> def add(a, b=0):
... return a + b
...
>>> add(1)
1
>>> add(1, 2)
3
>>> add(1, b=2)
3
可选参数:
>>> def example(a, b=None, *args, **kwargs):
... print(a, b)
... print(args)
... print(kwargs)
...
>>> example(1, "var", 2, 3, word="hello")
1 var
(2, 3)
{'word': 'hello'}
参数拆包:
>>> def foo(a, b, c='BAZ'):
... print(a, b, c)
...
>>> foo(*("FOO", "BAR"), **{"c": "baz"})
FOO BAR baz
仅关键字参数:
>>> def f(a, b, *, kw):
... print(a, b, kw)
...
>>> f(1, 2, kw=3)
1 2 3
>>> f(1, 2, 3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() takes 2 positional arguments but 3 were given
是否可调用:
>>> a = 10
>>> def fun():
... print("I am callable")
...
>>> callable(a)
False
>>> callable(fun)
True
获取函数名称:
>>> def example_function():
... pass
...
>>> example_function.__name__
'example_function'
lambda表达式:
>>> fn = lambda x: x**2
>>> fn(3)
9
>>> (lambda x: x**2)(3)
9
>>> (lambda x: )(2)
>>> (lambda x: x if x>3 else 3)(5)
5
遍历:
>>> def fib(n):
... a, b = 0, 1
... for _ in range(n):
... yield a
... b, a = a + b, b
...
>>>
装饰参数:
>>> from functools import wraps
>>> def decorator_with_argument(val):
... def decorator(func):
... @wraps(func)
... def wrapper(*args, **kwargs):
... print("Val is {0}".format(val))
... return func(*args, **kwargs)
... return wrapper
... return decorator
...
>>> @decorator_with_argument(10)
... def example():
... print("This is example function.")
...
>>> example()
Val is 10
This is example function.
等价于:
>>> def example():
... print("This is example function.")
...
>>> example = decorator_with_argument(10)(example)
>>> example()
Val is 10
This is example function.
待更新
谢谢分享 谢谢分享 谢谢分享 学习学习
谢谢分享
{:5_108:}学习学习 感谢分享 {:5_106:} 66666 感谢分享 良心作品,十分推荐 学习学习 感谢楼主分享 看瑞士军刀 看看隐藏内容 欲罢不能 看那看那看看看啊看 好 谢谢分享
页:
[1]