Python PyObject类是否有一个实现,允许您正确重写magic方法?

Python PyObject类是否有一个实现,允许您正确重写magic方法?,python,class,oop,cpython,metaclass,Python,Class,Oop,Cpython,Metaclass,因此,我在一本书中读到,如果您想从内置类型(如list、dict或str)进行扩展,并想覆盖magic方法,那么应该分别使用collections模块中的UserList、UserDict和UserString。显然,这是因为基类是在CPython中实现的,在CPython中,这些方法不相互调用,因此重写它们不会产生任何不必要的影响 我想知道是否与UserList类等类似,存在一个可用于从object类“正确”扩展的类。我查看了PyObject,发现了,以及,但是我既不想用C扩展,也不想说它。我

因此,我在一本书中读到,如果您想从内置类型(如list、dict或str)进行扩展,并想覆盖magic方法,那么应该分别使用collections模块中的UserList、UserDict和UserString。显然,这是因为基类是在CPython中实现的,在CPython中,这些方法不相互调用,因此重写它们不会产生任何不必要的影响

我想知道是否与UserList类等类似,存在一个可用于从object类“正确”扩展的类。我查看了PyObject,发现了,以及,但是我既不想用C扩展,也不想说它。我在“收藏”模块或其他任何地方都找不到任何内容


我问这个问题的原因是因为我之前的一个问题,我有一种预感,我的方法不起作用的原因与我之前概述的相同。

如评论中所述-没有这样的事情,也没有必要这样做-object中的所有魔法方法都可以被覆盖,并且可以正常工作

MisterMiyagi在评论中解释说,字典、列表和其他集合的情况是,例如,dict的get不会使用u_getitem_u________________________________________。正确解决这一问题的类是collections.abc模块中定义的类,这些类允许用户使用最少的重用代码创建完全工作的映射、序列和集

现在,如果您想让其中一个神奇的方法在一个对象的类上工作,而不是在该类的实例上工作,那么您必须在该类的类(即元类)中实现这些方法

这与超类大不相同——超类定义子类继承的方法和属性,这些方法和属性将在子类中可用。但是类上的魔术方法只影响实例,而不影响类本身,除了uuu init_子类uuuu,当然还有uuu new_uuuuuuuu,可以将其更改为执行创建新实例以外的其他操作

元类控制类如何使用uuu new_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu和uuuuuuuuuuuuuuuuuuuuuuuuuu,与它们在类与普通实例的关系中的工作相比。如果在元类上实现uuu添加uuu、uuuu获取项uuu、uuuuu len uu,所有这些都将适用于使用该元类创建的类

如果您不想在元类本身中为类编写神奇的方法,那么可以做的是创建一个元类,该元类将在被调用时自动创建另一个动态元类,并将dunder方法复制到该类。但在任何严肃的应用程序中,很难将其视为一种健康的设计——将神奇的方法应用到类中已经有点过头了——尽管在某些情况下这是方便的

因此,例如,如果您希望一个类有一个允许您检索该类的所有实例的_geitem uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

类InstanceRegistertype: 定义初始化cls,名称,基,命名空间,**kw: super.\uuuu init\uuuu名称、基、命名空间,**kw cls._实例=[] 原始\u新=cls.\u新__ def新包装器CLS,*参数,**千瓦: 如果原始\u新建为对象。\u新建\u: 实例=原始\新CLS 其他: 实例=original_newcls,*args,**kw cls._instances.appendinstance 返回实例 cls.\uuuuu新的\uuuuu=新的包装器 def____________cls: 返回lencls.\u实例 def _获取项目_cls,项目: 返回cls.\u实例[项目] 这将起作用,就像在这个互动的会议中所看到的:

在[26]中:类Ametaclass=InstanceRegister:pass 在[27]中:a=a 在[28]中:莉娜 Out[28]:1 在[29]中,A[0]是一个 Out[29]:对
你能澄清一下你想做什么吗?UserList的情况与链接问题完全不同。内置对象(如list)的方法不会调用同一对象(如list)的其他方法。_iter__;不使用覆盖的列表。_getitem__;关于子类是否应该这样做以及以什么顺序这样做是有争议的。这并不意味着您不能覆盖特殊方法。类“\uuu getitem\uuu”是一个enti
依赖与类'class'又名元类_uGetItem_uuuuu'分开的东西,它们需要被单独覆盖。对于你的最后一个问题,你需要元类…对于这个问题,对象使用类型。所以你也可以使用类型谢谢你的评论@MisterMiyagi@vks!不过,我很难理解这一点。你是说元类和父类不一样吗?是的,父/基类和元类是两个不同的东西。父/基类满足issubclassmy_class,base_class–类是其基类的变体。元类是类的类,也就是说,isinstancemy_类,meta_类。一个类是它的元类的一个实例。我不太确定你所说的UserObject到底是什么意思,但是没有任何东西可以接近。abc.abc可能是相关的,尽管它有不同的用途。请注意,您可以创建自己的UserObject,就像您可以创建自己的UserList一样。