元类有哪些(具体的)用例? [英] What are some (concrete) use-cases for metaclasses?

查看:81
本文介绍了元类有哪些(具体的)用例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个喜欢使用元类的朋友,并定期提供它们作为解决方案.

I have a friend who likes to use metaclasses, and regularly offers them as a solution.

我认为您几乎不需要使用元类.为什么?因为我认为如果您正在对类执行类似的操作,则可能应该对对象执行此操作.并进行了少量的重新设计/重构.

I am of the mind that you almost never need to use metaclasses. Why? because I figure if you are doing something like that to a class, you should probably be doing it to an object. And a small redesign/refactor is in order.

能够使用元类已经使很多地方的许多人将类用作某种第二流的对象,这对我来说似乎是灾难性的.用元编程代替编程吗?不幸的是,添加了类装饰器使它变得更加容易接受.

Being able to use metaclasses has caused a lot of people in a lot of places to use classes as some kind of second rate object, which just seems disastrous to me. Is programming to be replaced by meta-programming? The addition of class decorators has unfortunately made it even more acceptable.

所以,我很想知道您在Python中对元类的有效(具体)用例.还是要启蒙一下为什么有时候变异类比变异对象更好.

So please, I am desperate to know your valid (concrete) use-cases for metaclasses in Python. Or to be enlightened as to why mutating classes is better than mutating objects, sometimes.

我将开始:

有时使用第三方 库,能够 以某种方式改变班级.

Sometimes when using a third-party library it is useful to be able to mutate the class in a certain way.

(这是我唯一能想到的情况,并不具体)

(This is the only case I can think of, and it's not concrete)

推荐答案

我有一个处理非交互式绘图的类,作为Matplotlib的前端.但是,有时有人想进行交互式绘图.仅使用几个函数,我发现我能够增加图形数量,手动调用绘制等,但是我需要在每次绘制调用之前和之后执行这些操作.因此,要创建交互式绘图包装器和屏幕外绘图包装器,我发现通过元类包装适当的方法来执行此操作比执行以下操作更有效:

I have a class that handles non-interactive plotting, as a frontend to Matplotlib. However, on occasion one wants to do interactive plotting. With only a couple functions I found that I was able to increment the figure count, call draw manually, etc, but I needed to do these before and after every plotting call. So to create both an interactive plotting wrapper and an offscreen plotting wrapper, I found it was more efficient to do this via metaclasses, wrapping the appropriate methods, than to do something like:

class PlottingInteractive:
    add_slice = wrap_pylab_newplot(add_slice)

此方法不能跟上API的更改等,但是在重新设置类属性之前对__init__中的类属性进行迭代的方法更有效,并且可以使事情保持最新状态:

This method doesn't keep up with API changes and so on, but one that iterates over the class attributes in __init__ before re-setting the class attributes is more efficient and keeps things up to date:

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__中完成,但这是我找到的最简单的解决方案.

Of course, there might be better ways to do this, but I've found this to be effective. Of course, this could also be done in __new__ or __init__, but this was the solution I found the most straightforward.

这篇关于元类有哪些(具体的)用例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆