我习惯了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,但它没有帮助。我错过了什么?在
像
__contains__
这样的特殊方法只有在类上定义时才是特殊的,而不是在实例上定义的(python2中的遗留类除外,无论如何都应该而不是使用它)。在那么,你的代表团在班级层面:
实际上,我更喜欢将后者拼写为
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)中。在我是否推荐“聪明”或“魔法”解决方案?不,我不喜欢:几乎总是用简单、直截了当的方式做事情更好。但是“几乎”在这里是一个重要的词,而且很高兴手头有这样先进的“钩子”来处理罕见但并非不存在的情况,在这种情况下,它们的使用可能是有保证的。在
相关问题 更多 >
编程相关推荐