在Python中模拟membershiptest:将\uuu contains_uu正确地委派给containedobject

2024-05-29 00:11:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我习惯了Python允许一些巧妙的技巧将功能委托给其他对象。一个例子是对包含对象的委派。在

但是,当我想授权时,我没有运气,包含:

class A(object):
    def __init__(self):
       self.mydict = {}
       self.__contains__ = self.mydict.__contains__

a = A()
1 in a

我得到:

^{pr2}$

我做错了什么?当我调用一个.\uuu包含uu(1)时,一切都很顺利。我甚至试图在A中定义一个uu iter方法,使它看起来更像iterable,但它没有帮助。我错过了什么?在


Tags: 对象self功能技巧objectdefmydictclass
1条回答
网友
1楼 · 发布于 2024-05-29 00:11:06

__contains__这样的特殊方法只有在类上定义时才是特殊的,而不是在实例上定义的(python2中的遗留类除外,无论如何都应该而不是使用它)。在

那么,你的代表团在班级层面:

class A(object):
    def __init__(self):
       self.mydict = {}

    def __contains__(self, other):
       return self.mydict.__contains__(other)

实际上,我更喜欢将后者拼写为return other in self.mydict,但这是一个次要的样式问题。在

编辑:如果并且当“特殊方法的完全动态的每个实例重定向”(如提供的旧样式类)是必不可少的,那么用新样式的类来实现它并不难:您只需要将具有这种特殊需要的每个实例包装在自己的特殊类中。例如:

^{pr2}$

本质上,在对一个新的类对象重新赋值self.__class__之后(它的行为与前一个一样,但是有一个空的dict,除了这个对象之外没有其他实例,self),在一个旧样式的类中的任何地方,您将分配给self.__magicname__,而应该分配给self.__class__.__magicname__(并确保它是一个内置的或staticmethod,不是一个普通的Python函数,除非在某些不同的情况下,您确实希望它在对实例调用时接收self)。在

顺便说一句,这个BlackMagic类实例上的in运算符比以前提出的任何解决方案都要快,至少我用我通常信任的-mtimeit(直接到built-in method,而不是遵循涉及继承和描述符的常规查找路径,而是使用与继承和描述符相关的常规查找路径,来进行测量一点开销)。在

一个自动化self.__class__每实例思想的元类并不难写(它可以在生成的类的__new__方法中完成繁琐的工作,并且如果在实例上赋值,可以通过__setattr__或多个,many属性,将所有的魔法名称设置为实际分配给类)。但是,只有在对这个特性的需求非常广泛的情况下,这才是合理的(例如,将一个巨大的古代python1.5.2项目移植到现代Python,包括python3)中。在

我是否推荐“聪明”或“魔法”解决方案?不,我不喜欢:几乎总是用简单、直截了当的方式做事情更好。但是“几乎”在这里是一个重要的词,而且很高兴手头有这样先进的“钩子”来处理罕见但并非不存在的情况,在这种情况下,它们的使用可能是有保证的。在

相关问题 更多 >

    热门问题