链表本身就是个容器,可以将前面写的数据用一种新的方式存储起来,内存连续是列表。散列的是set,字典,链表是手拉手的方式,能够用前一个知道下一个或下一个知道前一个在哪里,就可以串联起来,每一个链表上面都放了很多元素,元素之前通过这个关系关联起来,每个元素内部通过面向对象保存住,只是放了个地址引用而已
链表的好处是增删较为容易,但是遍历是一样的,随机访问就慢了,列表arrange,就是数组,在内部随意的增删,都会引起整个数组的挪动,所以数组是建议在尾部做一些操作,中间操作就不太合适了,随机访问是O(1)的
加上列表,辅助完成上面方法,之前试了下,一个都不合适,写出来四不像
(之前写的代码)
先完成第一个要求
使用列表完成,现在容器加一个列表
在尾部追加的时候,列表中的元素也要尾部追加,在return之前追加
insert,在哪个里面加item,列表也要加
弹出也一样,链表从尾部弹出,列表也需要从尾部弹出
remove就需要注意了
iternodes,这些方法都可以,还有其他的写法
用这种方式对列表进行封装
下面解决__getitem__的问题,setitem
两种写法到底哪个可以
上面的链表,下面的列表,创建一个node节点,把左右关系定好,这个node节点就被head记住了,同样把node节点放到列表中,放的是同一个node,放在不同容器里,但是放的是同一个引用,现在想要修改某一个node节点的item,这两个都是用的同一个 引用地址
借用了列表的随机访问特性,要第5个就偏移即可,但是链表招第5个就需要遍历了,不遍历不行,这样就借助列表,保存同一个对象,就是为了借助列表的索引可以随机访问,想要哪个就哪个,访问的速度很快,但是现在使用的方式是查多写少,
但是现在如果不断增加元素,列表就吃不消了,挪动太平凡,所以这里看是很好,但是解决起来还是有很多问题
这里保存的node,node有上下级的关系,手拉手记住前后关系,在列表记录的node也是同一个node,这两个都是同一个,用任何方式去检索和修改就可以了,因为是同一个东西
这个访问肯定是有问题的,这样访问相当于重新创建了新的节点,塞到这个self.item里面去,链表跟这里就完全是两码事
这里是把列表中的元素更新掉了,列表和链表中的node就不一致了
试试这种还有没有其他写法
self【index】当前对象直接用索引访问,调到__getitem__,上面返回self.item[index]
用这种方式就解决了链表的写法问题
这个写完叫四不像
看似对链表进行增强,实际上只有在列表的使用场景的时候,才会产生高效
现在不用列表,只有链表
下面长度如何进行计算,(列表算长度,就是有个特殊的元素放长度,每次增加减少对应+1-1即可)
insert应该+=
pop应该-=
只要remove成功也是-=
这个该怎么样怎么样就不动了
** __iter__换一种写法,本身也是返回的生成器就没必要写这么多**
** __getitem__比较复杂,正索引和负索引
负索引就是反转iternodes(True),要 的数字是-1,-2。-3
写成这样子上下两个语句块绝对是同一个东西**
这样也支持正负索引,正数和负数如果有统一的地方,代码可以大大精简
** setitem,只要上面把node拿到,下面.item直接把值换掉即可**
python3的精髓是能惰性求职就惰性求职,其他语言,一般for循环就是迭代玩数字,python是enumerate提供了数字,排序要求立即返回列表,其他全是惰性求值
实现类似于property的装饰器
先来搞定property,先写等价式,data=property(data),data最终等于property实例
跟函数装饰器不一样,函数装饰器修饰后可以返回原来函数,也可以返回包装函数
data属性现在是描述器,一旦被访问,就会调用__get__instance就是小a,owner是A
这样就拿到结果了
这样的写法不好,要求你知道原来的属性名称,不知道就没办法了
假如不用属性名,那就模拟行为,原来的行为是调用这个函数可以把这个值返回出去
能不能把函数的返回结果扔回去,缺self,把self放进去
跟之前写的setattr,把一个方法附加到类上,变成一个类属性,另一个附加到实例上去,附加实例上的时候,有绑定效果,如果有把这个函数捆绑到实例的时候,在用实例就出问题了
如果写一个A.show=lambda self:pass这是增加类属性
a.show() 有的
a.show= lambda self:pass 这个是你自己处理self
这样的时候a.show()不会有绑定效果
self.fn=fn动态的为实例增加了一个函数,没有把fn变成一个类属性,实例的属性等于一个函数,没有任何绑定函数
最普通的函数调用不会有绑定效果(有绑定效果就会把某一个值塞进来,放到一个参数上,现在没有人放,就是参数缺失,现在要放的是A的实例)(第一参数没人管,)fn对应的是下面的data函数(1参),就需要补进instance,
用了装饰器,每次装饰应该产生实例,如果是类就装饰坏了,类属性是共用的就冲突了,这样的话每一个实例都有自己管理的函数
效果是一样的
下面解决data.setter,返回的时候property实例,然后需要settr方法
这样调用是没有绑定效果的
两个做完之后,这个A类就等价于property描述器实例
100传到这里
都可以判断一下
这就是关于property的实现
**可以把属性通过get,set方法,进行非常细节的控制 **