python、del 和 delattr 哪个更好?

发布于 2024-07-27 22:54:06 字数 254 浏览 8 评论 0原文

这可能很愚蠢,但它已经困扰我一段时间了。

Python 为我们提供了两种从对象中删除属性的内置方法,del 命令字和 delattr 内置函数。 我更喜欢 delattr 因为我认为它更明确一点:

del foo.bar
delattr(foo, "bar")

但我想知道它们之间是否存在潜在的差异。

This may be silly, but it's been nagging the back of my brain for a while.

Python gives us two built-in ways to delete attributes from objects, the del command word and the delattr built-in function. I prefer delattr because it I think its a bit more explicit:

del foo.bar
delattr(foo, "bar")

But I'm wondering if there might be under-the-hood differences between them.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

意中人 2024-08-03 22:54:07

毫无疑问是前者。 在我看来,这就像问 foo.bar 是否比 getattr(foo, "bar") 更好,而且我认为没有人问这个问题:)

Unquestionably the former. In my view this is like asking whether foo.bar is better than getattr(foo, "bar"), and I don't think anyone is asking that question :)

呢古 2024-08-03 22:54:07

这确实是一个偏好问题,但第一个可能更可取。 如果您不知道要提前删除的属性的名称,我只会使用第二个。

It's really a matter of preference, but the first is probably preferable. I'd only use the second one if you don't know the name of the attribute that you're deleting ahead of time.

渡你暖光 2024-08-03 22:54:07

就像 getattr 和 setattr 一样,delattr 仅应在属性名称未知时使用。

从这个意义上说,它大致相当于一些 Python 功能,用于访问比通常可用的级别更低的内置功能,例如 __import__ 而不是 importoperator.add 而不是 +

Just like getattr and setattr, delattr should only be used when the attribute name is unknown.

In that sense, it's roughly equivalent to several python features that are used to access built-in functionality at a lower level than you normally have available, such as __import__ instead of import and operator.add instead of +

望笑 2024-08-03 22:54:07

不确定内部工作原理,但从代码可重用性和不要成为混蛋同事的角度来看,请使用 del。 来自其他语言的人也更清楚和理解。

Not sure about the inner workings, but from a code reusability and don't be a jerk coworker perspective, use del. It's more clear and understood by people coming from other languages as well.

甜味超标? 2024-08-03 22:54:07

这是一个老问题,但我想投入 2 美分。

尽管 del foo.bar 更优雅,但有时​​您需要 delattr(foo, "bar")。 比如说,如果您有一个交互式命令行界面,允许用户通过键入名称来动态删除对象中的任何成员,那么您别无选择,只能使用后一种形式。

It is an old question, but I would like to put my 2 cents in.

Though, del foo.bar is more elegant, at times you will need delattr(foo, "bar"). Say, if you have an interactive command line interface that allows a user to dynamically delete any member in the object by typing the name, then you have no choice but to use the latter form.

陌生 2024-08-03 22:54:07

如果您认为 delattr 更明确,那么为什么不一直使用 getattr 而不是使用 object.attr 呢?

至于幕后……你的猜测和我的一样好。 如果没有明显好转。

If you think delattr is more explicit, then why not used getattr all the time rather than object.attr?

As for under the hood... your guess is as good as mine. If not significantly better.

无声静候 2024-08-03 22:54:06

第一个比第二个更有效率。 del foo.bar 编译为两个字节码指令:

  2           0 LOAD_FAST                0 (foo)
              3 DELETE_ATTR              0 (bar)

delattr(foo, "bar") 需要五个字节码指令:

  2           0 LOAD_GLOBAL              0 (delattr)
              3 LOAD_FAST                0 (foo)
              6 LOAD_CONST               1 ('bar')
              9 CALL_FUNCTION            2
             12 POP_TOP             

这转化为第一个运行稍微更快(但差别并不大——在我的机器上为 0.15 μs)。

就像其他人所说的那样,当您要删除的属性是动态确定的时,您实际上应该只使用第二种形式。

[编辑以显示函数内部生成的字节码指令,其中编译器可以使用 LOAD_FASTLOAD_GLOBAL]

The first is more efficient than the second. del foo.bar compiles to two bytecode instructions:

  2           0 LOAD_FAST                0 (foo)
              3 DELETE_ATTR              0 (bar)

whereas delattr(foo, "bar") takes five:

  2           0 LOAD_GLOBAL              0 (delattr)
              3 LOAD_FAST                0 (foo)
              6 LOAD_CONST               1 ('bar')
              9 CALL_FUNCTION            2
             12 POP_TOP             

This translates into the first running slightly faster (but it's not a huge difference – .15 μs on my machine).

Like the others have said, you should really only use the second form when the attribute that you're deleting is determined dynamically.

[Edited to show the bytecode instructions generated inside a function, where the compiler can use LOAD_FAST and LOAD_GLOBAL]

二智少女猫性小仙女 2024-08-03 22:54:06
  • del更加明确、高效;
  • delattr 允许动态属性删除。

考虑以下示例:

for name in ATTRIBUTES:
    delattr(obj, name)

或者:

def _cleanup(self, name):
    """Do cleanup for an attribute"""
    value = getattr(self, name)
    self._pre_cleanup(name, value)
    delattr(self, name)
    self._post_cleanup(name, value)

您不能使用 del 来做到这一点。

  • del is more explicit and efficient;
  • delattr allows dynamic attribute deleting.

Consider the following examples:

for name in ATTRIBUTES:
    delattr(obj, name)

or:

def _cleanup(self, name):
    """Do cleanup for an attribute"""
    value = getattr(self, name)
    self._pre_cleanup(name, value)
    delattr(self, name)
    self._post_cleanup(name, value)

You can't do it with del.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文