Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.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_Metaprogramming_Design Patterns_Factory_Metaclass - Fatal编程技术网

有人使用Python/其他语言中的元类/元类吗?

有人使用Python/其他语言中的元类/元类吗?,python,metaprogramming,design-patterns,factory,metaclass,Python,Metaprogramming,Design Patterns,Factory,Metaclass,我最近在python中发现了元类 基本上,python中的元类是创建类的类。有很多有用的理由可以解释为什么要这样做——例如,任何类型的类初始化。在工厂中注册类、复杂的属性验证、改变继承的工作方式等等。所有这些不仅是可能的,而且很简单 但在python中,元类也是普通类。因此,我开始怀疑抽象是否可以有效地提高,在我看来,它可以而且: 元类对应于或实现模式中的角色(如在GOF模式语言中) 元元类就是模式本身(如果我们允许它创建表示抽象角色的类元组,而不仅仅是单个类) 元类是一个模式工厂,它对应于G

我最近在python中发现了元类

基本上,python中的元类是创建类的类。有很多有用的理由可以解释为什么要这样做——例如,任何类型的类初始化。在工厂中注册类、复杂的属性验证、改变继承的工作方式等等。所有这些不仅是可能的,而且很简单

但在python中,元类也是普通类。因此,我开始怀疑抽象是否可以有效地提高,在我看来,它可以而且:

  • 元类对应于或实现模式中的角色(如在GOF模式语言中)
  • 元元类就是模式本身(如果我们允许它创建表示抽象角色的类元组,而不仅仅是单个类)
  • 元类是一个模式工厂,它对应于GOF模式分组,例如创造性、结构性、行为性。一个工厂,您可以在其中描述某类问题的案例,它将为您提供一组解决该问题的类
  • 一个元类(据我所知)是一个模式工厂,一个可以描述问题类型的工厂,它会给你一个模式工厂
我在网上找到了一些关于这方面的资料,但大部分都不是很有用。一个问题是不同的语言对元类的定义略有不同

有没有其他人在python/其他地方使用过这样的元类,或者在野外见过这样的元类,或者考虑过这样的元类?其他语言中的类比词是什么?例如C++中模板递归的深度有多大?
我很想进一步研究它。

回答你的问题:不

欢迎进一步研究

但是,请注意,您已经将设计模式(这只是想法)与代码(这是一种实现)混为一谈

好的代码通常反映了许多互锁的设计模式。没有一种简单的方法可以将其正式化。您所能做的最好是一幅漂亮的图片、编写良好的docstring和反映各种设计模式的方法名

还要注意,元类是一个类。这是一个循环。没有更高层次的抽象。在这一点上,这只是意图。元类的概念没有太大意义——它是一个用于元类的元类,这很愚蠢,但在技术上是可能的。然而,这只是一门课


编辑

“创建元类的类真的那么愚蠢吗?它们的实用程序是如何突然耗尽的?”

创建类的类很好。差不多就是这样。目标类是元类、抽象超类或具体类这一事实并不重要。元类构成类。他们可能会创建其他元类,这很奇怪,但他们仍然只是创建类的元类

实用程序“突然”用完了,因为在一个元类中没有实际需要(甚至可以编写)的东西来生成另一个元类。这并不是说它“突然”变得愚蠢。这是因为那里没有什么有用的东西

当我播种时,请随意研究它。例如,实际编写一个构建另一个元类的元类。玩得高兴那里可能有一些有用的东西


面向对象的要点是编写类定义,对真实世界的实体进行建模。因此,元类有时可以方便地定义几个相关类的交叉方面。(这是一种进行面向方面编程的方法。)这就是元类真正能做的;这是一个存放一些函数的地方,比如
\uuuuu new\uuuuuu()
,它们不是类本身的适当部分。

这让我想起了一些人似乎一直在追求的“模式的通用实现”。比如一个可以创建任何对象()的工厂,或者是一个通用的依赖注入框架,它的管理要比简单地编写实际执行某些操作的代码复杂得多

在管理Zend框架项目时,我不得不与那些专注于抽象的人打交道。我拒绝了一大堆创建组件的提议,这些组件什么都不做,它们只是GoF模式的神奇实现,好像模式本身就是一个目标,而不是实现目标的手段

对于抽象,存在一个收益递减的点。一些抽象很好,但最终您需要编写一些有用的代码


否则它只是。

Smalltalk中的课堂系统是一个值得研究的有趣的系统。在Smalltalk中,一切都是一个对象,每个对象都有一个类。这并不意味着层次结构是无限的。如果我没记错的话,它是这样的:

5->Integer->Integer类->元类->元类->元类->。。。(it循环)


其中“->”表示“是”

的一个实例。在2007年的编程语言史会议上,Simon Peyton Jones评论说Haskell允许使用类型类进行元编程,但实际上它一直都是乌龟。您可以在Haskell中使用meta etc程序,但他从未听说过有人使用超过3个级别的间接寻址

盖伊·斯蒂尔指出,在Lisp和Scheme中也是一样的。您可以使用backtick和evals进行元编程(您可以将backtick想象为Python lambda),但他从未见过使用超过3个backtick

想必他们看到的代码比你或我看到的都多,所以说没有人超过3级元代码只是稍微夸张了一点

如果你想一想,大多数人从来没有使用过元编程,而两个层次是很难理解的。我猜三次几乎是不可能的,而最后一个尝试四次的人最终被送进了精神病院。

自从我第一次被拘留以来
class MM(type):
    def __add__(cls, other):
        metacls = cls.__class__
        return metacls(cls.__name__ + other.__name__, (cls, other), {})

class M1(type, metaclass=MM):
    def __new__(metacls, name, bases, namespace):
        namespace["M1"] = "here"
        print("At M1 creation")
        return super().__new__(metacls, name, bases, namespace)

class M2(type, metaclass=MM):
    def __new__(metacls, name, bases, namespace):
        namespace["M2"] = "there"
        print("At M2 creation")
        return super().__new__(metacls, name, bases, namespace)
In [22]: class Base(metaclass = M1 + M2): 
    ...:     pass
    ...: 
At M1 creation
At M2 creation
In [23]: import abc

In [24]: class Combined(metaclass=M1 + abc.ABCMeta):
    ...:     pass
    ...: 
At M1 creation