1. 迭代器
1.1 自定义可迭代对象
只需要在对象中申明一个__iter()__方法即可,用来返回一个迭代器对象
1.2 自定义迭代器对象
只需要在对象中声明一个__next__()方法即可,用来获取下一个元素值
class FeiboIterator(object):
"""斐波那契数列迭代器"""
def __init__(self, n):
# 斐波那数列值的个数
self.n = n
# 记录当前遍历的下标
self.index = 0
# 斐波那数列前面的两个值
self.num1 = 0
self.num2 = 1
def __next__(self):
"""被next()函数调用来获取下一个数"""
if self.index < self.n:
num = self.num1
self.num1, self.num2 = self.num2, self.num1 + self.num2
self.index += 1
return num
else:
raise StopIteration
def __iter__(self):
"""迭代器的__iter__返回自身即可"""
return self
if __name__ == '__main__':
fb = FeiboIterator(20)
for num in fb:
print(num, end=' ')
1.3 python提供的内置方法
迭代器=iter(可迭代对象)
value=next(迭代器对象)
2. 生成器
- 它是一种特殊的迭代器,所以它也是可以迭代的。
2.1 创建生成器
2.1.1 通过列表推导式创建
data_list2 = (x*2 for x in range(10))
print(data_list2)
# 通过next获取下一个值
value = next(data_list2)
print("------->", value)
2.1.2 通过在函数中使用yield
# 使用yield 创建了一个生成器
def test1():
yield 10
# n 是一个生成器对象
n = test1()
print(n)
# <generator object test1 at 0x7ff7e4344f68>
value = next(n)
print("----->", value)
3. 闭包与装饰器
3.1闭包函数的定义
- 外层函数中定义了一个内层函数
- 内存函数引用了外层函数的临时变量
- 外层函数的返回值是内层函数的引用
def out(num):
def inner():
print(num)
return inner
3.2 装饰器的使用条件
- 存在闭包函数作为
装饰器生成器
。- 可以返回一个装饰函数
- 装饰函数和被装饰函数的关系是:如果被装饰函数有参数,则装饰函数也要有参数;如果被装饰函数有返回值,则装饰函数也要有返回值。
- 需要有被装饰函数
如何装饰不带参数的函数
def decorater(func):
def func_inner():
print("___开始装饰___")
func()
return func_inner
# @decorater 装饰了login() 函数,底层:login = decorater(login)
@decorater
def login():
print("被装饰的内容")
# 之后login就是被装饰后的函数,原先定义的函数被屏蔽
login()
如何装饰带有参数的函数
- 只能装饰参数是可变参数的函数
def function_out(func):
def function_in(*args, **kwargs):
print("-----开始验证----")
print("function_in:args=", args)
print("function_in:kwargs=", kwargs)
func(*args, **kwargs)
return function_in
# 登录函数
@function_out
def login(*args, **kwargs):
print("开始登录")
print("login:args=", args)
print("login:kwargs=", kwargs)
login(10, a=10)
如何装饰有返回值的函数
def function_out(func):
# func == login
def function_in(*args, **kwargs):
print("-----开始验证----")
print("function_in:args=", args)
print("function_in:kwargs=", kwargs)
return func(*args, **kwargs)
return function_in
# 登录函数
@function_out
# login = function_out(login)
def login(*args, **kwargs):
print("开始登录")
print("login:args=", args)
print("login:kwargs=", kwargs)
return 10
result = login(10, a=10)
print(result)
4. property装饰器
- @property装饰器会将方法转换为同名的只读属性
# ############### 定义 ###############
class Foo:
# 定义property属性
@property
def prop(self):
return "hello"
# ############### 调用 ###############
foo_obj = Foo()
foo_obj.prop # 调用property属性
新式类中扩展了属性装饰器的使用
# ############### 定义 ###############
class Goods:
"""python3中默认继承object类
以python2、3执行此程序的结果不同,因为只有在python3中才有@xxx.setter @xxx.deleter
"""
# get方法
@property
def price(self):
print('@property')
# set方法
@price.setter
def price(self, value):
print('@price.setter')
# delete方法
@price.deleter
def price(self):
print('@price.deleter')
# ############### 调用 ###############
obj = Goods()
obj.price # 自动执行 @property 修饰的 price 方法,并获取方法的返回值
obj.price = 123 # 自动执行 @price.setter 修饰的 price 方法,并将 123 赋值给方法的参数
del obj.price # 自动执行 @price.deleter 修饰的 price 方法
4.1 property作为类属性
通过property()函数可以在声明一个类属性的时候给其指定它的获取,设置,删除方式以及属性描述信息
class Foo(object):
def get_bar(self):
print("getter...")
return 'laowang'
def set_bar(self, value):
"""必须两个参数"""
print("setter...")
return 'set value' + value
def del_bar(self):
print("deleter...")
return 'laowang'
# 定义了一个类属性,同时指定了它的获取,设置,删除方式。以及该属性的表述信息
BAR = property(get_bar, set_bar, del_bar, "description...")
obj = Foo()
obj.BAR # 自动调用第一个参数中定义的方法:get_bar
obj.BAR = "alex" # 自动调用第二个参数中定义的方法:set_bar方法,并将“alex”当作参数传入
del obj.BAR # 自动调用第三个参数中定义的方法:del_bar方法
desc = Foo.BAR.__doc__ # 自动获取第四个参数中设置的值:description...
print(desc)
5. 类的魔法属性和方法
5.1 魔术属性
__doc__
获取描述信息(一般我们会在类和方法下写描述信息 “”" “”")类名.__doc__
对象名.方法名.__doc__
__module__
:获取对象所属的模块对象名.__module__
__class__
: 获取对象所属的类对象名.__class__
__dict__
:获取对象或类的信息对象名.__dict__
类名.__dict__
5.2 魔术方法
__init__()
:初始化方法, 构造类的实例对象时自动调用对象名=类名()
__del__()
:删除对象时会自动调用del 对象
__call__()
:使用对象名()会调用该方法对象名()
__str__()
:打印对象时会调用该方法print(obj)
__getitem__()
:利用字典的书写形式获取对象的属性对象['xx']
__setitem__()
:利用字典的书写形式设置对象属性对象['xx']=xxx
__delitem__()
:利用字典的书写形式删除对象属性del 对象['xx']
6. with管理上下文
6.1 上下文管理器
- 任何实现
__enter__()
和__exit__()
方法的对象都可以称作上下文管理器 - 上下文管理器可以与
with
关键字一起使用
方式1
class Sxw(object):
def __enter__(self):
'''进入'''
print("你好啊")
def __exit__(self, exc_type, exc_val, exc_tb):
'''退出'''
print("hao")
obj = Sxw()
with obj:
print("正在执行")
with Sxw() as obj:
print("正在执行")
`方式二
`
from contextlib import contextmanager
@contextmanager
def myopen(file_name, file_model):
print("进入上文")
# 1.上文 打开文件
file = open(file_name, file_model)
# 2.返回资源
yield file
print("进入下文")
# 3. 下文 关闭资源
file.close()
with myopen("hello.txt", "r") as file:
file_data = file.read()
print(file_data)