一、property属性
1.作用:把方法的调用变成属性调用
class Person():
def __init__(self):
self.__age = 0
@property
def age(self):
return self.__age
@age.setter
def age(self,age):
self.__age = age
p = Person()
p.age = 10
print(p.age)
2.类属性方式
class Person():
def __init__(self):
self.__age = 0
def get_age(self):
print('这里获取了age')
return self.__age
def set_age(self,age):
print('这里设置了age')
self.__age = age
# 属性中第一个是get方法 第二个是set方法
age = property(get_age, set_age)
p = Person()
p.age = 10
print(p.age)
二、with和上下文管理器
1. 使用方式
with open(文件名,模式) as f:
文件读写
2. 作用
文件打开后出现异常没有关闭,或数据库没有关闭,会导致资源浪费,内存泄漏
3. 上下文管理器
- 只要重写了__enter__和__exit__方法,就是上下文管理器;
- as之后的变量是上下文管理器__enter__返回的对象!
- 不管有没有出现异常,下文__exit__都会在with语句执行后自动执行
class File():
def __init__(self, path, model):
self.path = path
self.model = model
def __enter__(self):
print('--这里是上文--')
self.file = open(self.path, self.model)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
print('--这里是下文--')
self.file.close()
with File('./1.txt', 'w') as f:
f.write('aaaa')
1/0
print('--写数据!!!---')
print('程序执行结束')
三. 生成器
1. 生成器推导式
通过普通方式创建容器,容器内存就是所有元素内存 生成器可以不必创建完整的list,从而节省大量的空间
d = (ele for ele in range(100))
# 1. 使用next迭代
res1 = next(d)
print(res1)
res2 = next(d)
print(res2)
# 2. 使用for循环迭代
for ele in d:
print(ele)
2. yield关键字
yield会保存函数执行状态,并返回当前生成数值
def generater(num):
for i in range(num):
print('---start---')
yield i
print('---end---')
g = generater(5)
# 1. 使用next迭代
next(g)
# 2. 使用for循环迭代
for ele in g:
print(ele)
四、浅拷贝和深拷贝
拷贝仅限于可变类型(列表、字典、集合)!!!!
对于不可变类型,都是直接引用(与赋值操作相同),不开辟新空间
如果是不可变类型中嵌套可变类型,一律当作可变类型处理(例如:(1,2,[2,3,4]))
1.浅拷贝
浅拷贝:只拷贝第一层数据
列表的切片其实是浅拷贝(例如: list[:]是对list列表的浅拷贝)
# 浅拷贝:只拷贝第一层数据
import copy
a = [1,2]
b = [4,5,6]
c = [a,b]
d = copy.copy(c)
print(id(c))
print(id(d))
print(id(c[0]))
print(id(d[0]))
2. 深拷贝
可变类型嵌套了可变类型,对每一层可变对象都会拷贝
# 深拷贝:每一层都拷贝
import copy
a = [1,2]
b = [4,5,6]
c = [a,b]
d = copy.deepcopy(c)
print(id(c))
print(id(d))
print(id(c[0]))
print(id(d[0]))
四、正则表达式
1. 定义
对字符串的匹配规则
2. 单个字符匹配规则
import re
# result = re.match('我今年\d岁, 名字叫\w', '我今年7岁, 名字叫啦')
result = re.match(r'我今年[0-9]岁, 名字叫\w', '我今年7岁, 名字叫啦')
if result:
print(result.group())
else:
print('没有匹配!')
注意:
- 匹配规则前面加上r,表示原生字符串,告诉解释器不要用使用转义字符
- 补充:\b 单次边界 \B 非单词边界
3. 多个字符匹配规则
import re
result = re.match(r'[a-zA-Z][a-zA-Z0-9]{2,9}@qq\.com', 'aafd123123@qq.com')
if result:
print(result.group())
else:
print('没有匹配!')
4. 匹配开头和结尾
5. 匹配分组
6. 补充
-
如何返回第一次匹配字符串的下标
import re stra = 'bread is good good' p = re.compile('good') result1 = p.search(stra).span() # 返回值是元组 print(result1)
-
使用正则提取出字符串中的单词
import re s="i love you not because of who 234 you are, 234 but 3234ser because of who i am when i am with you" content=re.findall(r"\b[a-zA-Z]+\b",s) print(content)
-
使用正则表达式匹配合法的邮件地址:
import re s="xiasd@163.com, sdlfkj@.com sdflkj@180.com solodfdsf@123.com sdlfjxiaori@139.com saldkfj.com oisdfo@.sodf.com.com" content=re.findall(r"\w+@\w+.com",s) print(content)
-
提取每行中完整的年月日和时间字段
s="se234 1987-02-09 07:30:00 1987-02-10 07:25:00" content= re.findall(r"\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}",s ,re.M) print(s) print(content)