property
方式一:
class Person(object):
def __init__(self):
self.__age = 0
# 装饰器方式的property, 把age方法当做属性使用, 表示当获取属性时会执行下面修饰的方法
@property
def age(self):
return self.__age
# 把age方法当做属性使用, 表示当设置属性时会执行下面修饰的方法
@age.setter
def age(self, new_age):
if new_age >= 150:
print("成精了")
else:
self.__age = new_age
if __name__ == '__main__':
# 创建person
p = Person()
print(p.age)
p.age = 100
print(p.age)
p.age = 1000
方式二
class Person(object):
def __init__(self):
self.__age = 0
def get_age(self):
"""当获取age属性的时候会执行该方法"""
return self.__age
def set_age(self, new_age):
"""当设置age属性的时候会执行该方法"""
if new_age >= 150:
print("成精了")
else:
self.__age = new_age
# 类属性方式的property属性
age = property(get_age, set_age)
if __name__ == '__main__':
# 创建person
p = Person()
print(p.age)
p.age = 100
print(p.age)
p.age = 1000
with语句的基本使用
if __name__ == '__main__':
try:
# 1、以读的方式打开文件
f = open("1.txt", "r")
# 2、读取文件内容
f.write("xxxxx")
except IOError as e:
print("文件操作出错", e)
finally:
# 3、关闭文件
f.close()
# 1、以写的方式打开文件
with open("1.txt", "w") as f:
# 2、读取文件内容
f.write("hello world")
上下文管理器
# 一个类只要实现了__enter__()和__exit__()这个两个方法,通过该类创建的对象我们就称之为上下文管理器。
class File(object):
# 初始化方法
def __init__(self, file_name, file_model):
# 定义变量保存文件名和打开模式
self.file_name = file_name
self.file_model = file_model
# 上文方法
def __enter__(self):
print("进入上文方法")
# 返回文件资源
self.file = open(self.file_name, self.file_model)
return self.file
# 下文方法
def __exit__(self, exc_type, exc_val, exc_tb):
print("进入下文方法")
self.file.close()
if __name__ == '__main__':
# 使用with管理文件
with File("1.txt", "r") as file:
file_data = file.read()
print(file_data)
#Python 还提供了一个 @contextmanager 的装饰器,
# 更进一步简化了上下文管理器的实现方式。
# 通过 yield 将函数分割成两部分,yield 上面的语句在 __enter__ 方法中执行,
# yield 下面的语句在 __exit__ 方法中执行,紧跟在 yield 后面的参数是函数的返回值。
# 导入装饰器
from contextlib import contextmanager
# 装饰器装饰函数,让其称为一个上下文管理器对象
@contextmanager
def my_open(path, mode):
try:
# 打开文件
file = open(path, mode)
# yield之前的代码好比是上文方法
yield file
except Exception as e:
print(e)
finally:
print("over")
# yield下面的代码好比是下文方法
file.close()
if __name__ == '__main__':
# 使用with语句
with my_open('1.txt', 'w') as f:
f.write("hello , the simplest context manager")
生成器
# if __name__ == '__main__':
# # 创建生成器
# my_generator = (i * 2 for i in range(5))
# print(my_generator)
#
# # next获取生成器下一个值
# # value = next(my_generator)
# # print(value)
#
# # 遍历生成器
# for value in my_generator:
# print(value)
#----------------方式二---------------------
# def mygenerater(n):
# for i in range(n):
# print('生成...')
# yield i
#
#
# if __name__ == '__main__':
#
# g = mygenerater(2)
# # 获取生成器中下一个值
# # result = next(g)
# # print(result)
#
# # while True:
# # try:
# # result = next(g)
# # print(result)
# # except StopIteration as e:
# # break
#
# # # for遍历生成器, for 循环内部自动处理了停止迭代异常,使用起来更加方便
# for i in g:
# print(i)
# --------------生成器使用场景-----------
def fibonacci(num):
a = 0
b = 1
# 记录生成fibonacci数字的下标
current_index = 0
while current_index < num:
result = a
a, b = b, a + b
current_index += 1
# 代码执行到yield会暂停,然后把结果返回出去,下次启动生成器会在暂停的位置继续往下执行
yield result
if __name__ == '__main__':
fib = fibonacci(5)
# 遍历生成的数据
for value in fib:
print(value)
浅拷贝
import copy # 使用浅拷贝需要导入copy模块
# copy函数是浅拷贝,只对可变类型的第一层对象进行拷贝,对拷贝的对象开辟新的内存空间进行存储,不会拷贝对象内部的子对象
# 不可变类型有: 数字、字符串、元组
if __name__ == '__main__':
a1 = 123123
b1 = copy.copy(a1) # 使用copy模块里的copy()函数就是浅拷贝了
# 查看内存地址
print(id(a1))
print(id(b1))
print("-" * 10)
a2 = "abc"
b2 = copy.copy(a2)
# 查看内存地址
print(id(a2))
print(id(b2))
print("-" * 10)
a3 = (1, 2, ["hello", "world"])
b3 = copy.copy(a3)
# 查看内存地址
print(id(a3))
print(id(b3))
深拷贝
import copy # 使用深拷贝需要导入copy模块
# 不可变类型有: 数字、字符串、元组
if __name__ == '__main__':
a1 = 1
b1 = copy.deepcopy(a1) # 使用copy模块里的deepcopy()函数就是深拷贝了
# 查看内存地址
print(id(a1))
print(id(b1))
print("-" * 10)
a2 = "张三"
b2 = copy.deepcopy(a2)
# 查看内存地址
print(id(a2))
print(id(b2))
print("-" * 10)
a3 = (1, 2)
b3 = copy.deepcopy(a3)
# 查看内存地址
print(id(a3))
print(id(b3))
print("-" * 10)
# 注意: 元组里面要是有可变类型对象,发现对象有可变类型就会该对象到最后一个可变类型的每一层对象进行拷贝
a4 = (1, ["李四"])
b4 = copy.deepcopy(a4)
# 查看内存地址
print(id(a4))
print(id(b4))
# 元组里面的可变类型子对象也会进行拷贝
print(id(a4[1]))
print(id(b4[1]))
正则表达式
# 导入re模块
import re
# 使用match方法进行匹配操作
# result = re.match(正则表达式,要匹配的字符串)
# 匹配成功,返回匹配的字符串,匹配失败,返回none
match_obj = re.match('aa', 'aa')
if match_obj:
# 匹配成功
print('匹配成功')
else:
# 匹配失败
print('匹配失败')
# 匹配单个字符
# . 匹配任意1个字符(除了\n)
# [ ] 匹配[ ]中列举的字符
# \d 匹配数字,即0-9
# \D 匹配非数字,即不是数字
# \s 匹配空白,即 空格,tab键
# \S 匹配非空白
# \w 匹配非特殊字符,即a-z、A-Z、0-9、_、汉字
# \W 匹配特殊字符,即非字母、非数字、非汉字
# 匹配多个字符
# * 匹配前一个字符出现0次或者无限次,即可有可无
# + 匹配前一个字符出现1次或者无限次,即至少有1次
# ? 匹配前一个字符出现1次或者0次,即要么有1次,要么没有
# {m} 匹配前一个字符出现m次
# {m,n} 匹配前一个字符出现从m到n次
# 匹配开头和结尾
# ^ 匹配字符串开头
# $ 匹配字符串结尾
# [^指定字符]: 表示除了指定字符都匹配
# 匹配分组相关正则表达式
# | 匹配左右任意一个表达式
# (ab) 将括号中字符作为一个分组
# \num 引用分组num匹配到的字符串
# (?P<name>) 分组起别名
# (?P=name) 引用别名为name分组匹配到的字符串
import re
if __name__ == '__main__':
# 水果列表
fruit_list = ["apple", "banana", "orange", "pear"]
# 遍历数据
for value in fruit_list:
# | 匹配左右任意一个表达式
match_obj = re.match("apple|pear", value)
if match_obj:
print("%s是我想要的" % match_obj.group())
else:
print("%s不是我要的" % value)
match_obj = re.match("[a-zA-Z0-9_]{4,20}@(163|126|qq|sina|yahoo).com", "hello@163.com")
if match_obj:
print(match_obj.group())
# 获取分组数据
print(match_obj.group(1))
else:
print("匹配失败")
import re
match_obj = re.match("(qq):([1-9]\d{4,10})", "qq:10567")
if match_obj:
print(match_obj.group())
# 分组:默认是1一个分组,多个分组从左到右依次加1
print(match_obj.group(1))
# 提取第二个分组数据
print(match_obj.group(2))
else:
print("匹配失败")
match_obj = re.match("<[a-zA-Z1-6]+>.*</[a-zA-Z1-6]+>", "<html>hh</div>")
if match_obj:
print(match_obj.group())
else:
print("匹配失败")
match_obj = re.match("<([a-zA-Z1-6]+)>.*</\1>", "<html>hh</html>")
if match_obj:
print(match_obj.group())
else:
print("匹配失败")
match_obj = re.match("<([a-zA-Z1-6]+)><([a-zA-Z1-6]+)>.*</\2></\1>", "<html><h1>www.itcast.cn</h1></html>")
if match_obj:
print(match_obj.group())
else:
print("匹配失败")
match_obj = re.match("<(?P<name1>[a-zA-Z1-6]+)><(?P<name2>[a-zA-Z1-6]+)>.*</(?P=name2)></(?P=name1)>",
"<html><h1>www.itcast.cn</h1></html>")
if match_obj:
print(match_obj.group())
else:
print("匹配失败")