我记住你几乎不需要使用元类。为什么?因为我认为如果你正在为一个类做类似的事情,你应该把它做到一个对象。而一个小的重新设计/重构是为了。
能够使用元类已经导致许多地方的许多人将类用作某种二级对象,这对我来说似乎是灾难性的。编程是否被元编程所取代?不幸的是,类装饰器的添加使其更加可以接受。
所以请,我非常想知道你在Python中对元类的有效(具体)用例。或者,为了让人们明白为什么变异类比变异对象更好,有时候。
我将开始:
有时使用第三方库时,能够以某种方式改变该类是有用的。
(这是我能想到的唯一情况,它不是具体的)
发布于 2018-02-28 15:03:36
我有一个处理非交互式绘图的类,作为Matplotlib的前端。然而,有时候想做互动绘图。只有几个函数,我发现我能够增加图形数量,手动调用绘图等,但是我需要在每次绘图调用之前和之后执行这些操作。因此,为了创建一个交互式绘图包装器和一个屏幕外包装器,我发现通过元类来包装合适的方法比做类似的事情更有效:
class PlottingInteractive:
add_slice = wrap_pylab_newplot(add_slice)
这种方法跟不上API的变化等等,但是__init__
在重新设置类属性之前迭代类属性的方法更有效,并且保持最新:
class _Interactify(type):
def __init__(cls, name, bases, d):
super(_Interactify, cls).__init__(name, bases, d)
for base in bases:
for attrname in dir(base):
if attrname in d: continue # If overridden, don't reset
attr = getattr(cls, attrname)
if type(attr) == types.MethodType:
if attrname.startswith("add_"):
setattr(cls, attrname, wrap_pylab_newplot(attr))
elif attrname.startswith("set_"):
setattr(cls, attrname, wrap_pylab_show(attr))
当然,可能有更好的方法来做到这一点,但我发现这是有效的。当然,这也可以在__new__
或中完成__init__
,但这是我找到的最直接的解决方案。
发布于 2018-02-28 15:54:32
元类的目的不是用元类/类来替换类/对象的区别 - 而是以某种方式改变类定义(以及它们的实例)的行为。实际上,它是以对特定域比默认域更有用的方式来改变类语句的行为。我用过的东西是:
class Mp3File(MusicFile): extensions = ['.mp3'] # Register this type as a handler for mp3 files ... # Implementation of mp3 methods go here
元类然后维护一个{'.mp3' : MP3File, ... }
等的目录,并且当你通过一个工厂函数请求一个处理程序时,构造一个适当类型的对象。_get_foo
和_set_foo
和透明地转换为性能。作为一个真实世界的例子,这里给出了一个我写给更多类C结构体定义的方法。元类用于将声明的项目转换为结构格式字符串,处理继承等,并生成一个能够处理它的类。
对于其他现实世界的例子,请看看各种ORM,例如sqlalchemy 的 ORM或sqlobject。同样,目的是解释具有特定意义的定义(这里是SQL列定义)。https://stackoverflow.com/questions/-100003166
复制相似问题