什么是甲状腺?它们用于什么?
当前回答
此分類上一篇: tl;dr version
类型(obj)函数会给你一个对象的类型。
一个阶级的类型( )是它的甲型阶级。
使用甲状腺:
class Foo(object):
__metaclass__ = MyMetaClass
一个类的类是一个类的类 - 一个类的身体是转移到一个类的论点,它被用来构建一个类。
在这里,你可以阅读如何使用金属玻璃来自定义课堂建筑。
其他回答
当班级声明执行时,Python 首先将班级声明的身体作为一个正常的代码块执行。 结果的名称空间(dict)保留了班级的属性. 金属阶级通过观察班级的基层(金属阶级继承),在 __金属阶级__属性的班级(如果有)或 __金属阶级__全球变量来确定。
def make_hook(f):
"""Decorator to turn 'foo' method into '__foo__'"""
f.is_hook = 1
return f
class MyType(type):
def __new__(mcls, name, bases, attrs):
if name.startswith('None'):
return None
# Go over attributes and see if they should be renamed.
newattrs = {}
for attrname, attrvalue in attrs.iteritems():
if getattr(attrvalue, 'is_hook', 0):
newattrs['__%s__' % attrname] = attrvalue
else:
newattrs[attrname] = attrvalue
return super(MyType, mcls).__new__(mcls, name, bases, newattrs)
def __init__(self, name, bases, attrs):
super(MyType, self).__init__(name, bases, attrs)
# classregistry.register(self, self.interfaces)
print "Would register class %s now." % self
def __add__(self, other):
class AutoClass(self, other):
pass
return AutoClass
# Alternatively, to autogenerate the classname as well as the class:
# return type(self.__name__ + other.__name__, (self, other), {})
def unregister(self):
# classregistry.unregister(self)
print "Would unregister class %s now." % self
class MyObject:
__metaclass__ = MyType
class NoneSample(MyObject):
pass
# Will print "NoneType None"
print type(NoneSample), repr(NoneSample)
class Example(MyObject):
def __init__(self, value):
self.value = value
@make_hook
def add(self, other):
return self.__class__(self.value + other.value)
# Will unregister the class
Example.unregister()
inst = Example(10)
# Will fail with an AttributeError
#inst.unregister()
print inst + inst
class Sibling(MyObject):
pass
ExampleSibling = Example + Sibling
# ExampleSibling is now a subclass of both Example and Sibling (with no
# content of its own) although it will believe it's called 'AutoClass'
print ExampleSibling
print ExampleSibling.__mro__
其他人已经解释了金属玻璃是如何工作的,它们是如何适应Python类型系统的,这里有一个例子,它们可以用于什么。在我写的测试框架中,我想跟踪在哪个类被定义的顺序,以便我后来能够在这个顺序中安装它们,我发现使用金属玻璃最容易做到这一点。
class MyMeta(type):
counter = 0
def __init__(cls, name, bases, dic):
type.__init__(cls, name, bases, dic)
cls._order = MyMeta.counter
MyMeta.counter += 1
class MyType(object): # Python 2
__metaclass__ = MyMeta
class MyType(metaclass=MyMeta): # Python 3
pass
任何是 MyType 的子类,然后获得一个类属性 _ 命令,记录了类被定义的顺序。
一个用途是自动将新属性和方法添加到一个例子。
例如,如果你看 Django 模型,它们的定义看起来有点困惑。
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
然而,在工作时间里,人体对象充满了各种有用的方法。
上面的答案是正确的。
但读者可能来到这里寻找关于类似名称的内部课程的答案,他们在受欢迎的图书馆,如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 字段。
此分類上一篇: tl;dr version
类型(obj)函数会给你一个对象的类型。
一个阶级的类型( )是它的甲型阶级。
使用甲状腺:
class Foo(object):
__metaclass__ = MyMetaClass
一个类的类是一个类的类 - 一个类的身体是转移到一个类的论点,它被用来构建一个类。
在这里,你可以阅读如何使用金属玻璃来自定义课堂建筑。
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- 为什么元组可以包含可变项?
- 如何合并字典的字典?
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 解析日期字符串并更改格式
- 使用try和。Python中的if
- 如何在Python中获得所有直接子目录