【问题标题】:Find out if running INSIDE a @staticmethod of a class找出是否在类的@staticmethod 内部运行
【发布时间】:2021-06-17 23:45:43
【问题描述】:

如果函数在对象内部被调用,我使用以下方法:

frame = inspect.currentframe().f_back.f_locals
obj = frame['self'] if 'self' in frame else None
if obj is None : raise Exception("use only in objects")

有没有办法判断我是否在类的@staticmethod 内运行

【问题讨论】:

  • 这个的用例是什么?
  • 如果从实例方法内部调用静态方法会怎样,反之亦然?

标签: python class static-methods


【解决方案1】:

staticmethod 是实现the descriptor protocol 的包装器。描述符协议在查找方法期间应用,它不是堆栈帧中的额外层(在调用方法时,不再涉及描述符)。当您看到a.b() 时,它的实现方式为:

  1. 加载a
  2. 加载ab属性(现代CPython中有一些古怪的优化,但逻辑行为保持不变)
  3. 调用已加载的b

@staticmethod 在第 2 步中插入自身(更改从加载 b 属性获得的内容),而堆栈跟踪中只有第 3 步可见。

您可以应用各种启发式方法猜测您是否在 staticmethod 中,但堆栈帧中的任何内容都不会直接告诉您(@staticmethod 看起来与普通的不属于任何类的函数;这并没有错,因为@staticmethod 基本上是一个使用类作为命名空间的普通函数,而实际上并未以任何方式使用该类)。如果你认为你需要知道这些信息,那你可能错了,你有 an XY problem 你没有告诉我们。

【讨论】:

  • 我有一个简单的记录器/调试器来检查它执行的 obj attr 是否打印。我想在 staticmethod 调用中进行类似的检查:github.com/vsraptor/quick-debug/blob/master/debug.py
  • @sten:是的,这在很大程度上是荒谬的。静态方法有意丢弃有关它们如何被调用的所有信息;描述符在调用它之前丢弃有关实例(如果有)和类的信息。即使您已经在做的事情也有些不可靠(假设self 参数实际上被命名为self,而这只是一个约定)。你所说的“简单”实际上已经是“难以置信的复杂/骇人听闻”,而你必须添加的启发式方法才能对静态方法做任何微不足道的有用的事情,这会让你因它令人震惊的可怕而感到羞耻。
猜你喜欢
  • 2016-07-07
  • 2011-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-15
相关资源
最近更新 更多