如何在Python中将类变量转换为实例变量?

我正在尝试在运行时将类变量转换为实例变量,这与Django ORM中的情况类似,在Django ORM中,各种类型的类变量在运行时都转换为相同类型的实例变量。

我正在使用一个元类将某些类型的类变量收集到一个列表中,然后在实例化时将它们设置为实例变量。我尝试删除原始的类变量并保留它们,但在两种情况下我都得到了不同的结果,而这都是不希望的。

  • 我创建了一个简单的Field对象,该对象使用get _set _描述符将值转换为类型。TextField的一个简单实现是Textfield,它对get _上的值进行统一编码。

  • 在创建类时,元类将类型为“字段”的所有属性收集到列表中

  • 然后将字段列表设置为类的_meta ['fields']。

  • 当将该类实例化为一个对象时,然后将_meta ['fields']设置为该对象。在一个用例中,原始类var会被事先删除。

  • 然后,我通过创建两个对象进行测试,将一个对象的textfield属性设置为某些文本,期望get _set _被调用并且都具有不同的非冲突值。

删除类变量后,设置Field值实际上不会调用setget _,并且该字段仅将类型更改为str。当我不删除类变量时,实例化的两个对象共享它们之间的值。

我已经将代码稀释为下面的代码,可以将其保存到文件中,并与python test.pypython shell一起运行或导入其中。将DELETE_CLASS_VAR设置为True将删除类变量(以解决这两个测试用例)。

显然我在这里错过了一些东西。未能使它正常工作,我会在整个过程中使用常规实例变量,但是我非常喜欢Django模型(并且我通过Django代码没有成功),其中在模型上设置的类变量随后在某种程度上成为其实例变量。类型安全性和设置的特定方法。


德玛西亚99
浏览 310回答 4
4回答

红糖糍粑

我想我解决了您的奥秘-您分配的类不是Field的实例。这样有帮助:class Model(object):    __metaclass__ = ModelMetaClass    def __init__(self):        print "ROOT MODEL INIT", self._meta        print "-"*80        super(Model, self).__init__()        _metafields = self._meta.get('fields',[])        for _field in _metafields:            _f = _field['value']            if DELETE_CLASS_VAR and hasattr(self, _field['name']):                delattr(self.__class__, _field['name'])            setattr(self, _field['name'], \                _f.__new__(_f.__class__, *_f._args, **_f._kwargs))仅在DELETE_CLASS_VAR启用时有效。但是printin__set__()方法的结果迫使我的胆量向我发出信号,告诉我该解决方案仍然存在某些问题,才能进一步完善和实用。

紫衣仙女

在尝试实现复杂目标时只能提供一些提示:尝试创建自己的Options类-_meta实际上是的一个实例django.db.models.options.Options,其中的某些_meta行为看起来似乎像列表等,但是您应该研究将Django的类子类化,并覆盖您必需的东西。猜猜您使用Django的模型元类是正确的方法,但是您还应该查看字段类内置了什么魔术,字段的contribute_to_class本质是非常重要的...还要尝试使用Django的Field类作为基类,因为可能会进行代码检查某个字段是否真的像这样……好吧,这不是真正的答案,只是试图提供一些提示!
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python