什么是甲状腺?它们用于什么?


当前回答

我看到一个有趣的使用案例在一个名为类用途的包中,它检查是否所有类变量在顶部案例格式(方便有统一逻辑的配置类),并检查是否没有例子级方法在课堂上。

其他回答

在 Python 或任何其他语言中,我们对每个变量或对象都有一个类型. 在 Python 中,我们可以使用 Type() 函数来获得任何类型(变量、对象等)。

通过在课堂定义中的 meta 类关键词,我们可以自定义课堂创建过程。

class meta(type):
    pass
class baseclass(metaclass=meta): # This is Mestaclass
    pass
class derivedclass(baseclass):
    pass
print(type(meta))
print(type(baseclass))
print(type(derivedclass))

在定义新类时,如果没有定义的甲型,则使用默认类型甲型;如果一个甲型不是类型(例)的对象(例),则在这种情况下,它直接用作甲型。

我看到一个有趣的使用案例在一个名为类用途的包中,它检查是否所有类变量在顶部案例格式(方便有统一逻辑的配置类),并检查是否没有例子级方法在课堂上。

上面的答案是正确的。

但读者可能来到这里寻找关于类似名称的内部课程的答案,他们在受欢迎的图书馆,如Django和WTForms。

相反,这些是班级的命令之内的名称空间,它们是用内部班级为可读性而建造的。

在这个特殊的例子领域,抽象是显而易见地与作者模型的领域分开。

from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=50)
    email = models.EmailField()

    class Meta:
        abstract = True

另一个例子是WTForms的文档:

from wtforms.form import Form
from wtforms.csrf.session import SessionCSRF
from wtforms.fields import StringField

class MyBaseForm(Form):
    class Meta:
        csrf = True
        csrf_class = SessionCSRF

    name = StringField("name")

这个合成不会在Python编程语言中得到特别的处理. Meta 不是这里的一个关键词,也不会引发 meta 类行为. 相反,第三方图书馆代码在 Django 和 WTForms 等包中,在某些类的构建者和其他地方读到这个属性。

这些声明的存在改变了具有这些声明的类别的行为. 例如,WTForms 阅读 self.Meta.csrf 以确定表格是否需要一个 csrf 字段。

一个用途是自动将新属性和方法添加到一个例子。

例如,如果你看 Django 模型,它们的定义看起来有点困惑。

class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

然而,在工作时间里,人体对象充满了各种有用的方法。

什么是Metaclasses?你用它们用于什么?

>>> Class(...)
instance

>>> Metaclass(...)
Class

>>> type('Foo', (object,), {}) # requires a name, bases, and a namespace
<class '__main__.Foo'>

每当你创建一个类时,你都会使用一个类型:

class Foo(object): 
    'demo'

>>> Foo
<class '__main__.Foo'>
>>> isinstance(Foo, type), isinstance(Foo, object)
(True, True)

name = 'Foo'
bases = (object,)
namespace = {'__doc__': 'demo'}
Foo = type(name, bases, namespace)

>>> Foo.__dict__
dict_proxy({'__dict__': <attribute '__dict__' of 'Foo' objects>, 
'__module__': '__main__', '__weakref__': <attribute '__weakref__' 
of 'Foo' objects>, '__doc__': 'demo'})

(在 __dict__: __module__ 类的内容上有一个侧笔记,因为类必须知道它们在哪里定义,而 __dict__ 和 __weakref__ 是因为我们不定义 __slots__ - 如果我们定义 __slots__ 我们会在例子中节省一些空间,因为我们可以通过排除它们来排除 __dict__ 和 __weakref__。

>>> Baz = type('Bar', (object,), {'__doc__': 'demo', '__slots__': ()})
>>> Baz.__dict__
mappingproxy({'__doc__': 'demo', '__slots__': (), '__module__': '__main__'})

我们可以像任何其他类定义一样扩展类型:

>>> Foo
<class '__main__.Foo'>

class Type(type):
    def __repr__(cls):
        """
        >>> Baz
        Type('Baz', (Foo, Bar,), {'__module__': '__main__', '__doc__': None})
        >>> eval(repr(Baz))
        Type('Baz', (Foo, Bar,), {'__module__': '__main__', '__doc__': None})
        """
        metaname = type(cls).__name__
        name = cls.__name__
        parents = ', '.join(b.__name__ for b in cls.__bases__)
        if parents:
            parents += ','
        namespace = ', '.join(': '.join(
          (repr(k), repr(v) if not isinstance(v, type) else v.__name__))
               for k, v in cls.__dict__.items())
        return '{0}(\'{1}\', ({2}), {{{3}}})'.format(metaname, name, parents, namespace)
    def __eq__(cls, other):
        """
        >>> Baz == eval(repr(Baz))
        True            
        """
        return (cls.__name__, cls.__bases__, cls.__dict__) == (
                other.__name__, other.__bases__, other.__dict__)

>>> class Bar(object): pass
>>> Baz = Type('Baz', (Foo, Bar,), {'__module__': '__main__', '__doc__': None})
>>> Baz
Type('Baz', (Foo, Bar,), {'__module__': '__main__', '__doc__': None})

但是,与 eval(repr(Class))的进一步检查是不可能的(因为函数将是相当不可能从他们的默认 __repr__ 的 eval 。

from collections import OrderedDict

class OrderedType(Type):
    @classmethod
    def __prepare__(metacls, name, bases, **kwargs):
        return OrderedDict()
    def __new__(cls, name, bases, namespace, **kwargs):
        result = Type.__new__(cls, name, bases, dict(namespace))
        result.members = tuple(namespace)
        return result

class OrderedMethodsObject(object, metaclass=OrderedType):
    def method1(self): pass
    def method2(self): pass
    def method3(self): pass
    def method4(self): pass

>>> OrderedMethodsObject.members
('__module__', '__qualname__', 'method1', 'method2', 'method3', 'method4')

>>> inspect.getmro(OrderedType)
(<class '__main__.OrderedType'>, <class '__main__.Type'>, <class 'type'>, <class 'object'>)

而且它大约有正确的回报(除非我们能找到代表我们的功能的方式,否则我们就不能再评估):

>>> OrderedMethodsObject
OrderedType('OrderedMethodsObject', (object,), {'method1': <function OrderedMethodsObject.method1 at 0x0000000002DB01E0>, 'members': ('__module__', '__qualname__', 'method1', 'method2', 'method3', 'method4'), 'method3': <function OrderedMet
hodsObject.method3 at 0x0000000002DB02F0>, 'method2': <function OrderedMethodsObject.method2 at 0x0000000002DB0268>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'OrderedMethodsObject' objects>, '__doc__': None, '__d
ict__': <attribute '__dict__' of 'OrderedMethodsObject' objects>, 'method4': <function OrderedMethodsObject.method4 at 0x0000000002DB0378>})