|
|
1
23
我有一个处理非交互式绘图的类,作为Matplotlib的前端。然而,有时人们想进行交互式绘图。只使用了几个函数,我发现我可以增加数字计数、手动调用绘图等,但我需要在每次绘图调用之前和之后执行这些操作。因此,为了创建一个交互式绘图包装器和一个屏幕外绘图包装器,我发现通过元类(包装适当的方法)这样做比执行以下操作更有效:
这个方法不跟上API的变化等等,而是在
当然,也许有更好的方法可以做到这一点,但我发现这是有效的。当然,这也可以在
|
|
|
2
64
最近有人问我同样的问题,我想出了几个答案。我希望可以重新激活这个线程,因为我想详细说明上面提到的一些用例,并添加一些新的用例。 我见过的大多数元类都做两件事之一:
考虑到最常见和最具体的用例,您绝对必须使用元类的唯一情况是,当您想要修改类名或基类列表时,因为一旦定义了这些参数,这些参数就会被烘焙到类中,并且没有任何装饰器或函数可以将它们取消绑定。
这可能在框架中很有用,用于在定义具有相似名称或不完整继承树的类时发出警告,但除了Trolling之外,我想不出实际更改这些值的原因。也许大卫比兹利可以。
无论如何,在python 3中,元类也有
γ
您可能认为可以使用创建计数器实现有序属性,并且可以使用默认参数模拟重载:
γ
除了更难看之外,它也不那么灵活:如果你想要有序的文字属性,比如整数和字符串,怎么办?如果…怎么办
以下是解决第一个问题的创造性方法:
下面是解决第二个问题的创造性方法:
但这比一个简单的元类(尤其是第一个真正融化你大脑的元类)要多得多。我的观点是,你将元类视为不熟悉的和反直觉的,但是你也可以将它们视为编程语言进化的下一步:你只需要调整你的思维方式。毕竟,您可以在C中做任何事情,包括用函数指针定义一个结构,并将它作为第一个参数传递给它的函数。第一次看到C++的人可能会说:“这是什么魔法?”为什么编译器隐式地传递
最后,元类是RAD,编程应该很有趣。使用标准的编程结构和设计模式一直都是无聊和无趣的,并且阻碍了你的想象力。多活一点!这是一个元类,只为您。
|
|
|
3
35
元类的目的不是用元类/类替换类/对象的区别,而是以某种方式改变类定义(及其实例)的行为。实际上,它是改变类语句的行为,其方式对于特定域可能比默认域更有用。我使用它们的目的是:
|
|
|
4
17
让我们从蒂姆·彼得的经典名言开始:
说到这一点,我(定期)遇到了元类的真正用途。想到的是在Django中,所有模型都继承自models.model。模型。模型,反过来,做了一些严重的魔术,用Django的ORM美德包装您的数据库模型。这种魔力是通过元类产生的。它创建各种各样的异常类、管理器类等。 请参见django/db/models/base.py,class modelbase()了解故事的开头。 |
|
|
5
6
元类可以方便地在Python中构造特定于域的语言。具体的例子是Django,sqlObject的数据库模式声明性语法。 一个基本的例子 A Conservative Metaclass Ian Bicking:
其他一些技术: Ingredients for Building a DSL in Python (PDF)。 编辑(由Ali):使用集合和实例执行此操作的一个示例是我喜欢的。重要的事实是实例,它给了您更多的能力,并消除了使用元类的原因。更值得注意的是,您的示例使用了类和实例的混合,这显然表明您不能只使用元类来完成这一切。并创造出一种真正不统一的方式。
它并不完美,但是已经几乎没有魔法了,不需要元类,并且改进了一致性。 |
|
|
6
5
我在Python中唯一一次使用元类是在为FlickrAPI编写包装器时。 我的目标是刮 flickr's api site 并动态生成完整的类层次结构,以允许使用Python对象访问API:
所以在那个例子中,因为我从网站生成了整个python-flickr API,所以我真的不知道运行时的类定义。能够动态生成类型非常有用。 |
|
|
7
5
我昨天也是这么想的,完全同意。在我看来,代码中的复杂之处在于试图使其更具声明性,这通常会使代码库更难维护、更难阅读,也会减少蟒蛇。 它通常还需要大量的copy.copy()ing(以维护继承和从类到实例的复制),这意味着您必须在许多地方查看发生了什么(总是从元类向上看),这也违背了Python的粒度。 我一直在挑选formEncode和sqlacalchemy代码,看看这样的声明性风格是否值得,显然不值得。这样的样式应该留给描述符(如属性和方法)和不可变的数据。 Ruby对这种声明性风格有更好的支持,我很高兴核心的Python语言不会走这条路。 我可以看到它们用于调试,向所有的基类添加元类以获得更丰富的信息。 我也看到它们只在(非常)大的项目中使用,以去掉一些样板代码(但失去了清晰性)。斯巴尔化学 example 是否在其他地方使用它们,根据类定义中的属性值向所有子类添加特定的自定义方法 例如玩具例子
可能有一个元类,它在该类中生成了一个具有基于“hello”的特殊属性的方法(比如在字符串末尾添加“hello”的方法)。确保您不必在每个子类中编写一个方法,这对可维护性很有好处,相反,您需要定义的只是方法\ maker \值。 这种需求是非常罕见的,而且只减少了一些输入,除非您有足够大的代码库,否则不值得考虑。 |
|
8
5
合理的元类使用模式是在定义类时执行一次操作,而不是在实例化同一类时重复执行。
当多个类共享相同的特殊行为时,重复
但即使只有一个特殊的班级,而且没有可预见的延期,
|
|
9
4
你从来没有绝对 需要 要使用元类,因为您可以始终使用要修改的类的继承或聚合来构造执行所需操作的类。 也就是说,在Smalltalk和Ruby中,能够修改现有的类非常方便,但Python不喜欢直接这样做。 有一个很好的 DeveloperWorks article 在python中进行元分类可能会有所帮助。这个 Wikipedia article 也不错。 |
|
|
10
3
元类不能取代编程!它们只是一个可以自动化或使某些任务更优雅的技巧。一个很好的例子是
Pygments
语法突出显示库。它有一个叫做
它们就像盐,很容易用得太多。 |
|
|
11
3
我使用元类的方法是为类提供一些属性。例如:
会把 名称 将元类设置为指向NameClass的每个类的属性。 |
|
|
12
3
一些GUI库在多个线程尝试与它们交互时遇到问题。
在某些情况下,能够动态地重写整个库,从而使其在多线程应用程序中正常工作,这是非常有用的。这个 safetkinter 模块在由 threadbox 模块——不需要事件和队列。
一个整洁的方面
|
|
13
3
元类唯一合法的用例是防止其他多管闲事的开发人员接触您的代码。一旦一个爱管闲事的开发人员掌握了元类并开始使用您的元类,就可以添加一两个级别来阻止它们。如果不起作用,开始使用
(在脸上写着“舌头”,但我见过这种混淆。Django就是一个很好的例子) |
|
|
14
2
这只是一个小用途,但是…我发现有一件事很有用,那就是在创建子类时调用一个函数。我把它编成一个元类
请注意,我慢慢地意识到这种行为的隐式魔力有点不受欢迎,因为从上下文中看类定义是不可预料的…所以除了初始化一个
|
|
|
15
1
最近,我不得不使用一个元类来帮助声明性地在一个数据库表周围定义一个sqlachemy模型,该数据库表由来自 http://census.ire.org/data/bulkdata.html 艾尔提供 database shells 对于人口普查数据表,该表根据人口普查局的命名约定(p012015、p012016、p012017等)创建整数列。
我想a)能够使用
然后,我可以将这个元类用于模型定义,并访问模型上自动枚举的字段:
|
|
|
16
1
似乎有一个合法的使用描述 here -用元类重写python docstrings。 |
|
|
17
0
为了便于使用,我必须对二进制分析器使用它们一次。您可以定义一个消息类,该类具有线中存在的字段的属性。 它们需要按照声明的方式进行排序,以从中构造最终的线格式。如果使用有序的名称空间dict,则可以对元类执行此操作。实际上,它在元类示例中有: https://docs.python.org/3/reference/datamodel.html#metaclass-example 但是总的来说:如果您真的需要增加元类的复杂性,请仔细评估。 |