一、可变数据类型
在Python中我们知道数字、字符串、元组为不可变数据类型,而列表、字典为可变的数据类型。那到底什么是可变数据类型?什么是不可变数据类型呢?
如上图对不可变数据类型整数实例分析:即知一个数值无论被多少个变量引用,其在内存中永远只会存储一个,一旦这个数值发生变化,这就是一个新的数值,既会有一个新的存储地址,即数据存储只认变量值。也就是说这个数值本身是不可以进行append等操作。
如上图为可变数据类型的分析图:可知无论是相同的变量对象还是不同的变量的对象引用相同的数值,其在内存中都是以不同的内存的地址进行存储的,即可变数据类型存储只认变量对象本身,每一个对象指向一个内存地址,内存地址中数据可以进append操作,即数据可以变化,但是变量对象永远指向这个地址,变量对象的数据随着指向的数据变化而变化。
总之,用一句话来概括上述过程就是:“python中的不可变数据类型,不允许变量的值发生变化,如果改变了变量的值,相当于是新建了一个对象,而对于相同的值的对象,在内存中则只有一个对象,内部会有一个引用计数来记录有多少个变量引用这个对象;可变数据类型,允许变量的值发生变化,即如果对变量进行append、+=等这种操作后,只是改变了变量的值,而不会新建一个对象,变量引用的对象的地址也不会变化,不过对于相同的值的不同对象,在内存中则会存在不同的对象,即每个对象都有自己的地址,相当于内存中对于同值的对象保存了多份,这里不存在引用计数,是实实在在的对象。”
二、应用实例
在我们blog项目中构建评论树(即所有的子评论,归在其对应的父评论下面)时,在评论数据整理时,我们就要用到这种可变数据类型思想。具体实例如下:
comment_list=[
{"nid":1,"content":"111","pid":None},
{"nid":2,"content":"222","pid":None},
{"nid":3,"content":"333","pid":None},
{"nid":4,"content":"444","pid":1}, #为第一条评论的子评论
{"nid":5,"content":"555","pid":4}, #为第四条评论的子评论
{"nid":6,"content":"666","pid":2}, #为第二条评论的子评论
]
假设如上为我们评论数据,其中pid为None代表此条评论为根评论,有值则代表此评论为nid=pid评论的子评论,我们现在需要将所有的子评论数据加到对应的父评论后面,并只保留父评论数据,实现方式如下:
# 方法一
for comment in comment_list:
comment["children_list"]=[] #用于存放子评论的列表
for comment1 in comment_list:
if comment1["pid"]==comment["nid"]:
comment["children_list"].append(comment1)
print(comment_list)
new_comment_list=[]
for comment2 in comment_list:
if not comment2["pid"]:
new_comment_list.append(comment2)
print(new_comment_list)
因为comment["children_list"]=[]为可变数据类型,现在每一条评论数据都有这么一个键值对,当第四条评论加到第一条评论的comment["children_list"]=[]列表中时,第四条评论中的此列表为空,当第五条评论加到第四条评论的列表中后,第一条评论里的第四条评论中也会有第五条这条子评论。
# 方法二
comment_dict={}
for comment in comment_list:
comment["children_list"]=[]
comment_dict[comment["nid"]]=comment
print(comment_dict)
result=[]
for key,comment in comment_dict.items():
pid=comment["pid"]
if pid:
comment_dict[pid]["children_list"].append(comment)
else:
result.append(comment)
print(result)
三、页面跳转
在我们实际的网页中访问中,当我们需要做评论或者点赞等动作时,应该先验证是否登录用户,如果没有应该跳转到登录页面进行登录,但是通过这种登录后该如何原路跳转到登录前的那个页面呢?具体实例讲解如下:
1、获取当前页面路径
在此页面的对应的视图函数通过request.path便可获得当前页面的请求路径,在渲染页面时可将此路径传给当页面进行保存。在进行登录页面跳转时可将此路径地址作为参数附带,如下例:
2、登录完跳转至原路径
以下为登录验证成功后跳转到原路径的情况,这里需要注意location.href和location.search两个参数所代表路径情况,前者为当前页面的完整路径,而后者为路径中的参数部分,如location.href为:http://127.0.0.1:8000/login/?next=/blog/zhangli/articles/1,则location.search为:?next=/blog/zhangli/articles/1,应用实例如下: