如何获取调用方法的类?

2024-04-15

The get_calling_class函数必须通过返回调用该函数的方法的类来通过以下测试A.f method:

class A:
    def f(self): return get_calling_class()

class B(A):
    def g(self): return self.f()

class C(B):
    def h(self): return self.f()

c = C()
assert c.g() == B
assert c.h() == C

遍历堆栈应该会给出答案。
理想情况下,答案应该是在调用者的堆栈帧中。

问题是,堆栈帧只记录函数
名称(例如:“f”、“g”、“h”等)有关的任何信息
课程丢失。试图对丢失的信息进行逆向工程,
通过导航类层次结构(与
堆栈帧),并没有让我走得太远,并且变得复杂。

因此,这是一种不同的方法:
将类信息注入栈帧
(例如使用局部变量),
并从被调用的函数中读取它。

import inspect

class A:
  def f(self):
    frame = inspect.currentframe()
    callerFrame = frame.f_back
    callerLocals = callerFrame.f_locals
    return callerLocals['cls']

class B(A):
  def g(self):
    cls = B
    return self.f()
    
  def f(self):
    cls = B
    return super().f()

class C(B):
  def h(self):
    cls = C
    return super(B, self).f()
  
  def f(self):
    cls = C
    return super().f()

c = C()
assert c.h() == C
assert c.g() == B
assert c.f() == B

Related:
从检查堆栈获取完全限定方法名称 https://stackoverflow.com/questions/16589547/get-fully-qualified-method-name-from-inspect-stack


不修改子类的定义:
添加了一个“外部”装饰器来包装类方法。
(至少作为临时解决方案。)

import inspect

class Injector:
  def __init__(self, nameStr, valueStr):
    self.nameStr = nameStr
    self.valueStr = valueStr
  
  # Should inject directly in f's local scope / stack frame.
  # As is, it just adds another stack frame on top of f.
  def injectInLocals(self, f):
    def decorate(*args, **kwargs):
      exec(f'{self.nameStr} = {self.valueStr}')
      return f(*args, **kwargs)
    return decorate

class A:
  def f(self):
    frame = inspect.currentframe()
    callerDecoratorFrame = frame.f_back.f_back  # Note:twice
    callerDecoratorLocals = callerDecoratorFrame.f_locals
    return callerDecoratorLocals['cls']

class B(A):
  def g(self): return self.f()
  def f(self): return super().f()

class C(B):
  def h(self): return super(B, self).f()
  def f(self): return super().f()

bInjector = Injector('cls', B.__name__)
B.g = bInjector.injectInLocals(B.g)
B.f = bInjector.injectInLocals(B.f)

cInjector = Injector('cls', C.__name__)
C.h = cInjector.injectInLocals(C.h)
C.f = cInjector.injectInLocals(C.f)

c = C()
assert c.h() == C
assert c.g() == B
assert c.f() == B

我发现这个链接很有趣
(但没有利用这里的元类):
python 中的元类是什么 https://stackoverflow.com/questions/100003/what-are-metaclasses-in-python/6581949#6581949

也许有人甚至可以替换函数定义*,
其代码与原始代码重复的函数;
但直接在其范围内添加了当地人/信息。

*
也许在类定义完成之后;
也许在类创建期间(使用元类)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何获取调用方法的类? 的相关文章

随机推荐

  • 对链接列表进行排序

    我用 C 编写了一个基本的链表类 它有一个 Node 对象 它 显然 代表列表中的每个节点 代码中没有使用IEnumerable 但是我可以实现排序功能吗 我使用的语言是C C 中有这样的例子吗 我正在从这个工作sample http ww
  • Python,在输出中将所有浮点数打印到小数点后两位

    我需要输出 4 个不同的浮点数到小数点后两位 这就是我所拥有的 print 2f var1 kg 2f var2 lb 2f var3 gal 2f var4 l 这是非常不干净的 而且看起来很糟糕 有没有办法让输出 2f 中出现任何浮动
  • 如何在 Swift 中创建一个空数组?

    我对如何在 Swift 中创建空数组感到非常困惑 您能否向我展示创建带有一些细节的空数组的不同方法 干得好 var yourArray String 上面的方法也适用于其他类型 而不仅仅是字符串 这只是一个例子 为其添加价值 我想您最终会想
  • app.dock.hide(); 的等效项是什么?

    我目前正在开发电子托盘应用程序 对于 Mac Electron 框架具有将应用程序隐藏在 Dock 中的功能 app dock hide 我尝试在 Windows 计算机上运行此程序并收到错误 TypeError Cannot read p
  • “内部联系”是什么意思?

    标准中写道 当名称具有内部链接时 它所表示的实体可以是 由同一翻译单元中其他范围的名称引用 and 具有命名空间范围 3 3 6 的名称具有内部链接 如果它是 变量 函数或函数模板的名称 显式声明为静态 所以考虑下面的代码 include
  • s3 存储桶中的 utf-8 文件名

    是否可以使用 utf 8 编码名称 如 jpg 向 s3 添加密钥 使用 boto 上传时出现以下错误
  • Python 请求:requests.exceptions.TooManyRedirects:超过 30 个重定向

    我试图使用 python requests 库抓取此页面 import requests from lxml import etree html url http www amazon in b ref sa menu mobile ele
  • 使用 MongoDB 有效确定层次结构中记录的所有者

    我正在努力实现以下目标 选择我拥有的所有记录 其中所有权是我创建的对象或我管理的用户创建的对象 其中用户管理可以在管理用户的用户层次结构中 所有权显然很简单 可以通过与所有者相对应的简单 ID 来处理 用户管理的层次结构让我有点难以执行 而
  • 当 Net Framework 引用 Net 标准库时,无法加载文件或程序集

    我对 netstandard 非常陌生 当我想运行引用 netstandard 库的 Net Framework 控制台 调试模式时 我刚刚遇到异常 所以我后来发现 如果我将 nuget 中的 System IO Ports 安装到 Net
  • 如何在某一点切断一条线,但在最近的空间处分割

    我希望每行在 20 个字符过去后分开 但我希望它在最近的空格处分开 这样句子就只有整个单词 这是我的代码 System out println Please input a word Scanner stringScanner new Sc
  • 如何获取PAC的访问日志(代理自动配置)

    我正在使用 Chrome 我想为自己监控浏览器访问日志 我怀疑某些扩展程序在后台发送 url 等 我尝试使用 Privoxy 但它无法记录 HTTPS url 我认为 PAC 是记录原始 url 的唯一方法 我使用 PAC 几年了 但我仍然
  • 如何使用 django-pytest 跟踪 Django 重定向?

    在设置一个档案索引视图 https docs djangoproject com en 2 0 ref class based views generic date based django views generic dates Arch
  • 文件包含\u00c2\u00a0,转换为字符

    我有一个 JSON 文件 其中包含这样的文本 wax and voila u00c2 u00a0At the moment you can t use our 我的简单问题是如何将这些 u 代码转换 而不是删除 为空格 撇号等 Input
  • ANTLR 语法也可以识别数字键和整数

    我正在尝试创建一个 ANTLR 语法来解析可选地具有重复计数的键序列 例如 a b c r5 表示 重复键 a b 和 c 五次 我有语法工作KEYS a z A Z 但是当我尝试添加数字键时KEYS a z A Z 0 9 输入表达式如
  • URL 中的 HTML5 不明确的 & 符号

    The W3C 验证器 http validator w3 org 在我的一些 URL 中引发了有关 符号的错误 例如 根据HTML5 规范 http www whatwg org specs web apps current work m
  • 如何计算给定日期Android的周数

    我正在尝试从给定日期获取当前周数 即 如果我输入日期为 01 03 2013 那么我应该得到周数 9 请帮助我找到解决方案 Thanks 阿布舍克 您可以为该日期创建一个 Calendar 对象并通过以下方式获取星期 calendar ge
  • if 语句在循环内部还是外部?

    如果我这样做会更好吗 foreach my item array if bool code else code or if bool foreach my item array else foreach my item array 我会离开
  • 有关 URLEncoder 和 URLDecoder 的一些问题?

    我已经浏览了 URLEncoder 和 URLDecoder 的 javadocs 然后就更加好奇了 将服务器视为 tomcat 在任何 Web 应用程序中 每当我们提交时 表单 服务器将表单字段转换为 urlencoded 字段 当我们执
  • 邮件与发送邮件

    我正在 Codeigniter 中使用 Email 类 并且在manual http codeigniter com user guide libraries email html我看到有 3 个协议可以使用 mail sendmail 和
  • 如何获取调用方法的类?

    The get calling class函数必须通过返回调用该函数的方法的类来通过以下测试A f method class A def f self return get calling class class B A def g sel