一.python函数
1.内置函数
内置函数
- 无需导包即可使用的函数
- 不同版本的Python内置函数可能略有不同
之前已经接触过的内置函数
- type()、dir()、input()、print()、id()
各版本内置函数和使用方法参考文档
- https://docs.python.org/zh-cn/3/library/functions.html
2.自定义函数
定义函数
def func_name(参数列表):
函数体
[return/yield 函数返回值]
Python函数的特点
- 函数参数类型多样
- 允许嵌套函数
- 无需声明函数返回值类型
- yield可以作为函数返回值的关键字
- 函数能够被赋值给变量
Python的函数参数
- 无参函数
def show_log():
print('I am a log')
show_log()
- 位置参数:传入的参数与定义的参数一一对应
def func_name(arg1,arg2,arg3):
print(arg1,arg2,arg3)
func_name(val1,val2,val3)
- 关键字参数:直接通过等号传递参数,参数顺序可不一样
def func_name(arg1,arg2,arg3):
print(arg1,arg2,arg3)
func_name(arg1=val1,arg3=val3,arg2=val2)
- 默认值参数:定义函数时,设置参数的默认值
- 调用函数时,可以指定通过位置或者关键字指定参数的值,如果不指定,参数为默认值
def func_name(arg1=val1,arg2=val2,arg3=val3) :
print(arg1,arg2,arg3)
func_name()
- 定义默认值参数的错误示范,对顺序有严格要求
def func1(x=10, y) : # <= ERROR!
value = x + y ** 2
if value > 5 :
return value
不定长参数
- 参数的个数不确定
- 可适应更加复杂情况
- 不定长参数种类
- 包裹(packing)位置参数:接收不定长的位置参数,参数被组织成一个元组传入
- 包裹(packing)关键字参数:接收不定长的关键字参数,参数被组织成一个字典传入
包裹(packing)位置参数
- 参数表示为*args
- 调用函数时,参数自动会组织成一个元组传入
- 传入的位置参数与组织成的元组索引位置一致
def func2( *t ) : # t is a tuple
print(t)
func2() # no argument
func2(1,2,3)
func2(1,2,3,4,5)
包裹(packing)关键字参数
- 参数表示为**kwargs
- 调用函数时,参数自动会组织成一个字典传入
- 传入的位置参数与组织成的字典的键值对一致
def func3( **d ) : # d is a dictionary
print(d)
func3() # no argument
func3(a=1, b=2, c=3)
不同类型函数参数混用顺序
- 位置参数
- 默认值参数
- 包裹位置参数
- 包裹关键字参数
def func5(x, y=10, *args, **kwargs) :
print(x, y, args, kwargs)
func5(0)
func5(a=1, b=2, y=3, x=4)
func5(1, 2, 3, 4, a=5, b=6)
函数是对象
- Python中函数是对象
- 函数可以被引用,即函数可以赋值给一个变量
- 函数可以当做参数传递
- 函数可以作返回值
- 函数可以嵌套
def factorial(n):
if n <= 2: return n
return factorial(n-1)*n
f=factorial
f(4)
l=[factorial, f]
l[0](4)
l[1](4)
d={'x':factorial}
d['x'](4)
嵌套函数
- 在函数内部定义新的函数
- 内部函数不能被外部直接调用
- 函数可以被当做变量赋值,因为本质函数是一个对象
def func6() :
def nestedFunc() :
print('Hi')
return nestedFunc
x = func6() # x is the nestedFunc
x()
装饰器
- 修改其他函数的功能的函数
- 使函数更加简洁
def my_decorator(some_func):
def wrapper(*args):
print("I am watching you!")
some_func(*args)
print("You are called.")
return wrapper
@my_decorator
def add(x, y):
print(x,'+',y,'=',x+y)
add(5,6)
函数的返回值
- 函数无需声明返回值类型
- 在函数没有返回值时,函数默认返回None
- return关键字用于返回返回值
yield关键字
- 当函数使用yield关键字时,函数变为生成器
- 生成器是Python中的一种可迭代对象
- 能够使用for循环遍历
- 生成器每次只被读取一次
- 生成器有内置方法__next()__,调用后返回下一个元素
- yield不会终止程序,返回值之后程序继续运行
示例:求斜边小于n的勾股数组合
def list_pythagorean_triples(n) :
for c in range(n):
for a in range(1, c):
for b in range(1, c):
if a*a+b*b==c*c and a<b:
yield (a,b,c)
- 生成器的使用方法
- for循环迭代生成器
- next()函数从生成器中取值
- 构造生成器的结果列表
#使用循环迭代生成器
for i in list_pythagorean_triples(35):
print(i)
#使用next()方法从生成器中取值
g = list_pythagorean_triples(100)
next(g)
#构造生成器的结果列表
g = list_pythagorean_triples(100)
list(g)
- 生成器表达式
(x**3 for x in range(10))
- 列表生成式
[x**3 for x in range(10)]
二.变量作用域
变量作用域
- 变量能够生效的范围
按照作用域划分变量类型
- 全局变量
- 局部变量
全局变量:定义在模块中的变量
- 全局变量在整个模块中可见
- globals()函数:返回所有定义在改模块中的全局变量
- 修改全局变量时,要先使用global关键字声明变量
msg = 'created in module'
def outer_1() :
def inner() :
print("print in inner",msg)
inner()
outer_1()
msg = 'created in module'
def outer() :
def inner() :
global msg
msg = 'changed in inner'
inner()
outer()
print(msg)
局部变量:定义在函数中的变量
- 局部变量仅在定义的函数中可见
- locals()函数:返回所有定义在函数中的局部变量
- 自由变量:在函数中使用,但未定义在该函数中的非全局变量
def outer_1() :
msg = 'created in outer'
def inner() :
print(msg) # msg is a Free variable
inner()
outer_1()
nonlocal关键字:修改自由变量时,要先使用nonlocal关键字声明变量
def outer():
msg = 'created in outer'
def inner() :
nonlocal msg
msg = 'changed in inner' # msg is a Free variable
inner()
print(msg)
outer()
LEGB规则:使用 LEGB 的顺序来查找一个符号对应的对象
- Local -> Enclosed -> Global -> Built-in
- Local:一个函数或者类方法内部
- Enclosed:嵌套函数内
- Global:模块层级
- Built-in:Python内置符号
type=4
def f1():
type=3
def f2():
type=2
def f3():
type=1
print('type=', type)
f3()
f2()
f1()
三.lambda表达式
lambda表达式是一个匿名的函数
- 只包含一条语句, 并自动返回这条语句的结果
- 语法如下:
lambda param1, param2, … : expression
- 使用示例
f=lambda x: x * x
f(3)
# return results of +, -, *, //, % in a list
lambda x,y: [x+y, x-y, x*y, x//y, x%y]
# return max, min, sum in a tuple
lambda *n: (max(n), min(n), sum(n))
# sum 1 to n
lambda n: sum(range(1, n+1))
filter()函数中使用lambda表达式
- 过滤掉不符合条件的元素,返回由符合条件元素组成的新列表
items=[0, 1, 2, 3, 4, 5]
list(filter(lambda x: x%2==0, items))
list(filter(None, items))
map()函数中使用lambda表达式
- 根据提供的函数对指定序列做映射
i1=[1, 2, 3, 4, 5, 6]
i2=[11, 12, 13, 14]
i3=[111, 112]
list(map(lambda x,y,z: x+y+z, i1, i2, i3))
max()函数中使用lambda表达式
- 返回序列中的最大值
max(1,2,3,4)
max([1,2,3,4])
max([1,2,3,4], key=lambda x:-x)
min()函数中使用lambda表达式
- 返回序列中的最小值
min(1,2,3,4)
min([1,2,3,4])
min([1,2,3,4], key=lambda x:-x)
sorted()函数中使用lambda表达式
- 对序列进行排序
sorted([1,2,3,4], reverse=True)
sorted([1,2,3,4], key=lambda x:-x)
四.Python中使用正则表达式
Python正则表达式模块
- re模块
常用方法
表达式 | 说明 |
---|---|
compile() | 用于编译正则表达式,生成一个正则表达式( Pattern )对象 |
match() | 查看字符串的开头是否符合匹配模式,如果匹配失败,返回None |
search() | 扫描整个字符串并返回第一个成功的匹配 |
findall() | 在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表 |
sub() | 替换字符串中的匹配项 |
正则表达式常用符号及示例
符号 | 说明 | 示例 |
---|---|---|
(空) | 逐字匹配 | re.match(‘abc’, ‘abc123’)# match! |
re.match(‘abc’, ‘123abc’)# not match! | ||
| | 或 | re.match(‘abc|xyz’, ‘xyz123’) # match! |
. | 除换行符外匹配任意字符 | re.match(’.’, ‘123abc’) # match! |
[…] | 匹配任意一组字符中的一个 | re.match(’[aAbc]’, ‘b’) # a, A, b, or c |
re.match(’[a-c]’, ‘b’) # a to c | ||
re.match(’[A-C0-9]’, ‘B’) # A to C and 0 to 9 | ||
[^…] | 匹配不在[ ]中的字符 | re.match(’[^A-Z0-9]’, ‘b’)# not A to Z nor 0 to 9 |
\d | 匹配任意数字 | re.match(r’\d’, ‘8’) # match! |
\D | 匹配任意非数字 | re.match(r’\D’, ‘B’) # match! |
\w | 匹配字母数字及下划线 | re.match(r’\w’, ‘_’) # match! |
\W | 匹配非字母数字及下划线 | re.match(r’\W’, ‘?’) # match! |
\s | 匹配任意空白字符 | re.match(r’\s’, ’ ') # match! |
\S | 匹配任意非空字符 | re.match(r’\S’, ‘#’) # match! |
^ | 匹配字符串的开头 | re.findall(’1’, ‘xabc’) # not found |
$ | 匹配字符串的末尾 | re.findall(’[c]$’, ‘cc cc’) # found one |
\b | 匹配一个单词边界 | re.findall(r’\bc’, ‘cc cc’) # cc cc |
\B | 匹配非单词边界 | re.findall(r’c\B’, ‘cc cc’) # cc cc |
re* | 匹配0个或多个的表达式 | re.match(’[abc]*’, ‘xabc’) # match |
re+ | 匹配1个或多个的表达式 | re.match(’[abc]+’, ‘abcd’) # match |
re? | 匹配0个或1个表达式 | re.match(’[abc]?’, ‘xabc’) # match |
re{n} | 匹配n个前面的表达式 | re.match(’[abc]{2}’, ‘abc’) # match |
re{n, m} | 匹配n到m次前面的表达式 | re.match(’[abc]{1,3}’, ‘abc’) # match |
?= | 前向肯定界定符 | 用\b\w+(?=ing\b)查找I’m singing while you’re dancing.匹配到sing danc |
?! | 前向否定界定符 | \d{3}(?!\d)匹配三位数字,而且这三位数字的后面不能是数字 |
?<= | 向后肯定界定符 | 用(?<=\bre)\w+\b查找reading a book得到ading。 |
?<! | 向后否定界定符 | (?<![a-z])\d{7}匹配前面不是小写字母的七位数字 |
默认为贪婪匹配
- re.match(’.{2,6}c’, ‘cc cc cc’) # match ‘cc cc c’
?为非贪婪匹配
- re.match(’.{2,6}?c’, ‘cc cc cc’) # match ‘cc c’
正则替换
- re.sub(‘a?’, ‘-’, ‘bb’) # result: ‘-b-b-’
- re.sub(‘a*’, ‘-’, ‘bb’) # result: ‘-b-b-’
使用()分组
match=re.match(r'(\d+)', '123')
groups=match.groups() # groups is ('123',)
g1=match.group(1) # g1 is '123'
match=re.match(r'(\d)(\d)(\d)', '123')
groups=match.groups() # groups is ('1', '2', '3')
g1=match.group(1) # g1 is '1'
g2=match.group(2) # g2 is '2'
g3=match.group(3) # g3 is '3'
\1…\9匹配第n个分组的内容
ma = re.match(r'(\d(\d(\d)))\1\2\3', '123123233')
print(ma.groups())
解析
- 初始分为三组:
组1: (\d(\d(\d))) 123123233
组2: (\d(\d(\d))) 123123233
组3: (\d(\d(\d))) 123123233
\1: 123123233
\2: 123123233
\3: 123123233
?:跳过分组
ma = re.match(r'(\d(?:\d(\d)))-\2', '647-7')
print(ma.groups())
解析
- 初始分为三组:
组1: (\d(\d(\d))) 647-7
组2: (\d(\d(\d))) 647-7
组3: (\d(\d(\d))) 647-7
?:在组2中,所以组2被跳过了,所以有两个分组
组1: (\d(\d(\d))) 647-7
组2: (\d(\d(\d))) 647-7
五.Python面向对象
定义类
class Shape :
def __init__(self, x=0, y=0) :#构造方法
self.x = x #实例变量
self.y = y
def move(self, deltaX, deltaY) :#实例方法
self.x += deltaX
self.y += deltaY
shape = Shape()#创建对象
shape.move(2,3)#调用实例方法
print(shape.x)
print(shape.y)
实例方法
- 使用对象才能够调用的方法
- 方法的第一个参数为self表示对象本身
abc ↩︎