如何在 Python 中伪造/代理一个类

2024-04-02

我编写了一些包装器,其中有另一个对象作为属性。该包装器代理(转发)所有属性请求__getattr__ and __setattr__到存储为属性的对象。我还需要为我的代理提供什么,以便包装器在通常情况下看起来像包装的类?

我想我可能需要修复诸如继承之类的问题__repr__, ... 我还需要注意什么以及如何修复继承以便instanceof() works?

编辑:我尝试制作函数代理,但是由于我不完全理解配方,它失败了:(

setattr_=object.__setattr__
getattr_=object.__getattribute__

class Proxy(object):
    __slots__=["_func", "_params", "_kwargs", "_obj", "_loaded", "__weakref__"]
    def __init__(self, func, *params, **kwargs):
        setattr_(self, "_func", func)
        setattr_(self, "_params", params)
        setattr_(self, "_kwargs", kwargs)

        setattr_(self, "_obj", None)
        setattr_(self, "_loaded", False)

    def _get_obj(self):
        if getattr_(self, "_loaded")==False:
            print("Loading")
            setattr_(self, "_obj", getattr_(self, "_func")(*getattr_(self, "_params"), **getattr_(self, "_kwargs")))
            setattr_(self, "_loaded", True)

        return getattr_(self, "_obj")
    #
    # proxying (special cases)
    #
    def __getattribute__(self, name):
        return getattr(getattr_(self, "_get_obj")(), name)
    def __delattr__(self, name):
        delattr(getattr_(self, "_get_obj")(), name)
    def __setattr__(self, name, value):
        setattr(getattr_(self, "_get_obj")(), name, value)

    def __nonzero__(self):
        return bool(getattr_(self, "_get_obj")())
    def __str__(self):
        return str(getattr_(self, "_get_obj")())
    def __repr__(self):
        return repr(getattr_(self, "_get_obj")())

    #
    # factories
    #
    _special_names=[
        '__abs__', '__add__', '__and__', '__call__', '__cmp__', '__coerce__',
        '__contains__', '__delitem__', '__delslice__', '__div__', '__divmod__',
        '__eq__', '__float__', '__floordiv__', '__ge__', '__getitem__',
        '__getslice__', '__gt__', '__hash__', '__hex__', '__iadd__', '__iand__',
        '__idiv__', '__idivmod__', '__ifloordiv__', '__ilshift__', '__imod__',
        '__imul__', '__int__', '__invert__', '__ior__', '__ipow__', '__irshift__',
        '__isub__', '__iter__', '__itruediv__', '__ixor__', '__le__', '__len__',
        '__long__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__',
        '__neg__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__',
        '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__',
        '__repr__', '__reversed__', '__rfloorfiv__', '__rlshift__', '__rmod__',
        '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__',
        '__rtruediv__', '__rxor__', '__setitem__', '__setslice__', '__sub__',
        '__truediv__', '__xor__', 'next',
    ]

    @classmethod
    def _create_class_proxy(cls, theclass):
        """creates a proxy for the given class"""

        def make_method(name):
            def method(self, *args, **kw):
                return getattr(getattr_(self, "_get_obj")(), name)(*args, **kw)
            return method

        namespace={}
        for name in cls._special_names:
            if hasattr(theclass, name):
                namespace[name]=make_method(name)
        return type("%s(%s)"%(cls.__name__, theclass.__name__), (cls,), namespace)

    def __new__(cls, obj, *args, **kwargs):
        """
        creates an proxy instance referencing `obj`. (obj, *args, **kwargs) are
        passed to this class' __init__, so deriving classes can define an 
        __init__ method of their own.
        note: _class_proxy_cache is unique per deriving class (each deriving
        class must hold its own cache)
        """
        try:
            cache=cls.__dict__["_class_proxy_cache"]
        except KeyError:
            cls._class_proxy_cache=cache={}
        try:
            theclass=cache[obj.__class__]
        except KeyError:
            cache[obj.__class__]=theclass=cls._create_class_proxy(obj.__class__)
        ins=object.__new__(theclass)
        theclass.__init__(ins, obj, *args, **kwargs)
        return ins

if __name__=='__main__':
    def t(x, y):
        print("Running t")
        return x+y

    a=Proxy(t, "a", "b")
    print("Go")
    print(a+"c")

此方法很好地解决了这个问题:

对象代理(Python 配方) https://web.archive.org/web/20220819152103/http://code.activestate.com/recipes/496741-object-proxying/

您必须遵循的总体思想是,类上的大多数方法都是通过某种组合来访问的__getattr__ and __getattribute__要么在类本身上,要么在它的元类上,但这不适用于Python特殊方法,即以双下划线开头和结尾的方法,为了找到这些方法,它们必须是实际类上的实际方法,没有属性代理是可能的。

您必须提供哪些方法显然取决于代理类本身提供的哪些方法。您需要提供的特殊方法isinstance()__instancecheck__ and __subclasscheck__ http://docs.python.org/reference/datamodel.html#customizing-instance-and-subclass-checks方法。为了repr()为了工作,您还必须定义一个适当的__repr__()关于代理类本身。

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

如何在 Python 中伪造/代理一个类 的相关文章

随机推荐

  • 将 MaxMind java 类与 ColdFusion 结合使用

    我正在尝试将 MaxMind java 库与 ColdFusion 一起使用 我开始在 MaxMind 官方网站上转换此示例代码 A File object pointing to your GeoIP2 or GeoLite2 datab
  • Laravel 基本身份验证

    我想用basic auth对于我的网页 但身份验证不起作用 路线 php admin 验证 Route get admin array before gt auth basic function return Top secret crea
  • 缓存图像并显示

    您好 我面临一个特殊问题 我需要下载图像并将其显示到ListView对应他们特定的TextView s 我的代码成功显示了TextView s我需要显示 但我不知道如何在我的文本视图旁边显示所有这些不同的图像ListView 在经历了SO中
  • 地理位置和半正矢公式

    我正在尝试创建一个基本的 Web 应用程序 用于检测用户的地理位置 查询 mySQL 数据库并返回 5 公里内的所有公交车站 包括经度和纬度的 GTFS 提要已插入到 mySQL 数据库中 我找到了一个示例 HTML 页面 它提供了访问 W
  • 通过 XML 和 Java 代码使用 OnClickListener 接口有何不同? [复制]

    这个问题在这里已经有答案了 可能的重复 OnClick 事件和 OnClickListener 之间的区别 https stackoverflow com questions 7453299 difference between oncli
  • 如何在 Quarkus 中启用 Jaeger JDBC 跟踪

    我如何启用Jaeger jdbc追踪Quarkus 我已经按照Quarkus指南Opentracing并且没有看到任何有关此的信息 我在用着Quarkusv0 21 2 具有以下扩展 quarkus smallrye opentracing
  • 为什么Java类的首字母要大写? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 为什么我出现致命错误:在非对象上调用成员函数prepare()?

    我问了一个有关 PDO 错误的问题 here https stackoverflow com questions 25135353 i dont understand why ive statementexecute error 25135
  • 在iOS中,使用ARC,将所有ivars和属性设置为nil,并在viewDidUnload中释放上下文、图像、颜色空间是否足够?

    对于使用 ARC 的 iOS 应用程序 我们通常会在以下位置发布这些应用程序吗 viewDidUnload 将所有实例变量设置为nil 将所有属性设置为nil 使用释放任何上下文CGContextRelease CG图像与CGImageRe
  • 单击“通知”未启动预期活动?

    我在我的应用程序中使用 GCM 并在收到 GCM 消息时使用 NotificationManager 创建通知 到目前为止 一切正常 GCM 消息在通知区域中正确显示 但是当我单击通知时 它应该启动一个活动我的应用程序将显示未发生的消息详细
  • Eclipse 特定颜色随新 Ubuntu 主题而变化

    在使用新的 Ubuntu 10 10 深色主题的 Eclipse 中 除了一种颜色之外的所有颜色都是一个问题 我只想改变这一点 而不是主题 这是当项目被选中时 Eclipse 在列表 资源管理器 开放资源 中使用的背景 颜色pre已选择 所
  • Android:避免在 TextView 字符串部分中断行[重复]

    这个问题在这里已经有答案了 我想避免在字符串的特定部分断行 假设我们有这个字符串 Speed m s 理想的情况是根本不跳转并将完整的字符串放在一行中 或者如果需要跳转 则以这种方式 Speed m s 我想避免的是这样的事情 Speed
  • 更快的 memcpy 替代品?

    我有一个正在执行 memcpy 的函数 但它占用了大量的周期 有没有比使用 memcpy 移动一块内存更快的替代 方法 memcpy可能是在内存中复制字节的最快方法 如果你需要更快的东西 尝试找出一种方法not复制周围的东西 例如仅交换指针
  • 为什么我们不能在 C# 中进行 IntPtr 和 UIntPtr 算术?

    这是一个看似简单的问题 鉴于本机大小的整数最适合算术 为什么 C 或任何其他 NET 语言 不支持本机大小的算术IntPtr and UIntPtr 理想情况下 您可以编写如下代码 for IntPtr i 1 i lt arr Lengt
  • Hibernate/Spring:即使在 Service 方法上使用 @Transactional,会话在检索子集合之前仍然关闭

    Spring Hibernate 专家您好 在这样的时候 我希望你成为我最好的朋友 我正在使用 hibernate 3 6 1 开发一个项目 使用会话和 spring 3 0 5 实现最终的 JPA 使用 maven 发布 所以使用 mav
  • 在 Mac 上获取桌面背景

    如何获取 Mac 上的当前壁纸 只需向我指出一个 API 函数 这样我就可以通过 Google 搜索更多信息 编辑 我想我找到了 NSUserDefaults standardUserDefaults 提到http lists apple
  • 是否可以在未安装 Xcode 的 Mac 上运行 iOS 模拟器?

    有几个与该主题相关的问题 但具体到细节时却没有完全相同的问题 我们希望在 MacBook 上使用 iOS 模拟器而不安装 XCode 的其余部分 它是一台内部笔记本电脑 供员工使用 但不供工程师使用 我们已经知道如何在不需要源代码和编译的情
  • 在 Roslyn 诊断分析器中检测隐式转换

    我想创建一个 Roslyn 诊断分析器来查找隐式转换 特别是如下构造 DateTimeOffset v new DateTime 这意味着我要么必须检测隐式转换 要么找到对DateTimeOffset op Implicit DateTim
  • 除了导航到另一个视图之外,NavigationLink 是否还可以执行其他操作?

    我正在尝试创建一个按钮 它不仅可以导航到另一个视图 而且可以同时运行一个函数 我尝试将 NavigationLink 和按钮嵌入到堆栈中 但我只能单击按钮 ZStack NavigationLink destination TradeVie
  • 如何在 Python 中伪造/代理一个类

    我编写了一些包装器 其中有另一个对象作为属性 该包装器代理 转发 所有属性请求 getattr and setattr 到存储为属性的对象 我还需要为我的代理提供什么 以便包装器在通常情况下看起来像包装的类 我想我可能需要修复诸如继承之类的