为什么python函数有一个__dict__?

时间:2022-09-11 18:12:00

In Python, functions created using def and lambda have a __dict__ attribute so you can dynamically add attributes to them. Having a __dict__ for every function has a memory cost. An empty dict uses 140 bytes in CPython 2.6.

在Python中,使用def和lambda创建的函数具有__dict__属性,因此可以动态地向它们添加属性。对每个函数都有一个__dict__具有内存开销。一个空指令在CPython 2.6中使用140个字节。

Adding attributes to a function isn't a particularly common thing to do, and you can use a custom object with a __call__ method for the cases where you do need a function with non-standard attributes.

将属性添加到函数中并不是特别常见的事情,您可以使用带有__call__方法的自定义对象来处理那些需要使用非标准属性的函数。

Since adding custom attributes to a function isn't a common use case and having a __dict__ has a memory cost why do Python functions have a __dict__?

由于在函数中添加自定义属性不是一个常见的用例,并且拥有一个__dict__有一个内存开销,为什么Python函数有一个__dict__?

3 个解决方案

#1


9  

PEP 232 has an extensive discussion about this, you might wanna take a look.

PEP 232对此进行了广泛的讨论,您可能想看看。

#2


5  

In Python, functions created using def and lambda have a __dict__ attribute so you can dynamically add attributes to them.

在Python中,使用def和lambda创建的函数具有__dict__属性,因此可以动态地向它们添加属性。

Well, yes; they're objects, after all.

嗯,是的;毕竟,他们的对象。

Having a __dict__ for every function has a memory cost. An empty dict uses 140 bytes in CPython 2.6.

对每个函数都有一个__dict__具有内存开销。一个空指令在CPython 2.6中使用140个字节。

It's 124 bytes for me. Not that it really matters for the sake of discussion.

这是124个字节。并不是说这真的很重要,只是为了讨论。

If you really needed to save every byte, you wouldn't be using Python. In a program that uses a lot of memory, functions normally represent a tiny fraction of the number of objects, so the overhead is not really important. IMO you should be much more worried about the fact that it's costing you 16 bytes per floating-point value and you can't switch from double to float. Of course, the way to worry about this is to use Numpy. :)

如果您真的需要保存每个字节,那么就不会使用Python。在使用大量内存的程序中,函数通常只表示对象数量的一小部分,因此开销并不重要。你应该更担心的是,它会花费你16字节每浮点值,你不能从double转换到float。当然,担心这个问题的方法是使用Numpy。:)

Adding attributes to a function isn't a particularly common thing to do,

将属性添加到函数中并不是特别常见的事情,

If you come from the Java/C++/C# world, then I imagine it must seem horribly messy to you. But for people who come from the Perl/Javascript world (or even, in a rather different direction, maybe something like Scheme or Haskell), it's pretty elegant.

如果你来自Java/ c++ / c#世界,那么我想这对你来说一定很混乱。但是对于那些来自Perl/Javascript世界的人(或者甚至是一个不同的方向,可能是Scheme或Haskell),这是非常优雅的。

So basically, I would say the answer is "why not?" :)

所以基本上,我认为答案是“为什么不呢?”:)

#3


2  

the empty dict doesn't exist if you don't require it, here is the code to check it:

如果你不需要,空的字典是不存在的,下面是检查它的代码:

import gc
f = lambda :1
print {} in gc.get_referents(f)
f.__dict__
print {} in gc.get_referents(f)

#1


9  

PEP 232 has an extensive discussion about this, you might wanna take a look.

PEP 232对此进行了广泛的讨论,您可能想看看。

#2


5  

In Python, functions created using def and lambda have a __dict__ attribute so you can dynamically add attributes to them.

在Python中,使用def和lambda创建的函数具有__dict__属性,因此可以动态地向它们添加属性。

Well, yes; they're objects, after all.

嗯,是的;毕竟,他们的对象。

Having a __dict__ for every function has a memory cost. An empty dict uses 140 bytes in CPython 2.6.

对每个函数都有一个__dict__具有内存开销。一个空指令在CPython 2.6中使用140个字节。

It's 124 bytes for me. Not that it really matters for the sake of discussion.

这是124个字节。并不是说这真的很重要,只是为了讨论。

If you really needed to save every byte, you wouldn't be using Python. In a program that uses a lot of memory, functions normally represent a tiny fraction of the number of objects, so the overhead is not really important. IMO you should be much more worried about the fact that it's costing you 16 bytes per floating-point value and you can't switch from double to float. Of course, the way to worry about this is to use Numpy. :)

如果您真的需要保存每个字节,那么就不会使用Python。在使用大量内存的程序中,函数通常只表示对象数量的一小部分,因此开销并不重要。你应该更担心的是,它会花费你16字节每浮点值,你不能从double转换到float。当然,担心这个问题的方法是使用Numpy。:)

Adding attributes to a function isn't a particularly common thing to do,

将属性添加到函数中并不是特别常见的事情,

If you come from the Java/C++/C# world, then I imagine it must seem horribly messy to you. But for people who come from the Perl/Javascript world (or even, in a rather different direction, maybe something like Scheme or Haskell), it's pretty elegant.

如果你来自Java/ c++ / c#世界,那么我想这对你来说一定很混乱。但是对于那些来自Perl/Javascript世界的人(或者甚至是一个不同的方向,可能是Scheme或Haskell),这是非常优雅的。

So basically, I would say the answer is "why not?" :)

所以基本上,我认为答案是“为什么不呢?”:)

#3


2  

the empty dict doesn't exist if you don't require it, here is the code to check it:

如果你不需要,空的字典是不存在的,下面是检查它的代码:

import gc
f = lambda :1
print {} in gc.get_referents(f)
f.__dict__
print {} in gc.get_referents(f)