python进阶语法
一.正则表达式与json
-
正则表达式
-
正则表达式是一个特殊的字符序列,用于判断一个字符串是否与我们所设定的字符序列匹配
-
可用于快速检索文本,替换文本
-
元字符与普通字符
a = 'C0C++4Java5C#6Python7Javascript'
提取字符串a中的所有数字
import re a = 'C0C++4Java5C#6Python7Javascript' r = re.findall('\d', a) print(r) # 输出:['0', '4', '5', '6', '7']
此处的’\d’就被称为元字符
-
a = ‘abc, acc, adc, aec, afc, agc, ahc’,找出正中间字母为c或者f的子串
import re a = 'abc, acc, adc, aec, afc, agc, ahc' #出现在[]中的多个字符,它们之间是或的关系 r = re.findall('a[cf]c', a) #匹配中间字母既不是c,也不是f的字符串 r1 = re.findall('a[^cf]c', a) #匹配中间字母是c到f中的一个的字符串 r2 = re.findall('a[c-f]c', a) print(r) # 输出:['acc', 'afc'] print(r1) # 输出:['abc', 'adc', 'aec', 'agc', 'ahc'] print(r2) # 输出:['acc', 'adc', 'aec', 'afc']
-
字符集:
'\d'或者'[0-9]':匹配单个数字字符 '\D'或者'[^0-9]':匹配单个非数字字符 '\w':匹配单个单词(数字、字母或下划线)字符 '\W':匹配单个非单词字符 '\s':匹配空白字符 '\S':匹配非空白字符 '.':匹配除换行符之外的所有字符
-
数量词
'[a-z]{3}':匹配3个a到z的字母 '[a-z]{3-6}':匹配3到6个a到z的字母
import re a = 'C|C++|Java|C#|Python|Javascript' r = re.findall('[a-zA-z#+]{1,10}', a) print(r) # 输出:['C', 'C++', 'Java', 'C#', 'Python', 'Javascript']
-
贪婪匹配:正则表达式一般趋向于最大长度匹配,也就是所谓的贪婪匹配
-
非贪婪匹配:就是匹配到结果就好,就少的匹配字符
import re a = 'C|C++|Java|C#|Python|Javascript' r = re.findall('[a-zA-z#+]{1,10}', a) print(r) # 输出:['C', 'C++', 'Java', 'C#', 'Python', 'Javascript']
-
python默认是以贪婪的模式去匹配的,若要以非贪婪的模式去匹配,则需要在数量词后面加一个’?’
'[a-z]{3-6}?':非贪婪模式匹配3到6个a到z的字母
-
匹配0次、1次、无限多次
'*':匹配'*'前面的字符0次或者无限多次 '+':匹配'+'前面的字符1次或者无限多次 '?':匹配'?'前面的字符0次或者1次
import re a = 'pytho0python1pythonn2' r = re.findall('python*', a) r1 = re.findall('python+', a) r2 = re.findall('python?', a) print(r) # 输出: ['pytho', 'python', 'pythonn'] print(r1) # 输出: ['python', 'pythonn'] print(r2) # 输出: ['pytho', 'python', 'python']
-
边界匹配符:使用’^‘符号开头,’$‘符号结尾,’^‘符号表示以什么什么开头,’$'符号表示以什么什么结尾
import re a = '12345' b = '123456' c = '1234567' d = '12345678' e = '123456789' r1 = re.findall('^\d{6,8}$', a) r2 = re.findall('^\d{6,8}$', b) r3 = re.findall('^\d{6,8}$', c) r4 = re.findall('^\d{6,8}$', d) r5 = re.findall('^\d{6,8}$', e) print(r1) # 输出:[] print(r2) # 输出:['123456'] print(r3) # 输出:['1234567'] print(r4) # 输出:['12345678'] print(r5) # 输出:[]
-
组:一个’()'对应一组
a = 'PythonPythonPythonPythonPythonPythonPython' re.findall('(Python{3})', a) #匹配a中出现三个'Python的字符串'
-
匹配模式参数:findall方法的第三个参数,取值如下:
're.I':忽略大小写 're.S':'.'将匹配所有的字符
-
正则替换:‘re.sub(…)’
import re a = 'PythonC#JavaPhp' # 第一个参数:正则表达式 # 第二个参数:用于替换正则表达式匹配到的字符串 # 第三个参数:替换几次,0表示替换全部 # 第四个参数:匹配模式 r = re.sub('C#', 'GO', a, 0) print(r) # 输出:'PythonGOJavaPhp'
-
将函数作为正则替换的替换参数
``` 当使用函数作为正则替换的替换参数(第二个参数)时: 1.当正则表达式匹配到一个结果之后, 会把匹配到的结果封装成一个Match对象, 并把该对象作为函数的参数传递进去, 最终把函数调用的返回结果作为正则替换的替换字符串 2.可以通过Match对象的group方法,获取到正则表达式的匹配结果 ``` import re def convert(value): print(type(value)) # 输出:<class 're.Match'> print(value) # 输出:<re.Match object; span=(6, 8), match='C#'> print(value.group()) # 输出:'C#' def convert1(value): match = value.group return '!!!' + match + '!!!' a = 'PythonC#JavaPhp' r = re.sub('C#', convert, a, 0) r1 = re.sub('C#', convert1, a, 0) print(r) # 输出:'PythonJavaPhp' print(r1) # 输出:'Python!!!C#!!!JavaPhp'
-
-
JSON
-
什么是JSON:JSON是(JavaScript Object Notation)的简写,即JavaScript对象标记;是一种轻量级的数据交换格式
-
JSON字符串:JSON字符串是符合JSON格式的字符串,是JSON的表现形式
-
JSON的反序列化:将一个JSON的字符串转换为Python中的数据类型
import json a = '{"name":"Tom", "age":20, "flag": false}' b = '[{"name":"Tom", "age": 20, "flag": false},{"name":"Tom", "age": 20, "flag": false}]' r = json.loads(a) # 输出:{'name': 'Tom', 'age': 20, 'flag': False} r1 = json.loads(type(b)) # 输出:<class 'list'> print(r)
-
JSON的序列化: 将Python中的数据类型转换为JSON字符串
import json a = [{'name':'Tom', 'age':20, 'flag': False}, {'name':'Tom', 'age':20, 'flag': False}] r = json.dumps(a) print(r) # 输出: [{"name": "Tom", "age": 20, "flag": false}, {"name": "Tom", "age": 20, "flag": false}]
-
JSON的数据类型与Python的数据类型的对应关系
JSON python object dict array list string str number int number float true True false False null None
-
二.枚举类型
-
枚举是一个类
-
定义一个枚举类
from enum import Enum class DIRECT(Enum): LEFT = 1 RIGHT = 2 UP = 3 DOWN = 4
-
枚举类型、枚举名称和枚举值
from enum import Enum class DIRECT(Enum): LEFT = 1 RIGHT = 2 UP = 3 DOWN = 4 print(type(DIRECT.LEFT)) # 输出:<enum 'DIRECT'> print(type(DIRECT.LEFT.name)) # 输出:<class 'str'> print(type(DIRECT.LEFT.value)) # 输出:<class 'int'> print(type(DIRECT['LEFT'])) # 输出:<enum 'DIRECT'>
-
遍历枚举类型
from enum import Enum class DIRECT(Enum): LEFT = 1 RIGHT = 2 UP = 3 DOWN = 4 for d in DIRECT: print(d) # 输出: ``` DIRECT.LEFT DIRECT.RIGHT DIRECT.UP DIRECT.DOWN ```
-
枚举的比较运算
from enum import Enum class DIRECT(Enum): LEFT = 1 RIGHT = 2 UP = 3 DOWN = 4 class DIRECT1(Enum): LEFT = 1 RIGHT = 2 UP = 3 DOWN = 4 print(DIRECT.LEFT == DIRECT.RIGHT) # 输出:False print(DIRECT.LEFT == DIRECT.LEFT) # 输出:True print(DIRECT.LEFT == 1) # 输出:False print(DIRECT.LEFT is DIRECT.LEFT) # 输出:True print(DIRECT.LEFT == DIRECT1.LEFT) # 输出:False print(DIRECT.LEFT > DIRECT.RIGHT) # 报错:枚举类型不支持大小比较
-
注意事项
-
如果枚举类中有两个枚举的值相同,枚举名称不同,则其中一个被称为另一个的别名
from enum import Enum class DIRECT(Enum): LEFT = 1 LEFT_ALIAS = 1 UP = 3 DOWN = 4 for d in DIRECT: print(d) # 输出: ``` DIRECT.LEFT DIRECT.UP DIRECT.DOWN ``` for d in DIRECT.__members__: print(d) # 输出: ``` LEFT LEFT_ALIAS UP DOWN ```
-
-
将枚举值转换为枚举类型
from enum import Enum class DIRECT(Enum): LEFT = 1 RIGHT = 2 UP = 3 DOWN = 4 print(DIRECT(1)) # 输出:DIRECT.LEFT
三.闭包
-
函数内部可以定义函数
-
函数可以做为返回结果,被另外一个函数返回
-
函数可以赋给一个变量
a = 10 def f1(x): return a * x ** 2 print(f1(2)) # 输出:40
def curve_pre(): a = 25 def curve(x): return a * x ** 2 return curve a = 10 f = curve_pre() print(f.__closure__[0].cell_contents) # 输出:25 print(f(2)) # 输出:100
-
闭包:在定义一个函数时,有另外一个函数被当成对象返回,并夹带了外部的环境变量,被返回的函数内部一定要引用环境变量,就形成了一个闭包,即闭包 = 环境变量 + 函数
-
实例
start = 0 def factory(pos): def go(step): nonlocal pos pos += step return pos return go f = factory(start) print(f(3)) # 输出:3 print(f(5)) # 输出:8 print(f(8)) # 输出:16
四.函数式编程
-
匿名函数:python中定义匿名函数需要借助lambda表达式
def add(x, y): return x + y # 匿名函数写法如下: lambda x, y: x + y
-
三元表达式
#条件为真时返回的结果 if 条件判断 else 条件为假时返回的结果 x = 0 y = 4 result = x if x > y else y print(result) # 输出:4
-
map
# map对接受到的序列中的每一个元素都会去执行func函数 map(func, list)
list_x = [1,2,3,4,5,6,7,8] def square(x): return x ** 2 result = map(square, list_x) print(result) # 输出:<map object at 0x10b46bb50> list_y = list(result) print(list_y) # 输出:[1, 4, 9, 16, 25, 36, 49, 64]
-
map与lambda
list_x = [1,2,3,4,5,6,7,8] list_y = [1,2,3,4,5,6] # 传入列表的个数必须和lambda表达式的参数个数一样 # map最后返回结果的个数取决于传入序列较小长度的那个 result = map(lambda x, y: x ** 2 + y, list_x, list_y) print(result) # 输出:<map object at 0x10b46bb50> list_z = list(result) print(list_z) # 输出: [2, 6, 12, 20, 30, 42]
-
reduce
``` 在遍历序列list的过程中,首先把 前两个元素传给 函数参数, 函数加工后,然后把得到的结果和第三个元素作为两个参数传给 函数参数, 函数加工后得到的结果又和第四个元素作为两个参 数传给函数参数,依次类推。 如果传入了 initial 值, 那 么首先传的就不是 序列list 的第一个和第二个元素,而是 initial值 和 第一个元素。经过这样的累计计算之后合并序 列到一个单一返回值 ``` reduce(func, list, initial)
from functools import reduce list_x = [1, 2, 3, 4, 5, 6, 7, 8] def add(x, y): return x + y # result = (((((((1 + 2) + 3) + 4) + 5) + 6) + 7) + 8) result = reduce(add, list_x) print(result) # 输出:36
-
reduce与lambda
from functools import reduce list_x = [1, 2, 3, 4, 5, 6, 7, 8] # result = (((((((1 + 2) + 3) + 4) + 5) + 6) + 7) + 8) result = reduce(lambda x, y: x + y, list_x) print(result) # 输出:36
-
filter
# 序列list的每个元素作为参数传递给函数进行判断,然后返回 True 或 False,最后将返回 True 的元素放到新列表中 filter(func, list)
list_x = [1, 2, 3, 4, 5, 6, 7, 8] def is_odd(x): return x % 2 == 1 result = filter(is_odd, list_x) print(list(result)) # 输出:[1, 3, 5, 7]
-
filter与lambda
list_x = [1, 2, 3, 4, 5, 6, 7, 8] result = filter(lambda x: x % 2 == 1, list_x) print(list(result)) # 输出:[1, 3, 5, 7]
五.装饰器
- 自定义一个装饰器
-
定义一个装饰器的外部函数
def decorator(func): pass
-
定义装饰器的外部函数中定义一个内部函数
def decorator(func): def wrapper(): pass
-
在装饰的外部函数中返回装饰器的内部函数
def decorator(func): def wrapper(): pass return wrapper
-
编写装饰器的内部函数的具体实现
def decorator(func): def wrapper(): print("do something") func() return wrapper
-
使用自定义的装饰器
def decorator(func): def wrapper(): print("do something") func() return wrapper @decorator def func1(): print("this is func1") func1() # 输出: ``` do something this is func1 ```
-
可以看出装饰器的作用是:可以在不改变被装饰函数内部实现的情况下,为被装饰的函数添加特定的业务逻辑代码
-
被装饰函数带有一个必须参数的情况
def decorator(func): def wrapper(): print("do something") func() return wrapper @decorator def func1(a): print("this is func1" + ", a = " + str(a)) func1(1) # TypeError: wrapper() takes 0 positional arguments but 1 was given
-
可以看到,在上面的代码中,被装饰的函数func1并不能识别传入的必须参数a,因此需要在装饰器的内部函数的参数列表中增加一个必须参数,并在实际调用被装饰函数的时候传入该参数
def decorator(func): def wrapper(a): print("do something") func(a) return wrapper @decorator def func1(a): print("this is func1" + ", a = " + str(a)) func1(1) # 输出: ``` do something this is func1, a = 1 ```
-
被装饰函数带有多个必须参数或者可变参数列表的情况
def decorator(func): def wrapper(*args): print("do something") func(*args) return wrapper @decorator def func1(a, b): print("this is func1" + ", a = " + str(a) + ", b = " + str(b)) @decorator def func2(*a): print("this is func2" + ", a = " + str(a)) func1(1, 2) # 输出: ``` do something this is func1, a = 1, b = 2 ``` func2(1,2,3) # 输出: ``` do something this is func2, a = (1, 2, 3) ```
-
被装饰函数带有多个必须参数、关键字可变参数列表或者可变参数列表、关键字可变参数列表的情况
def decorator(func): def wrapper(*args, **key_words): print("do something") func(*args, **key_words) return wrapper @decorator def func1(a, b, **key_words): print("this is func1" + ", a = " + str(a) + ", b = " + str(b)) print("key_words = " + str(key_words)) @decorator def func2(*a, **key_words): print("this is func2" + ", a = " + str(a)) print("key_words = " + str(key_words)) func1(1, 2, c = 1, d = 2, d = "python") # 输出: ``` do something this is func1, a = 1, b = 2 key_words = {'c': 1, 'd': 2, 'e': 'python'} ``` func2(1, 2, 3, c = 1, d = 2, d = "python") # 输出: ``` do something this is func2, a = (1, 2, 3) key_words = {'c': 1, 'd': 2, 'e': 'python'} ```
-