Jas*_*ker 350 python dictionary del python-internals
我真的不能想到为什么python需要del关键字(并且大多数语言似乎没有类似的关键字).例如,不是删除变量,而是可以分配None给它.从字典中删除时,del可以添加方法.
是否有任何理由保留delpython,或者它是Python垃圾收集前几天的遗迹?
Win*_*ert 466
首先,你可以除了局部变量之外还有其他东西
del list_item[4]
del dictionary["alpha"]
Run Code Online (Sandbox Code Playgroud)
这两者都应该是显而易见的.其次,使用del局部变量使意图更清晰.相比:
del foo
Run Code Online (Sandbox Code Playgroud)
至
foo = None
Run Code Online (Sandbox Code Playgroud)
我知道在这种情况下del foo,意图是从范围中删除变量.目前尚不清楚这样foo = None做.如果有人刚刚分配foo = None我可能认为它是死代码.但我立即知道编码的人del foo正在尝试做什么.
Gre*_*ill 157
这部分内容del(来自Python语言参考):
删除名称将删除该名称与本地或全局名称空间的绑定
分配None名称不会从名称空间中删除名称的绑定.
(我想可能会有一些关于删除名称绑定是否实际有用的争论,但这是另一个问题.)
Jas*_*ker 42
我发现del有用的一个地方是清除for循环中的无关变量:
for x in some_list:
do(x)
del x
Run Code Online (Sandbox Code Playgroud)
现在,如果在for循环外使用x,则可以确定x是未定义的.
Sin*_*ion 16
del当您sys.exc_info()用于检查异常时,有一个特定的例子,您应该何时使用(可能还有其他人,但我知道这一个).此函数返回一个元组,引发的异常类型,消息和回溯.
前两个值通常足以诊断错误并对其进行操作,但第三个值包含引发异常的位置和捕获异常的位置之间的整个调用堆栈.特别是,如果你做的事情
try:
do_evil()
except:
exc_type, exc_value, tb = sys.exc_info()
if something(exc_value):
raise
Run Code Online (Sandbox Code Playgroud)
回溯,tb最终在调用堆栈的本地中,创建一个无法进行垃圾回收的循环引用.因此,重要的是:
try:
do_evil()
except:
exc_type, exc_value, tb = sys.exc_info()
del tb
if something(exc_value):
raise
Run Code Online (Sandbox Code Playgroud)
打破循环引用.在很多情况下,你想打电话sys.exc_info(),像元类魔术,回溯是有用的,所以你必须确保你清理之前,你都不可能离开异常处理程序.如果您不需要回溯,则应立即将其删除,或者只是执行以下操作:
exc_type, exc_value = sys.exc_info()[:2]
Run Code Online (Sandbox Code Playgroud)
为了避免这一切.
tdi*_*ihp 15
只是另一种想法.
在像Django这样的框架中调试http应用程序时,调用堆栈中充满了无用且搞砸了之前使用的变量,特别是当它是一个很长的列表时,对开发人员来说可能非常痛苦.所以,在这一点上,名称空间控制可能很有用.
Ber*_*ard 15
删除变量名称del很可能是很少使用的东西,但如果没有关键字,它就无法轻易实现.如果您可以通过编写创建变量名称a=1,那么理论上可以通过删除a来撤消它.
在某些情况下,它可以使调试更容易,因为尝试访问已删除的变量会引发NameError.
Python允许你编写类似的东西:
class A(object):
def set_a(self, a):
self.a=a
a=A()
a.set_a(3)
if hasattr(a, "a"):
print("Hallo")
Run Code Online (Sandbox Code Playgroud)
如果您选择动态地向类实例添加属性,您当然希望能够通过编写来撤消它
del a.a
Run Code Online (Sandbox Code Playgroud)
小智 12
明确地使用"del"也比将变量赋值给None更好.如果你尝试del一个不存在的变量,你会得到一个运行时错误,但如果你试图将一个不存在的变量设置为None,Python会默默地将一个新变量设置为None,留下变量你想删除它的位置.所以del会帮助你早点发现你的错误
要在上面的答案中添加几点:
del x
x指示的定义r -> o(r指向对象的引用o)但是del x更改r而不是o.它是对象的引用(指针)而不是与之关联的对象的操作x.区分r和o关键在这里.
locals().globals(),如果x是属于那里.x属于哪里,而不是x指向哪里.记忆中唯一的物理变化就是这个.例如,如果x在字典或列表中,它(作为参考)将从那里(而不一定从对象池)中删除.在这个例子中,它所属的字典是堆栈框架(locals()),它与之重叠globals().使用numpy.load后强制关闭文件:
也许利基使用,但我发现它在numpy.load用于读取文件时很有用.每隔一段时间我就会更新文件,并需要将具有相同名称的文件复制到目录中.
我曾经del发布过该文件并允许我复制新文件.
注意我想避免使用with上下文管理器,因为我在命令行中使用了绘图并且不想按Tab键很多!
看到这个问题.
del常见于__init__.py文件中.__init__.py文件中定义的任何全局变量都会自动"导出"(它将包含在a中from module import *).避免这种情况的一种方法是定义__all__,但这可能会变得混乱而不是每个人都使用它.
例如,如果您有__init__.py类似的代码
import sys
if sys.version_info < (3,):
print("Python 2 not supported")
Run Code Online (Sandbox Code Playgroud)
然后您的模块将导出sys名称.你应该写
import sys
if sys.version_info < (3,):
print("Python 2 not supported")
del sys
Run Code Online (Sandbox Code Playgroud)
我发现del在使用 Numpy 处理大数据时对伪手动内存管理很有用。例如:
for image_name in large_image_set:
large_image = io.imread(image_name)
height, width, depth = large_image.shape
large_mask = np.all(large_image == <some_condition>)
# Clear memory, make space
del large_image; gc.collect()
large_processed_image = np.zeros((height, width, depth))
large_processed_image[large_mask] = (new_value)
io.imsave("processed_image.png", large_processed_image)
# Clear memory, make space
del large_mask, large_processed_image; gc.collect()
Run Code Online (Sandbox Code Playgroud)
这可能是在 Python GC 跟不上时,随着系统疯狂地交换而使脚本陷入停顿,并且它在松散的内存阈值以下完美流畅地运行,从而留出足够的空间来使用机器进行浏览并在工作时编写代码。
我想详细说明已接受的答案,以强调设置变量与None删除变量之间的细微差别del:
给定变量foo = 'bar'和以下函数定义:
def test_var(var):
if var:
print('variable tested true')
else:
print('variable tested false')
Run Code Online (Sandbox Code Playgroud)
一旦最初宣布,test_var(foo)就会产生variable tested true预期的效果。
现在尝试:
foo = None
test_var(foo)
Run Code Online (Sandbox Code Playgroud)
产生variable tested false.
将此行为与以下行为进行对比:
del foo
test_var(foo)
Run Code Online (Sandbox Code Playgroud)
现在提出了NameError: name 'foo' is not defined.
| 归档时间: |
|
| 查看次数: |
309387 次 |
| 最近记录: |