python:如何从类变量访问类?

2024-03-29 00:34:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要定义一个类变量,名为“class”。我想直接在类命名空间中执行此操作,而不是在类方法中。显然,我不能直接说:

class MyClass(object):
    a = 1
    b = 2
    class = 3

所以,我想做些类似的事情:

^{pr2}$

其中“self”应替换为对类的引用。那么,如何从类名称空间引用类呢?在


注意:这个问题可能看起来有些做作,但它源于一个实际的目标。在

实际上,MyClass是一个Django REST框架序列化程序,我需要在其上定义一个“class”字段,因为这个REST端点必须遵循某种协议。在

有一个为序列化程序定义的元类,它在类创建时调用__new__(),并且{}聚合类上定义的所有字段,并用它们填充字段的注册表。因此,在创建类之前,我必须定义我的变量class。另请参见:Django REST Framework: how to make verbose name of field differ from its field_name?


Tags: django方法nameselfrestfield序列化定义
3条回答

不需要将属性命名为class,这可能会导致各种问题。您可以将属性命名为class_,但仍要将其从名为class的源属性中提取出来,并以class的形式呈现为JSON。在

可以通过重写序列化程序的元类来实现这一点。下面是一个serializers.py文件的示例(模型和类很大程度上是直接从tutorial中提取出来的)。在

主要的魔法是元类的这一部分

# Remap fields (to use class instead of class_)
fields_ = []
for name, field in fields:
    if name.endswith('_'):
        name = name.rstrip('_')
    fields_.append((name, field))

这将获取您在序列化程序中定义的以下划线结尾的任何字段(即field_),并在绑定Fields并在序列化程序上设置_declared_fields属性时从名称中删除下划线。在

^{pr2}$

这是模型.py引用文件(django不允许字段名以下划线结尾)

from django.db import models

class Snippet(models.Model):
    title = models.CharField(max_length=100, blank=True, default='')
    klass = models.CharField(max_length=100, default='yo')

这就是django shell的外观

$ python manage.py shell

>>> from snippets.models import Snippet
>>> from snippets.serializers import SnippetSerializer
>>> from rest_framework.renderers import JSONRenderer
>>> from rest_framework.parsers import JSONParser
>>> snippet = Snippet(title='test')
>>> snippet.save()
>>> serializer = SnippetSerializer(snippet)
>>> serializer.data
{'title': u'test', 'pk': 6, 'class': u'yo'}

你可以:

class MyClass(object):
    a = 1
    b = 2
    vars()['class'] = 3

但是由于class是一个保留关键字,因此必须使用getattr和{}来访问变量,这样class仍然是一个字符串。在

^{pr2}$

您可以从type创建类,并将属性class添加到类字典中:

>>> MyClass = type('MyClass', (), {'class': 3, 'a':1, 'b':2})
>>> getattr(MyClass, 'class')
3

不能用点引用直接访问名称class,需要使用getattr

^{pr2}$

FWIW中,您可以像通常那样定义类方法,然后在以后将它们绑定到类。在

注意事项:虽然这是可行的,但我自己不会使用这个黑客攻击,因为关键字class是一个太多的关键字,不能篡改。在

相关问题 更多 >