Python3入门(二)
面向对象
类的创建与实例化
-
代码
1
2
3
4
5
6
7
8class Student(): # 创建一个类
name = ''
age = 0
def print_file(self): # 类中的函数
pass
student = Student() # 类的实例化 -
方法 与 函数 有何区别?
方法:设计层面的说法
函数:程序运行、过程的一种称谓
构造函数
-
无参构造函数
1
2def __init__(self):
pass -
有参构造函数
1
2
3def __init__(self,name,age):
self.name = name;
self.age = age;
类变量与实例变量
-
举例
1
2
3
4
5
6
7
8
9class Student():
sum = 0; # 类变量的赋值,Student.sum即可访问
name = ''
age = 0
def __init__(self,name,age):
self.name = name # 实例变量的赋值
self.age = age # 类内访问类变量需要加self,在类外访问为 对象名.变量名
print(self.__class__.sum) # 第二种调用方法 -
检测实例变量
1
2# className为类名
className.__dict__
类方法
-
定义方式
1
2
3
4
5# 若添加了这个装饰器,与self还是cls无关(可替换)
def plus_sum(cls):
cls.sum += 1
print(cls.sum)
私有与公开方法、成员
-
若要表示该方法为私有,在方法名前加 __ 即可,例如
1
2def __marking(self, score):
self.score = score; -
若要表示该方法为公开,默认即可,或者前后均加上 __
-
可通过特殊方法在类外强制访问私有成员(不建议)
1
2#例如
print(student2._Student__score)
封装、继承、多态——三大特性
-
继承(继承父类变量与方法)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# 继承举例,父类People,子类Student
class People():
sum = 0
def __init__(self, name, age):
self.name = name
self.age = age
class Student(People):
def __init__(self,school,name,age):
self.school = school
People.__init__(self,name,age)
# 注意调用父类构造函数要传入self
# super(Student, self).__init__(name, age)
# super关键字用来调用父类成员和方法 -
若上面使用super的方式,代码运行后会出现错误:
1
TypeError: super() argument 1 must be type, not classobj
-
原因:注意,super方法只能用于新类,即必须有继承的类,下面是经典类的举例
1
2class People():
.... -
若要将上述类变为新类(加上继承关系),可改为:
1
2class People(object):
.....
正则表达式
什么是正则表达式
-
正则表达式(regular expression)描述了一种字符串匹配的模式(pattern) , 用以检查字符串
-
正则表达式举例
1
2
3
4
5
6import re
a = 'C2C++3Java4C#5Python6Javascript'
print(re.findall('\d',a)) #'\d'代表所有数字字符
#结果:
['2', '3', '4', '5', '6']
普通字符与元字符
-
元字符代表抽象的字符串,正则表达式的学习与元字符息息相关
-
例如:‘ Python’ 为普通字符,‘\d’为元字符
-
查看更多元字符 点击这里
字符集
-
抽象出要查找的字符(串)的特性
-
使用中括号 [] ,表示’或’关系
-
例如
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import re
s = "abc, acc, adc, aec, afc, ahc"
r = re.findall('a[cf]c',s)
print(r)
#结果:
['acc', 'afc']
import re
s = "abc, acc, adc, aec, afc, ahc"
r = re.findall('a[^cf]c',s)
print(r)
#结果:
['abc', 'adc', 'aec', 'ahc'] -
概括字符集:可用字符集来表达的元字符
1
2
3#例如
'\d' 等同于 '[0-9]'
'\w' 等同于 '[a-zA-Z0-9_]' #单词字符 -
正则表达式常用的字符集:点击这里
数量词
-
使用{ }指定前一个字符集或字符出现的次数
1
2
3
4
5
6import re
a = 'java 4 C# 5 python 6 & php'
print(re.findall('[a-z]{3,6}',a))
#结果
['java', 'python', 'php'] -
贪婪 与 非贪婪 的匹配机制
-
默认情况下,Python使用贪婪机制,即尽可能满足某个条件
-
若使用非贪婪在数量词后加 ? 即可
1
2
3
4
5
6import re
a = 'java 4 C# 5 python 6 & php'
print(re.findall('[a-z]{3,6}?',a))
#结果
['jav', 'pyt', 'hon', 'php']
-
-
匹配0次、1次、无限多次
-
使用 * 匹配前一个字符(集)0次或无限多次
1
2
3
4
5
6import re
a = 'pytho0python1pythonn2'
print(re.findall('python*',a))
#结果
['pytho', 'python', 'pythonn'] -
使用 + 匹配前一个字符(集)1次或无限多次
1
['python', 'pythonn']
-
使用 ? 匹配前一个字符(集)0次或1次
1
['pytho', 'python', 'python']
-
边界匹配
-
用以匹配整个字符串
-
在表达式前加 ^ ,在表达式后加 $,例如:
1
2
3
4
5
6
7import re
qq = "798998087"
re.findall('^\d{4,8}$',qq)
print(r)
#结果,^代表从头匹配,$代表从末尾匹配
[]
组
-
使用圆括号 () ,表示’且’的关系
1
re.findall('(Python)',a)
匹配模式参数
-
re.I模式举例:忽略正则表达式字母大小写
1
2
3
4
5
6import re
a = 'PythonC#JavaPHP'
print(re.findall('c#',a,re.I))
#结果
['C#'] -
若要用多种模式,将不同模式用 | 连接即可
re.sub用以正则替换
-
代码举例
1
2
3
4
5
6
7
8
9
10#coding=utf-8
import re
language = 'PythonC#PHPC#JAVA'
#参数1:正则表达式,参数2:要替换成的字符串(也可以是函数),参数3:被搜索的字符串,参数4:替换模式 0为全替换,n为替换n个
r = re.sub('C#','GO',language,1)
print(r)
#结果
'PythonGOPHPC#JAVA' -
通过函数判断并替换字符
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import re
s = 'A8C3721D86'
def convert(value):
matched = value.group()
if int(matched) >=6 :
return '9'
else:
return '0'
r = re.sub('\d',convert,s)
print(r)
#结果
A9C0900D99
re.match与re.search : 匹配成功一次则返回
- re.match从字符串首字母开始匹配,若头部不满足条件则返回None
- re.search搜索整个字符串
- 可使用span()函数获得匹配成功的字符位置
获取字符串中间内容
-
代码参考
1
2
3
4
5
6
7
8
9
10
11
12import re
s = "life is short , i use python"
r1 = re.search('life(.*)python', s)
#r2 = re.findall('life(.*)python',s) 使用括号表达正则表达式分组
print(r1.group(1))
#print(r2)
#结果
is short , i use -
总结:对于search函数来说,使用group(n)来访问正则表达式的分组,若n=0,返回全部分组匹配结果,否则返回第n个分组匹配内容
JSON
什么是JSON
-
JavaScript Object Notation
-
一种轻量级的数据 交换格式
-
字符串 是JSON的表现形式
-
什么是JSON字符串?
符合JSON格式的字符串叫做JSON字符串,如:
1
{"name":"ba-nana"}
Python接收JSON字符串 (反序列化)
-
代码参考
1
2
3
4
5
6
7
8
9
10
11
12
13
14import json
#注意单双引号
json_str='{"name":"banana", "age":19}' #一个JSON object
student = json.loads(json_str)
print(type(student))
print(student)
print(student['age']) #访问字典内容
#结果
<type 'dict'>
{'age': 19, 'name': 'banana'}
19 -
若接收的JSON字符串为数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import json
#多个JSON object组成数组
json_str='[{"name":"banana", "age":19},{"name":"salaka", "age":18}]'
student = json.loads(json_str)
print(type(student))
print(student)
print(student[0]["name"])
#结果
<type 'list'>
[{'age': 19, 'name': 'banana'}, {'age': 18, 'name': 'salaka'}]
banana -
JSON -> Python常见的数据转换格式
JSON Python object dict array list string str number int number float true True false False null None
序列化 Python -> JSON
-
代码参考
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import json
student = [
{'name':'banana','age':19,'flag':False},
{'name':'salaka','age':18}
]
print(type(student))
#序列化
json_str = json.dumps(student)
print(json_str)
#结果
<type 'list'>
[{"age": 19, "flag": false, "name": "banana"}, {"age": 18, "name": "salaka"}]
Python的高级语法与用法
枚举
-
枚举的定义
1
2
3
4
5
6
7
8from enum import Enum
#from enum import IntEnum 与上面不同,枚举类型只能为Int
class VIP(Enum):
YELLOW = 1
BLACK = 2
GREEN = 3
RED = '4' -
访问枚举名与值
1
2
3#访问枚举成员GREEN为示例
VIP.GREEN.name #访问枚举名
VIP.GREEN.value #访问枚举值 -
枚举的比较
- 可以做身份(is)和等值(==)比较
- 不可以做大小比较
-
枚举的遍历
1
2
3
4
5
6
7
8#获取枚举值与名字
for x in VIP:
print(x.value)
#print(x.name)
#获取所有枚举
for x in VIP.__members__.items():
print(x) -
枚举类型转换
1
2
3
4
5
6#数字 -> 枚举类型
a = 1
r = VIP(a)
print(r)
#结果
VIP.YELLOW -
枚举唯一值装饰器
1
2
3
4from enum import Enum,unique
class(Enum)
pass
闭包
-
函数+环境变量 -> 闭包
1
2
3
4
5
6
7
8
9
10
11
12def curve_pre():
a = 25 #环境变量
def curve(x):
return a*x*x
return curve
a = 10 #外部变量
f = curve_pre()
print(f(2))
#结果(形成闭包后不受外部变量改变影响)
100 -
查看闭包参数
1
2
3
4
5
6
7f = curve_pre()
print(f.__closure__) #若没有闭包,会返回None
print(f.__closure__[0].cell_contents)
#结果
(<cell at 0x1060d6670: int object at 0x7fb40bd05388>,)
25 -
解决一个实例问题——累加
-
非闭包方法
1
2
3
4
5
6
7
8
9
10
11origin = 0
def go(step):
global origin #若没全局变量声明,下面会报错,origin会被默认为局部变量
new_pos = origin + step
origin = new_pos
return new_pos
print(go(2)) #2
print(go(3)) #5
print(go(4)) #9 -
闭包方法:不修改全局变量,保存现场 的功能
1
2
3
4
5
6
7
8
9
10
11
12
13
14origin = 0
def factory(pos):
def go(step):
nonlocal pos
new_pos = pos + step
pos = step
return new_pos
return go
tourist = factory(origin)
print(tourist(2)) #2
print(tourist(3)) #5
-
函数式编程
匿名函数
-
声明
1
lambda parameter_list: expression
-
示例
1
2
3
4
5
6def add(x, y):
return x+y
add(1,2)
f = lambda x,y: x+y #匿名函数的声明
f(1,2) #匿名函数的调用
三元表达式
-
相对于其他编程语言(Java为例)
1
2//Java中
x > y ? x : y -
Python中的三元表达式略有不同
1
2#Python中
x if x > y else y
map
-
用于多次执行函数 (映射),分别传入方法与列表(可多个列表)
1
2
3
4
5
6
7
8
9
10
11
12
13list_x = [1,2,3,4,5,6,7,8]
def square(x):
return x*x
r = map(square, list_x)
# for x in list_x:
# 等同于下列for循环
# square(x)
print(r)
#结果
[1, 4, 9, 16, 25, 36, 49, 64] -
当lambda和map结合
1
2
3
4
5list_x = [1,2,3,4,5,6,7,8]
r = map(lambda x: x*x, list_x)
print(r)
#结果与上个代码块相同
reduce
-
元素递减运算(归约)
1
2
3
4
5
6#例子
list_x = [1,2,3,4,5,6,7,8]
r = reduce(lambda x,y:x+y, list_x, 15)
#上述运算相当于((((15+(1+2))+3)+4)+...
filter
-
过滤函数
1
2
3
4
5
6list_x=[1,0,1,0,1,0]
r = filter(lambda x: True if x==1 else False, list_x)
print(r)
#结果
[1, 1, 1]
装饰器
-
装饰器可以增强代码复用性,通常用于业务需求更改
-
装饰器的定义示例
1
2
3
4
5
6import time
def decorator(func): #形成了闭包
def wrapper():
print(time.time())
func()
return wrapper -
装饰器的调用
1
2
3
4
5
6
7
8
9
def f1():
print("this is a function")
f1()
#结果
1581134973.93
this is a function -
为了通用性,要将装饰器传入参数改为 动态的,即:
1
2
3
4
5
6import time
def decorator(func):
def wrapper(*args): #动态参数,单*号+任意名
print(time.time())
func(*args)
return wrapper -
双*号传入混合参数(参数名任意)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20import time
def decorator(func):
def wrapper(*args,**kw): #此处传入**kw
print(time.time())
func(*args,**kw)
return wrapper
def f2(func_name1, func_name2, **kw):
print('1:'+func_name1)
print('2:'+func_name2)
print(kw)
f2('lala','hh',a=2,b=3,c='123')
#结果
1581136034.04
1:lala
2:hh
{'a': 2, 'c': '123', 'b': 3} #此处为kw代表的值