Python 中的 del 语句在什么场景下是不可或缺的?

2012-07-07 13:35:20 +08:00
 skydark
除了美观以外,感觉也就是删除 local/global variable 的时候不得不用 del 了,但是这种事感觉很 evil ……
8289 次点击
所在节点    Python
18 条回复
Shared
2012-07-07 13:43:22 +08:00
没有。你可以完全假设 Python 已经废除了这个关键字
sethverlo
2012-07-07 13:49:18 +08:00
其实我一直觉得如果你想节约内存什么的可以用这个。。虽然完全没用过。。。
skydark
2012-07-07 13:52:35 +08:00
@sethverlo 想节约内存的话赋值一个 None 就好了。

@Shared 好吧……= =
Livid
2012-07-07 13:55:42 +08:00
管理 session 数组的时候用不错。
dreampuf
2012-07-07 14:15:33 +08:00
del 只是将变量的引用计数手动减一,没有执行实际的GC操作。GC还是Python内部调整
sethverlo
2012-07-07 14:35:06 +08:00
@skydark 看了@dreampuf 的回复才知道 del 和我想象的不一样= =.. 我一直以为 del 就等于是赋值 None 。。。(没用过 del)
Smartype
2012-07-07 14:42:05 +08:00
Erics-MacBook-Pro:~ eric$ python
Python 2.7.1 (r271:86832, Jul 31 2011, 19:30:53)
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a = []
>>> dir(a)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

- How to remove an item at a specified index?
fanzeyi
2012-07-07 14:44:56 +08:00
当某个特殊类定义了 __del__ 有特殊作用的时候@@
skydark
2012-07-07 14:55:26 +08:00
@sethverlo 呃,赋值为 None 不就可以把原先绑定的对象的引用计数减 1 么……

@Smartype
a = [1, 2, 3, 4]
i = 2
a = a[:i] + a[i+1:]
或者
a = [v for k, v in enumerate(a) if k != i]
当然明显要丑陋的多,虽然我觉得这完全可以实现为一个方法(其实就是__delitem__),只是因为先有了 del 就懒得加了……
skydark
2012-07-07 14:58:56 +08:00
@fanzeyi 本身 __del__ 对垃圾收集就很不友好,按照 Python 的 explicit 的习惯,用 with 和 content manager,或者干脆显示地写一个 release 方法手动释放不是更好么……
Smartype
2012-07-07 15:00:16 +08:00
@skydark 其实你也知道del是最快速,最有效的方法,干嘛纠结着造轮子呢?呵呵
skydark
2012-07-07 15:09:28 +08:00
@Smartype 不打算造轮子啦……这里没打算从实际应用角度考虑,只是从语言设计的角度,真用的时候肯定是怎么方便怎么来的。
只是觉得比起一般的函数/方法调用而言,一个特殊的 statement 要受限且 evil 的多,所以想确定到底哪里*必须*要用到它。
比如如果 list 的那个方法不叫作 __delitem__ 而叫作 del 的话,a.del(i) 也不比 del a[i] 差多少吧(当然对 del a[i:j], b[k] 这种就没这么漂亮)。
ayanamist
2012-07-07 18:58:57 +08:00
楼主应该去用ruby,你所说的a.del(3)是ruby的纯OO方式。
另外楼主的删除list和dict的变通方法太麻烦,而且会引起三个临时对象的创建和大量无意义的内存复制。
另外楼主不要搞混了js的del,js里的del确实是赋值undefined
aisk
2012-07-09 16:44:07 +08:00
拿dict保存一些缓存对象的时候用
yuelang85
2012-07-09 19:39:37 +08:00
有一种情况,

假设一个字典d,是要写入数据库的。里面有key“a“,不需要写入,于是需要把它清掉。于是:

del d['a']

当然,pop也可以用,pop会返回'a'的value,不过也没啥问题。
skydark
2012-07-09 19:50:02 +08:00
@yuelang85 这些完全可以实现为方法或函数,比如你说的 dict.pop .
实现为语句的话我能想到的唯一的不能用方法完成的是删除变量名,但是我想不到不得不删掉一个变量名的场景,所以才问这个问题的。
yuelang85
2012-07-10 00:24:27 +08:00
@skydark 这样的话,我倒是出现过一种情况,就是模块级变量。

假设我有模块m,有模块级变量m.x,而m.x是在m中计算得来的,需要临时变量_x,这时为了节省时间和效率(也是为了import之后直接就能用m.x),就不会再写函数去计算x(而且函数还会有下面说的和_x一样的问题)

这样的话就会有模块级变量m._x。而有时经常需要用dir操作去查看m有什么数据,如何使用m,这样的话m._x就会混淆视听(前面说的函数也有这个问题),于是,在计算完m.x之后,就会使用:del _x,这样去保持模块整洁。

不知道我有没有说明白。
yuelang85
2012-07-10 00:27:42 +08:00
@yuelang85 还有一种情况,也是模块级变量,就是用模块级变量去做临时储存,为了保持数据整洁,也是为了显式的减少对象计数,也会去del掉这个变量。


其实我觉得,运用语言,很重要一点就是语义,有时候就算是多此一举,为了语义清晰,罗嗦一点也是应该的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/41673

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX