赞
踩
class User(object):
def __init__(self, name, info):
self.name = name
self.info = info
def __getattr__(self, item):
return self.info[item]
# def __getattribute__(self, item):
# return 'hhh'
# 如果写了这个方法,那么所有的属性调用都会返回hhh
ls = User("李四", {"gender": "male"})
print(ls.gender)
print(ls.name)
元类就是创建类的类可以用两种方法创建,第一种是type,第二种是通过classmate传入参数
type()一共要传入三个参数
def __init__(self, name):
self.name = name
print("i am __init__")
User = type("User", (), {"age":22 , "__init__":__init__})
obj = User("beiyue")
print(obj.name)
metaclass的英文直译过来就是元类,支持自己定义一个类,使得它是后面某一个类的元类。
class AddInfo(type):
def __new__(cls, name, bases, attr):
attr['info'] = 'add by metaclass'
return super().__new__(cls, name, bases, attr)
class Test(metaclass=AddInfo):
pass
可以用for循环遍历的对象都是可迭代对象。
str,list,tuple,dict,set等都是可迭代对象。
generator,包括生成器和带yield的生成器函数。
除了看内置是否含有 _ _ iter _ _ 方法来判断该对象是否是一个可迭代的对象之外,我们还可以使用 isinstance() 判断一个对象是否是 Iterable 对象
from collections import Iterable,Iterator
print(isinstance('abc',Iterable)) # True
print(isinstance([1,2,3,4],Iterable)) # True
print(isinstance(123,Iterable)) # False
from collections import Iterable,Tterator
li = [1,2,3,4]
print(isinstance(li,Iterable)) # true
print(isinstance(li,Iterable)) # false
lis = iter(li)
print(type(lis)) # <class 'list_iterator'>
d = {'name': 'beiyue', 'city': 'sh', 'skill': 'python'}
for i in d:
print(i)
for 循环过程中,可迭代对象 d 会先通过 iter() 生成一个迭代器 iter(d), 该迭代器具有一个 next 方法。在每次迭代过程中,这个 next 方法会被调用,从而返回 d 中的下一个键,直至字典的键全部返回后,next 会引发 StopIteration 异常,而 for 循环则会通过捕捉该异常来终止迭代,python的for循环本质就是通过不断调用next()函数实现的
在Python中,一边循环一边计算的机制,称为生成器:generator。
对比生成器和迭代器所占有的内存
import os
import psutil
# 显示当前 python 程序占用的内存大小
def show_memory_info(hint):
pid = os.getpid()
p = psutil.Process(pid)
info = p.memory_full_info()
memory = info.uss / 1024. / 1024
print('{} memory used: {} MB'.format(hint, memory))
def test_iterator():
show_memory_info('initing iterator')
list_1 = [i for i in range(1000000)]
print(list_1)
show_memory_info('after iterator initiated')
print(sum(list_1))
show_memory_info('after sum called')
def test_generator():
show_memory_info('initing generator')
list_2 = (i for i in range(1000000))
print(list_2)
show_memory_info('after generator initiated')
print(sum(list_2))
show_memory_info('after sum called')
test_iterator()
test_generator()
生成器并不会像迭代器一样占用大量内存,只有在被使用的时候才会调用。而且生成器在初始化的时候,并不需要运行一次生成操作,相比于 test_iterator() ,test_generator() 函数节省了一次生成一亿个元素的过程,因此耗时明显比迭代器短。
列表所有数据都在内存中,如果有海量数据的话会非常消耗内存。
比如说:我们仅仅需要访问前面几个元素,但后面绝大多元素占用的内存就会浪费了,那么生成器就是在循环的过程中根据算法不断推算出后续的元素,这样就不用创建整个完整的列表,从而节省大量的空间,总而言之,就是当我们想要使用庞大数据,又想让它占用的空间少,那就使用生成器。
一共两种方法,yield关键字以及将列表推导式的[ ]写成括号
g = (x for x in range(5))
print(g) # generator object
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
# 超出报错
print(next(g))
for i in g:
print(i)
def createNums():
print("-----func start-----")
a,b = 0,1
for i in range(5):
# print(b)
print("--1--")
yield b
print("--2--")
a,b = b,a+b
print("--3--")
print("-----func end-----")
g = createNums()
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
"""文件样式为一行以|分割"""
def readlines(f,newline):
buf = ""
while True:
while newline in buf:
pos = buf.index(newline)
yield buf[:pos]
buf = buf[pos + len(newline):]
chunk = f.read(4096*10)
if not chunk:
yield buf
break
buf += chunk
with open('demo.txt') as f:
for line in readlines(f,"{|}"):
print(line)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。