【问题标题】:Allow calling function to get caller's attribute in Python允许调用函数在 Python 中获取调用者的属性
【发布时间】:2016-12-08 13:59:35
【问题描述】:

我想创建一个函数,每当调用者获取错误实例的参数时都会调用该函数,它将打印调用者的__doc__ 属性并退出。函数如下:

def checktype(objects,instances):
    if not all([isinstance(obj,instance) for
                obj,instance in zip(objects,instances)]):
      print 'Type Error'
      #Get __doc__ from caller
      print __doc__
      exit()

我陷入了必须获取__doc__ 属性的步骤。我知道inspect 模块可以做到这一点,方式如下:

name=inspect.stack()[1][3]
possibles=globals().copy()
__doc__= possibles.get(name).__doc__

(你可以推荐另一个兼容所有 Python 版本的,包括 3.5)

但我认为必须有另一种方式。我持怀疑态度的原因是内置的return 语句会立即向调用者返回一些东西,这意味着必须有一个子函数可以访问的“钩子”或“管道”,正在使用作为与家长进行信息交流的媒介。所以最初引起我兴趣的问题是:

这个管道是只发送并且没有信息可以向后发送吗?

我无法回答这个问题,因为return 声明仅在我搜索的网站中进行了简要说明。除此之外,据我所知,inspect 模块将多个帧保存在堆栈中并在后台持续运行。对我来说,这就像我试图用迷你枪杀死一只苍蝇。我只需要调用者函数的名称,而不是 10 帧之前的函数。如果没有任何方法可以做到这一点,在我看来,这是 Python 必须具备的一个特性。我的问题是:

在 Python 中获取调用者属性的 Python 编程方式是什么,并具有通用支持?对不起,如果我的问题存在无知,我愿意接受任何更正和“思想开放”。谢谢大家的回答。

【问题讨论】:

  • 我认为装饰器很适合。
  • @polku 我很想知道你将如何在装饰器中传递函数参数。如果我设置了信号处理程序,包装器是个好主意,但我认为这可能仅适用于 Linux 发行版。
  • IDK 你对装饰器有多熟悉,但你没有将函数参数传递给它。我的理解是,您想要一种可重复用于不同功能的类型检查机制,这就是我要使用的(以及自定义异常而不是打印和退出),但也许我弄错了。

标签: python function attributes callermembername


【解决方案1】:

我有一些功能可能与您的问题有关

import sys

def position(level = 0):
    """return a tuple (code, lasti, lineno) where this function is called

    If level > 0, go back up to that level in the calling stack.
    """
    frame = sys._getframe(level + 1)
    try:
        return (frame.f_code, frame.f_lasti, frame.f_lineno)
    finally:
        del frame

def line(level = 0):
    """return a tuple (lineno, filename, funcname) where this function is called

    If level > 0, go back up to that level in the calling stack.

    The filename is the name in python's co_filename member
    of code objects.
    """
    code, lasti, lineno = position(level=level+1)
    return (lineno, code.co_filename, code.co_name)

def _globals(level = 0):
    """return the globals() where this function is called

    If level > 0, go back up to that level in the calling stack.

    """
    frame = sys._getframe(level + 1)
    try:
        return frame.f_globals
    finally:
        del frame

【讨论】:

  • 感谢您的回答。据我所知,您建议使用sys._getframe(1).f_code.co_name。这让我得到了函数的名称,但我无法获得任何其他属性。这是个好主意。这个 Windows 兼容吗?
  • 试试_globals(1)[line(1)[2]].__doc__。所有这些都与操作系统无关。
  • 好的,这符合要求,而且非常整洁,因为我使用的是内置模块:f=sys._getframe(1) ; print f.f_globals[f.f_code.co_name].__doc__
  • 请参阅note about keeping references to frame。使用 try ...finally
  • 我找到了更简单的方法:getattr(f.f_locals['self'].__class__,f.f_code.co_name).__doc__
猜你喜欢
  • 2012-08-01
  • 2015-05-03
  • 2019-10-18
  • 1970-01-01
  • 1970-01-01
  • 2014-05-02
  • 2015-03-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多