我有几个在其中使用 self
的实例方法,但只在几个地方。
我可以直接将对象传递给这些方法并使它们成为staticmethod
。这会占用更少的内存吗?
最佳答案
您在这里进行微优化没有任何好处。
是的,常规方法涉及一个新的 method
为处理函数和实例之间的绑定(bind)而创建的对象,但这只是一点内存(2 个指针加上一些 Python 元数据)仅在调用期间或存储绑定(bind)方法时使用 *。 staticmethod
object 不会创建新的方法对象,但是 抵消了 staticmethod
所需的内存量。对象:
>>> import sys
>>> class Foo:
... def bar(self): pass
... @staticmethod
... def staticbar(): pass
...
>>> sys.getsizeof(Foo().bar) # bound method object size
64
>>> sys.getsizeof(Foo.__dict__['staticbar']) # staticmethod size
56
所以使用 staticmethod
object 为您节省 8 个字节(在 Mac OS X 上,在另一个操作系统上,字节数可能略有不同),但您通常不会保留绑定(bind)方法(您会使用 instance.method()
,它创建方法对象然后在调用后再次丢弃它)。
因此,除非您存储大量绑定(bind)方法,否则这不会产生足够的差异来证明通过在任何地方手动传递实例来使您的代码不可读是合理的。
* 请注意,从 Python 3.7 开始,对于常见情况,Python 甚至不再创建方法对象。查看Optimisations section of the 3.7 What's New notes :
Method calls are now up to 20% faster due to the bytecode changes which avoid creating bound method instances.
这适用于 <expr>.attribute_name(...)
调用序列,因此属性名称查找后直接跟在调用之后,在相同的整体表达式中,前提是仅使用位置参数。生成特殊字节码来验证 attribute_name
解析为类上的方法名称,然后使用 <expr>
的结果直接调用底层函数前置。 Python 使用 LOAD_METHOD
其次是 CALL_METHOD
操作码而不是 LOAD_ATTR
和 CALL_FUNCTION
操作码,但如果优化不适用,则回退到后两者的行为。
关于python - python静态方法是否比实例方法消耗更少的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44898947/