当您使用其他语言编写代码时,有时会创建一个块范围,如下所示:
statement
...
statement
{
statement
...
statement
}
statement
...
statement
Run Code Online (Sandbox Code Playgroud)
一个目的(很多)是提高代码可读性:显示某些语句形成逻辑单元或某些局部变量仅在该块中使用.
是否有一种在Python中做同样事情的惯用方法?
我通常del在我的代码中使用删除对象:
>>> array = [4, 6, 7, 'hello', 8]
>>> del(array[array.index('hello')])
>>> array
[4, 6, 7, 8]
>>>
Run Code Online (Sandbox Code Playgroud)
但我听到很多人说使用del是unpythonic.使用del不好的做法?
>>> array = [4, 6, 7, 'hello', 8]
>>> array[array.index('hello'):array.index('hello')+1] = ''
>>> array
[4, 6, 7, 8]
>>>
Run Code Online (Sandbox Code Playgroud)
如果没有,为什么有很多方法可以在python中完成同样的事情?一个比其他人好吗?
选项1:使用 del
>>> arr = [5, 7, 2, 3]
>>> del(arr[1])
>>> arr
[5, 2, 3]
>>>
Run Code Online (Sandbox Code Playgroud)
选项2:使用 list.remove()
>>> arr = [5, 7, 2, 3]
>>> arr.remove(7)
>>> arr
[5, 2, 3] …Run Code Online (Sandbox Code Playgroud) 每当我处理原型脚本时,我倾向于使用它,并且:
fileCount)和在这种情况下,为了避免潜在的变量冲突,我会在完成后立即删除bugger.我知道,在生产代码中我应该避免使用1.,2.和3.,但是从原型工作到完全抛光的类是非常耗时的.有时我可能想要解决一个次优,快速的重构工作.在那种情况下,我发现保持这些del陈述很方便.我是否养成了不必要的坏习惯?是del完全可以避免的?什么时候会好的?
我知道python有一个自动垃圾收集器,因此它应该在没有更多引用时自动删除变量.
我的印象是局部变量(函数内部)不会发生这种情况.
def funz(z):
x = f(z) # x is a np.array and contains a lot of data
x0 = x[0]
y = f(z + 1) # y is a np.array and contains a lot of data
y0 = y[0]
# is x and y still available here?
return y0, x0
Run Code Online (Sandbox Code Playgroud)
del x是节省内存的正确方法吗?
def funz(z):
x = f(z) # x is a np.array and contains a lot of data
x0 = x[0]
del x
y = f(z + 1) # …Run Code Online (Sandbox Code Playgroud) 对于刚接触python的人,我不明白如何从递归函数中删除类的实例.
考虑一下kd树的代码:
def remove(self, bin, targetAxis=0, parent=None):
if not self:
return None
elif self.data.x == bin.x and self.data.y == bin.y:
if self.rightNode:
self.data = self.rightNode.findMin((targetAxis+1)% KdSearch.DIMENSION)
self.rightNode = self.rightNode.remove(self.data, (targetAxis+1)% KdSearch.DIMENSION,self)
elif self.leftNode:
self.data = self.leftNode.findMin((targetAxis+1)% KdSearch.DIMENSION)
self.rightNode = self.leftNode.remove(self.data, (targetAxis+1)% KdSearch.DIMENSION,self)
else:
if not parent is None:
#get direction if child....
if not parent.leftNode is None:
if parent.leftNode.data.x == bin.x and parent.leftNode.data.y == bin.y:
parent.leftNode=None
if not parent.rightNode is None:
if parent.rightNode.data.x == bin.x and parent.rightNode.data.y == …Run Code Online (Sandbox Code Playgroud) 该del语句有许多实际用途来删除属性等(参见什么时候在python中有用?等等),但它也可以用来取消绑定局部变量:
def test():
x = ...
del x
Run Code Online (Sandbox Code Playgroud)
这有什么实际用例吗?
想到垃圾收集,但x=None应该具有相同的效果.我也听说"导入后清理"是一个原因,但from ... import ...做得更好."更清洁的代码"也出现了,但我不知道如何del使代码更清晰(至少对于不需要重构的代码而言).
编辑:
这有点失控.我期待一个像这样的答案
"当然你需要del x!你做不到......不然,不管怎样,呃!"
我想现在可以说没有这样的答案.如果有用途,那么它们的编码风格相关并且"有争议".
我试图通过在问题中直接反击最常见的问题来避免"意见"的讨论,显然这不起作用......
我只是好奇为什么Python有这个功能,并认为可能有一些最好的实践让我学习.
既然其他人都有他们的意见,那么让我自己加一点:
我建议不要解除局部变量的绑定.经验不足的Python程序员(特别是那些具有C++背景的程序员)很可能会被解读del x为delete the object referenced by x.他们经常把它del x当作捷径x.__del__().许多人__del__经常使用它们.我多次看到这种误解.它最糟糕的是它最初适用于它们!使用简单的代码,对象只从该变量引用,CPython的行为就像他们认为的那样.因此,初学者会对他们的误解得到积极的强化,并开始越来越频繁地使用它,最终导致大量的错误代码和他们不理解的怪异行为.
为什么python的创建者更喜欢这种语法(指令)
del list[index]
Run Code Online (Sandbox Code Playgroud)
这个(方法)?
list.del(index)
Run Code Online (Sandbox Code Playgroud)
在我看来,是del属于同一个"cathegory"为append,remove,find,等,因此应该有相同的语法(是一种方法),但由于一些原因,蟒蛇的创造者实现它的指令.他们为什么这么做?
每隔一段时间我就会想要从我的其他项目中休息一下,尝试将经典冒险基于文本的游戏(在Python中,这次)作为一个有趣的项目,但我总是有实现项目系统的设计问题.
我希望游戏中的项目从一个基Item类下降,包含每个项目具有的一些属性,例如损坏和重量.当我尝试为这些项添加一些功能时,我的问题开始了.当物品的伤害超过阈值时,它应该被摧毁.我的问题就在于:我真的不知道如何实现这一目标.
由于del self不会为一百万个不同的原因,工作(:我故意提供使用"删除"作为我知道错了东西,我知道垃圾收集是什么,以及它是如何不是我想要的.编辑)如何我应该这样做(和其他类似的任务)?每个项目是否应该包含某种对它的容器的引用(我猜这个玩家)并且"要求"自己被删除?
首先想到的是一个包含游戏中每个项目的大字典,每个对象都会引用这个列表,并且都拥有并知道它自己的唯一ID.我根本不喜欢这个解决方案,我认为这不是正确的方法.有人有什么建议吗?
编辑:我看到很多人都认为我担心垃圾收集.我所说的不是垃圾收集,而是从游戏玩法中删除对象.我不确定应该启动哪些对象去除等.
假设我有一项从网络获取图像并将其保存到目录的服务。我以 .png 文件形式获取输入并将其保存在本地。我使用 PIL 打开图像,并根据需要为其添加背景。我最近注意到处理某些 .png 文件时内存使用率很高。似乎当打开某些 .png 时,PIL 没有正确释放内存。
以下代码将演示会发生什么:
from PIL import Image
import resource
def check_mem(filename):
mem = lambda:resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
print mem()
img = Image.open(filename)
print mem()
img = img.convert('RGBA')
print mem()
background = Image.new("RGBA", img.size, (255, 255, 255))
print mem()
image = background.paste(img, img)
print mem()
del background
del img
del image
print mem()
if __name__ == "__main__":
import sys
check_mem(sys.argv[1])
Run Code Online (Sandbox Code Playgroud)
对于某些图像(例如像这样的图像),这会生成以下输出:
12416
12416
22508
22508
22508
22508
Run Code Online (Sandbox Code Playgroud)
您可以看到使用的内存几乎增加了一倍!即使最后我删除了所有对象,内存仍然是开始时的两倍。
对于其他图像,例如这一张内存使用情况不会改变:
12416
12416
12416 …Run Code Online (Sandbox Code Playgroud) sip.delete()我想了解使用和删除小部件(包括它的布局和此布局中的子项)之间有什么区别deleteLater()。我知道这一点removeWidget(),setParent(None)只是从布局中删除小部件,但它并没有从内存中删除对象本身。如果我想从内存中删除一个对象,我应该使用哪个?我知道这个问题以前被问过,但我希望得到详细的答案:)