Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用元类隐式地干预python中每个类的定义?_Python_Global_Metaclass - Fatal编程技术网

使用元类隐式地干预python中每个类的定义?

使用元类隐式地干预python中每个类的定义?,python,global,metaclass,Python,Global,Metaclass,我一直在学习元类,我想知道是否有可能为python中定义的每个类添加一个新属性,而不仅仅是那些显式继承自自定义元类的类 我可以使用如下自定义元类显式地添加新属性 类NewAttrMetatype: 定义、新定义、名称、基础、属性: 属性['new\u attr']='new\u thing' 返回super.\uuu new\uu cls、name、base、attrs 类Ametaclass=NewAttrMeta: ... 打印新属性 $“新事物” 但是,是否有可能对定义的每个类强制这样的更

我一直在学习元类,我想知道是否有可能为python中定义的每个类添加一个新属性,而不仅仅是那些显式继承自自定义元类的类

我可以使用如下自定义元类显式地添加新属性

类NewAttrMetatype: 定义、新定义、名称、基础、属性: 属性['new\u attr']='new\u thing' 返回super.\uuu new\uu cls、name、base、attrs 类Ametaclass=NewAttrMeta: ... 打印新属性 $“新事物” 但是,是否有可能对定义的每个类强制这样的更改,而不仅仅是那些显式继承自自定义元类的类

我想可能因为所有的类都是类型,如果我用我的自定义元类重写类型本身,那么所有的新类都可能从它继承。由于元类是类型的子类,那么以这种方式定义的所有类仍然有效

类NewAttrMetatype: 定义、新定义、名称、基础、属性: 属性['new\u attr']='new\u thing' 返回super.\uuu new\uu cls、name、base、attrs 类型=NewMagicMeta 但这仅在再次显式传入类型时有效:

类别类型: ... 打印新属性 $“新事物” B类: ... printB.new_attr $AttributeError:类型对象“A”没有属性“new\u attr” 我到底为什么要这么做?我想看看是否可以通过重写定义了任何版本的uuu getitem的每个类的uu getitem方法,在本地实现拒绝的版本。我这样做只是为了好玩,所以我会对任何见解或其他方法感兴趣,以做到越黑越好

Python不允许修改内置的声明类型。那个 意味着字典、列表、类在扩展中定义,如 从Python代码中冻结Numpy.ndarray

即使在可能的情况下,更改所有类的元类也不会更改已定义的类。所以,名单等等。。。不会有影响。不过,您可以安排您的程序,以便它可以在导入具有类定义的任何其他模块之前安装类创建挂钩,这样就可以影响用Python代码编写的类。在扩展中创建的类是在C代码中定义的,并且无论如何都不会经过元类类创建过程

类型被引用为对象的元类,所以即使您在内置中更改了类型(这是可能的),也不会自动将其用作任何人的元类。默认情况下使用它,因为它是typeobject返回的内容

综上所述,可以创建一些东西,在运行的Python程序中查找所有现有的类,并且,只要在Python中定义了类,就可以修饰一个_ugetItem__;方法(如果存在),以接受关键字参数

但是:

PEP 472中建议的对索引参数的支持需要对解析器和语言规范进行更改-只接受_getitem_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu中的关键字参数不会使[b=1]起作用,也。我们仍然需要写一个。。。\uuuu getitem\uuuuu b=1

_uuugetItem_uuuu中的索引名对于一类对象来说是非常特定的。如果没有考虑到这一点,任何类的设计都是没有意义的。如果a是一个列表,那么[fish='golden']是什么意思?如果a是一个dict呢


总而言之,如果你能想出一些在索引中传递名称是有意义的东西,那么你已经有了一个非常酷的类——然后你可以有任何方法来检索它,并使用正则括号表示a.getfish=gold,甚至,如果您将uuu call_uuu方法:afish=gold

写入全局性的monkey patch内置类和方法,则需要在内置模块uuuuu builtin_uuuuu上为Python2->导入内置;builtins.type=footinterest——但这似乎不起作用。添加导入内置;builtins.type=NewAttrMeta仍然提供相同的AttributeError:type对象“A”没有属性“new\u attr”。谢谢,非常有用。是的,我在发布PEP472后意识到需要对解析器进行更改。当然,除了新的行为外,您还需要保持旧的行为。激发这一灵感的非常酷的课程是我们的希望。