检测类是否被定义为声明式或函数式 - 可能吗?

2023-11-22

这是一个以声明方式创建的简单类:

class Person:
    def say_hello(self):
        print("hello")

这是一个类似的类,但它是通过手动调用元类来定义的:

def say_hello(self):
    print("sayolala")

say_hello.__qualname__ = 'Person.say_hello'

TalentedPerson = type('Person', (), {'say_hello': say_hello})

我很想知道它们是否无法区分。是否有可能从类对象本身检测到这种差异?

>>> def was_defined_declaratively(cls):
...     # dragons
...
>>> was_defined_declaratively(Person)
True
>>> was_defined_declaratively(TalentedPerson)
False

这根本不重要。即使我们挖掘更多不同的属性,也应该可以将这些属性注入到动态创建的类中。

现在,即使没有源文件(从中,诸如inspect.getsource可以按自己的方式进行,但请参见下文),类体语句应该有一个在某个时刻运行的相应“代码”对象。动态创建的类不会有代码体(但如果不是调用type(...)你打电话types.new_class您也可以为动态类拥有一个自定义代码对象 - 因此,对于我的第一句话:应该可以使这两个类无法区分。

至于在不依赖源文件的情况下定位代码对象(除了通过inspect.getsource可以通过方法达到.__code__注释的属性co_filename and co_fistlineno(我想人们必须解析该文件并找到class上面的声明co_firstlineno then)

是的,就是这样: 给定一个模块,您可以使用module.__loader__.get_code('full.path.tomodule')- 这将返回一个 code_object。这个对象有一个co_constsattribute 是一个包含在该模块中编译的所有常量的序列 - 其中包括类体本身的代码对象。这些也具有行号和嵌套声明方法的代码对象。

因此,一个简单的实现可能是:

import sys, types

def was_defined_declarative(cls):
    module_name = cls.__module__
    module = sys.modules[module_name]
    module_code = module.__loader__.get_code(module_name)
    return any(
        code_obj.co_name == cls.__name__ 
        for code_obj in module_code.co_consts 
        if isinstance(code_obj, types.CodeType)
    )

对于简单的情况。如果您必须检查类主体是否位于另一个函数内部,或者嵌套在另一个类主体内部,则必须在所有代码对象中进行递归搜索.co_consts文件中的属性> 如果您发现检查超出范围的任何属性是否更安全,则同样如此cls.__name__断言你选对了课程。

再说一遍,虽然这适用于“行为良好”的类,但如果需要,可以动态创建所有这些属性 - 但这最终需要替换模块中的代码对象sys.__modules__- 它开始变得比简单地提供一个更麻烦__qualname__到方法。

update此版本比较候选类的所有方法内定义的所有字符串。这将适用于给定的示例类 - 通过比较其他类成员(例如类属性)和其他方法属性(例如变量名,甚至可能是字节码)可以实现更高的准确性。 (由于某种原因,模块代码对象和类主体中方法的代码对象是不同的实例,尽管 code_objects 应该是不可变的)。

我将保留上面的实现,它只比较类名,因为它应该更好地理解正在发生的事情。

def was_defined_declarative(cls):
    module_name = cls.__module__
    module = sys.modules[module_name]
    module_code = module.__loader__.get_code(module_name)
    cls_methods = set(obj for obj in cls.__dict__.values() if isinstance(obj, types.FunctionType))
    cls_meth_strings = [string for method in cls_methods for string in method.__code__.co_consts  if isinstance(string, str)] 

    for candidate_code_obj in module_code.co_consts:
        if not isinstance(candidate_code_obj, types.CodeType):
            continue
        if candidate_code_obj.co_name != cls.__name__:
            continue
        candidate_meth_strings = [string  for method_code in candidate_code_obj.co_consts if isinstance(method_code, types.CodeType) for string in method_code.co_consts if isinstance(string, str)]
        if candidate_meth_strings == cls_meth_strings:
            return True
    return False
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

检测类是否被定义为声明式或函数式 - 可能吗? 的相关文章

  • 没有名为 crypto.cipher 的模块

    我现在正在尝试加密一段时间 我最近得到了这个基于 python 的密码器 名为PythonCrypter https github com jbertman PythonCrypter 我对 Python 相当陌生 当我尝试通过终端打开 C
  • Python 中的 Lanczos 插值与 2D 图像

    我尝试重新缩放 2D 图像 灰度 图像大小为 256x256 所需输出为 224x224 像素值范围从 0 到 1300 我尝试了两种使用 Lanczos 插值来重新调整它们的方法 首先使用PIL图像 import numpy as np
  • 使 django 服务器可以在 LAN 中访问

    我已经安装了Django服务器 可以如下访问 http localhost 8000 get sms http 127 0 0 1 8000 get sms 假设我的IP是x x x x 当我这样做时 从同一网络下的另一台电脑 my ip
  • 如何在flask中使用g.user全局

    据我了解 Flask 中的 g 变量 它应该为我提供一个全局位置来存储数据 例如登录后保存当前用户 它是否正确 我希望我的导航在登录后在整个网站上显示我的用户名 我的观点包含 from Flask import g among other
  • 使用带有关键字参数的 map() 函数

    这是我尝试使用的循环map功能于 volume ids 1 2 3 4 5 ip 172 12 13 122 for volume id in volume ids my function volume id ip ip 我有办法做到这一点
  • 如何使用Conda下载python包并随后离线安装?

    我知道通过 pip 我可以使用以下命令下载 Python 包 但 pip install 破坏了我的内部包依赖关系 当我做 pip download
  • 从字符串中删除识别的日期

    作为输入 我有几个包含不同格式日期的字符串 例如 彼得在16 45 我的生日是1990年7月8日 On 7 月 11 日星期六我会回家 I use dateutil parser parse识别字符串中的日期 在下一步中 我想从字符串中删除
  • python 相当于 R 中的 get() (= 使用字符串检索符号的值)

    在 R 中 get s 函数检索名称存储在字符变量 向量 中的符号的值s e g X lt 10 r lt XVI s lt substr r 1 1 X get s 10 取罗马数字的第一个符号r并将其转换为其等效整数 尽管花了一些时间翻
  • 是否可以忽略一行的pyright检查?

    我需要忽略一行的pyright 检查 有什么特别的评论吗 def create slog group SLogGroup data Optional dict None SLog insert one SLog group group da
  • 使用 Tkinter 显示 numpy 数组中的图像

    我对 Python 缺乏经验 第一次使用 Tkinter 制作一个 UI 显示我的数字分类程序与 mnist 数据集的结果 当图像来自 numpy 数组而不是我的 PC 上的文件路径时 我有一个关于在 Tkinter 中显示图像的问题 我为
  • Python pickle:腌制对象不等于源对象

    我认为这是预期的行为 但想检查一下 也许找出原因 因为我所做的研究结果是空白 我有一个函数可以提取数据 创建自定义类的新实例 然后将其附加到列表中 该类仅包含变量 然后 我使用协议 2 作为二进制文件将该列表腌制到文件中 稍后我重新运行脚本
  • 如何在ipywidget按钮中显示全文?

    我正在创建一个ipywidget带有一些文本的按钮 但按钮中未显示全文 我使用的代码如下 import ipywidgets as widgets from IPython display import display button wid
  • python获取上传/下载速度

    我想在我的计算机上监控上传和下载速度 一个名为 conky 的程序已经在 conky conf 中执行了以下操作 Connection quality alignr wireless link qual perc wlan0 downspe
  • 使用 \r 并打印一些文本后如何清除控制台中的一行?

    对于我当前的项目 有一些代码很慢并且我无法使其更快 为了获得一些关于已完成 必须完成多少的反馈 我创建了一个进度片段 您可以在下面看到 当你看到最后一行时 sys stdout write r100 80 n I use 80覆盖最终剩余的
  • Pandas:merge_asof() 对多行求和/不重复

    我正在处理两个数据集 每个数据集具有不同的关联日期 我想合并它们 但因为日期不完全匹配 我相信merge asof 是最好的方法 然而 有两件事发生merge asof 不理想的 数字重复 数字丢失 以下代码是一个示例 df a pd Da
  • 如何计算 pandas 数据帧上的连续有序值

    我试图从给定的数据帧中获取连续 0 值的最大计数 其中包含来自 pandas 数据帧的 id date value 列 如下所示 id date value 354 2019 03 01 0 354 2019 03 02 0 354 201
  • 发送用户注册密码,django-allauth

    我在 django 应用程序上使用 django alluth 进行身份验证 注册 我需要创建一个自定义注册表单 其中只有一个字段 电子邮件 密码将在服务器上生成 这是我创建的表格 from django import forms from
  • Python 类继承 - 诡异的动作

    我观察到类继承有一个奇怪的效果 对于我正在处理的项目 我正在创建一个类来充当另一个模块的类的包装器 我正在使用第 3 方 aeidon 模块 用于操作字幕文件 但问题可能不太具体 以下是您通常如何使用该模块 project aeidon P
  • 导入错误:没有名为 site 的模块 - mac

    我已经有这个问题几个月了 每次我想获取一个新的 python 包并使用它时 我都会在终端中收到此错误 ImportError No module named site 我不知道为什么会出现这个错误 实际上 我无法使用任何新软件包 因为每次我
  • 如何使用 Pycharm 安装 tkinter? [复制]

    这个问题在这里已经有答案了 I used sudo apt get install python3 6 tk而且效果很好 如果我在终端中打开 python Tkinter 就可以工作 但我无法将其安装在我的 Pycharm 项目上 pip

随机推荐

  • Java中字符串到二进制输出

    我想从字符串中获取二进制 011001 但我得到了 B addbf1 必须有一个简单的转换来做到这一点 但我没有看到它 public static String toBin String info byte infoBin null try
  • 可以在同一台机器上安装两个不同版本的Android Studio吗?

    我只有一台机器 Mac OS 10 9 5 我目前拥有 Android Studio 的金丝雀版本 但遇到了一些错误 所以我也想安装稳定版的Android Studio 有人这样做过吗 在同一台机器上安装多个版本是否有问题 是的 但您必须更
  • 如何为 binned_statistic 制作用户定义的函数

    我正在使用 scipy stats 包沿轴进行统计 但我在使用百分位统计时遇到问题binned statistic 我概括了下面的代码 我尝试在一系列 x bin 中获取具有 x y 值的数据集的第 10 个百分位数 但它失败了 我当然可以
  • Java 7 Update 25 的 rmi 线程中的 AppContext 为 null

    我们最近从 Update 21 更新到 Java 7 Update 25 并且现在在从 rmi 线程调用 SwingUtilities isEventDispatchThread 时遇到空指针异常 因为 AppContext getAppC
  • 7 段显示 OCR

    我正在使用 Tesseract 一个 OCR 库 构建一个 iOS 应用程序 拍照并在其上运行 OCR 并且它可以很好地处理书写良好的数字和字符 使用常用字体 我遇到的问题是 如果我在 7 段显示器上尝试 它会给出非常非常糟糕的结果 所以我
  • zend 文本元素中的占位符文本

    我正在开发一个 Zend 表单应用程序 其中我的表单包含带有水印的文本框 我们可以通过以下代码在 HTML 中实现这一点
  • 如何在wpf文本块中显示一行文本

    我是 wpf 的新手 我想在 wpf 文本块中的一行中显示文本 例如
  • .net 的替代 Oracle 驱动程序

    我必须用 C 开发一个工具来从 Oracle DB 检索一些数据 由于我们的 IT 支持人员在安装 Oracle 客户端时遇到了一些问题 因此我希望能够在不安装客户端的情况下连接到数据库 这个想法是只安装 也许注册 一个额外的库与应用程序一
  • 如何在 TypeORM 中查询数组

    我想创建用户权限管理 我将 TypeORM 与 PostgreSQL 结合使用 这是用户实体内权限的列定义 Column type text array true permissions UserPermission 这是UserPermi
  • 从 Bash 中的文件中读取行并将单词解析为 mailx 参数的变量

    我有一个 bash 脚本 它从 4 列 无标题 的文本文件中读取行 行数最多可以为 4 行或更少 每行中的单词由空格字符分隔 email protected email protected email protected Sub1 Mail
  • PyCharm IPython 控制台中的嵌入式图表

    有没有办法允许在 PyCharm 中激活的 IPython 控制台中嵌入 Matplotlib 图表 我正在寻找与 IPython 的 QT 控制台版本可以完成的类似行为 即ipython qtconsole matplotlib inli
  • 将自定义 HTML Helper 添加到 MVC 项目

    我一直在浏览网页 试图找到一个很好的示例 教程 详细说明如何为我的 MVC 3 Razor 应用程序创建和使用我自己的自定义 HTML 帮助程序 我发现了这个示例 教程 如下所示 在 ASP NET MVC 3 中添加您自己的 HtmlHe
  • 哪些 SDK 可用于创建 iPad/iPhone 离线地图应用程序?

    我们正在使用 Cloudmade SDK 开发适用于 iPad 的离线城市地图应用程序 我很好奇 是否还有其他可用于离线应用程序的 SDK 对我来说更好的解决方案是 1 生成您自己的地图TileMill从 Mapbox 导出 然后导出为 M
  • 在 Angular 6 项目中使用 jquery 库好吗?

    我正在创建一个 Angular 6 项目 该项目之前使用 jquery 开发 现在我陷入困境 好像在 Angular 6 中使用 jquery 很好 或者我应该删除所有 jquery 代码并将其替换为 Angular 不 这不是一个好主意
  • 初始化器列表返回的生命周期扩展

    所以我有一个 lambda 其返回类型是auto我在阵列支持方面遇到问题initializer list在这里被摧毁 const auto foo const auto a const auto b const auto c return
  • Django:i18n - 更改语言

    我安装了 model translation rosetta locale url 但改变语言不起作用 我的设置 py LANGUAGE CODE ru MODELTRANSLATION TRANSLATION REGISTRY proje
  • 在 Delphi 中使用 ADOConnection 查看“打印”语句的输出

    我的一些 MS SQL 存储过程使用 print 命令生成消息 在我的 Delphi 2007 应用程序中 使用 TADOConnection 连接到 MS SQL 如何查看这些 打印 命令的输出 关键要求 1 我不能多次运行查询 它可能正
  • 在 package.json 中使用“homepage”,不会弄乱 localhost 的路径

    这个问题实际上直接来自我的answer关于之前的问题 我添加了一个 homepage to my package json因为它是我在 Github Pages 上托管的 React 应用程序 的输出npm run build说 build
  • 使用 Tailwind CSS 基于类的暗模式防止 Next.js 12 中的页面闪烁

    在 Tailwind CSS 中使用 Next js v12 中基于类的深色模式时 如何防止页面闪烁 而不使用任何 3rd 方 pkg 例如 next themes 我看过 本次问答如何修复 NextJS 中的深色模式背景颜色闪烁 虽然它在
  • 检测类是否被定义为声明式或函数式 - 可能吗?

    这是一个以声明方式创建的简单类 class Person def say hello self print hello 这是一个类似的类 但它是通过手动调用元类来定义的 def say hello self print sayolala s