模块级别的 python 元类

发布于 2024-11-29 04:46:53 字数 1066 浏览 0 评论 0原文

我读过 Python 中的元类是什么?

我尝试了复制示例中的上元类,发现这在所有情况下都不起作用:

def upper(cls_name, cls_parents, cls_attr):                                     
    """ Make all class attributes uppper case """                               
    attrs = ((name, value) for name, value in cls_attr.items()                  
            if not name.startswith('__'))                                       
    upper_atts = dict((name.upper(), value) for name, value in attrs)           
    return type(cls_name, cls_parents, upper_atts)                              

__metaclass__ = upper #Module level
class Foo:                                                                      
    bar = 1                                                                     
f =  Foo()
print(f.BAR) #works in python2.6

上面在 python3 中失败(带有属性错误),我认为这是自然的,因为 python3 中的所有类都已经将对象作为它们的对象父类和元类解析进入对象类。

问题:

如何在 python3 中创建模块级元类?

I read What is a metaclass in Python?

and I tried to replicate the upper metaclass from the example and found that this doesn't work in all cases:

def upper(cls_name, cls_parents, cls_attr):                                     
    """ Make all class attributes uppper case """                               
    attrs = ((name, value) for name, value in cls_attr.items()                  
            if not name.startswith('__'))                                       
    upper_atts = dict((name.upper(), value) for name, value in attrs)           
    return type(cls_name, cls_parents, upper_atts)                              

__metaclass__ = upper #Module level
class Foo:                                                                      
    bar = 1                                                                     
f =  Foo()
print(f.BAR) #works in python2.6

The above fails (with an attribute error) in python3 which I think is natural because all classes in python3 already have object as their parent and metaclass resolution goes into the object class.

The question:

How do I make a module level metaclass in python3?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

分开我的手 2024-12-06 04:46:53

模块级元类并不是真正的“模块级”,它与类初始化的工作方式有关。创建类时,类创建将查找变量“__metaclass__”,如果它不在本地环境中,它将在全局环境中查找。因此,如果您有一个“模块级别”__metaclass__,它将用于以后的每个类,除非它们具有显式元类。

在 Python 3 中,您可以在类定义中使用 metaclass= 指定元类。因此没有模块级元类。

那你怎么办?简单:为每个类明确指定它

这实际上并没有太多额外的工作,如果您确实有数百个类并且不想手动执行,您甚至可以通过良好的正则表达式搜索和替换来完成。

The module level metaclass isn't really "module level", it has to do with how class initialization worked. The class creation would look for the variable "__metaclass__" when creating the class, and if it wasn't in the local environment it would look in the global. Hence, if you had a "module level" __metaclass__ that would be used for every class afterwards, unless they had explicit metaclasses.

In Python 3, you instead specify the metaclass with a metaclass= in the class definition. Hence there is no module level metaclasses.

So what do you do? Easy: You specify it explicitly for each class.

It's really not much extra work, and you can even do it with a nice regexp search and replace if you really have hundreds of classes and don't want to do it manually.

烟雨扶苏 2024-12-06 04:46:53

如果您想将所有属性更改为大写,您可能应该使用 __init__ 方法来执行此操作,而不是使用元类。

元类的魔力比 99% 的用户所担心的还要深。如果您想知道是否需要它们,那么您就不需要(真正需要它们的人肯定知道他们需要它们,并且不需要解释为什么)。

-- Python 大师 Tim Peters< /p>

如果您需要一些东西更深入地说,您还应该使用类装饰器进行评估。

只要您想做一些可以使用类装饰器或初始化来完成的事情,那么使用元类并了解如何创建类是不必要的。

也就是说,如果您确实想使用元类,请将其作为关键字参数传递给该类。

class Foo(object, metaclass=UpperCaseMetaClass)

其中 UpperCaseMetaClass 是扩展 type 的类,而不是方法。

class UpperCaseMetaClass(type):
    def __new__():
        #Do your Magic here.

If you want to change all the attributes to upper case, you should probably use the __init__ method to do so, than use a metaclass.

Metaclasses are deeper magic than 99% of users should ever worry about. If you wonder whether you need them, you don't (the people who actually need them know with certainty that they need them, and don't need an explanation about why).

-- Python Guru Tim Peters

If you need something deeper, you should also evaluate using Class Decorators.

Using MetaClasses and understanding how the classes are created is so unnecessary as long as you want to do something that you can do using class decorators or initialization.

That said, if you really want to use a Metaclass tho' pass that as a keyword argument to the class.

class Foo(object, metaclass=UpperCaseMetaClass)

where UpperCaseMetaClass is a class that extends type and not a method.

class UpperCaseMetaClass(type):
    def __new__():
        #Do your Magic here.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文