@staticmethod是否在CPython或Micropython中保存了任何内存? [英] Does @staticmethod save any ram in CPython or Micropython?
问题描述
@staticmethod
的一个原因是为了保存RAM,因为静态方法只实例化一次。这个断言很容易在网上找到(例如here),我不知道我第一次遇到它是在哪里。
我的推理基于两个假设,其中一个是错误的:a.在实例化一个类时,python实例化了所有的方法(这不是事实,想想就知道了,哎呀)和b.静态方法不是在访问时实例化的,而是直接调用的。因此我认为这个代码:
import asyncio
class Test:
async def meth1():
await asyncio.sleep(10)
return 78
t1= Test()
t2 = Test()
loop = asyncio.get_event_loop
loop.create_task(t1)
loop.create_task(t2)
def main():
for _ in range(10):
await asyncio.sleep(2)
loop.run(main())
如果我这样定义类,将使用更多的内存:
class Test:
@staticmethod
async def meth1():
await asyncio.sleep(10)
return 78
是这样的吗?静态方法在访问时被实例化吗?类方法是否在Access上实例化?我知道t1.meth1 is t2.meth1
将在第二种情况下返回True
,在第一种情况下返回False
,但这是因为Python第一次实例化meth1
然后在第二次查找它,还是因为在这两种情况下它都只是查找它,或者因为在两种情况下它都获得了某种程度上相同的静态方法的副本(我假设不是这样?)静态方法的id
似乎没有更改:但我不确定我对它的访问在做什么。
如果是这样的话,有什么现实世界需要关心的吗?我在micropython代码中看到了大量的静态方法,其中多个实例同时存在于异步代码中。我以为这是为了拯救公羊,但我怀疑我错了。我很想知道这里的micropython和Cpython实现之间是否有什么不同。
编辑
我认为调用t1.meth1()
和t2.meth1()
将在第一个实例中绑定两次,在第二个实例中绑定一次,这是正确的。
推荐答案
方法没有实例化&qot;,它们被绑定--这是";它们的self
/cls
参数填充";,类似于partial
parameter binding。staticmethod
的全部要点是没有self
/cls
参数,因此不需要绑定。
事实上,获取staticmethod
根本不做任何事情-它只是原封不动地返回函数:
>>> class Test:
... @staticmethod
... async def meth1():
... await asyncio.sleep(10)
... return 78
...
>>> Test.meth1
<function __main__.Test.meth1()>
因为方法是按需绑定的,所以它们通常不以绑定形式存在。因此,只拥有方法不需要支付内存成本,staticmethod
也不需要收回任何内存成本。由于staticmethod
是查找过程中的实际层--即使它什么也不做--使用(不)使用staticmethod
这两种方式都不会提高性能。
In [40]: class Test:
...: @staticmethod
...: def s_method():
...: pass
...: def i_method(self):
...: pass
...:
In [41]: %timeit Test.s_method
42.1 ns ± 0.576 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [42]: %timeit Test.i_method
40.9 ns ± 0.202 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
请注意,根据实施和测试设置的不同,这些计时可能略有不同。值得注意的是,这两种方法的速度都相当快,性能与选择其中一种并不相关。
≈staticmethod
工作方式为descriptor,它在每次查找方法时运行。
这篇关于@staticmethod是否在CPython或Micropython中保存了任何内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!