我(尝试)做一些元编程,事情似乎正在发挥作用,直到我尝试做一套。
class MetaField(type):
def __new__(meta, clsname, bases, attrs):
bases = (Field,) + bases
return super(MetaField, meta).__new__(meta, clsname, bases, attrs)
def __call__(cls, *args, **kw):
cls._primary_key = kw.pop('primary_key', False)
return super(MetaField, cls).__call__(*args, **kw)
class Field(object):
def __new__(cls, *args, **kw):
return super(Field, cls).__new__(cls, *args)
#def __set__(self, instance, value):
# magic needs to go here
#def __get__(self, instance, owner):
# more magic here
@property
def primary_key(self):
return self._primary_key
class IntField(int):
__metaclass__ = MetaField
class SomeObject(object):
# trying with descriptors here
i = IntField(10, primary_key=True, foo='set')
obj = SomeObject()
assert obj.i == 10
assert obj.i.primary_key == True
obj.i = 11
assert obj.i == 11
assert obj.i.primary_key == True
AttributeError: 'int' object has no attribute 'primary_key'
这是有道理的,因为obj.i
不再是IntField
,而是普通int
。
所以在Field.__set__
如果我可以做的话
super(self) = value
self
但IntField
仍然是超级ProxyFieldDescriptor
骗子。
我已经尝试按照中所述实现__get__
http://blog.kevinastone.com/django-model-descriptors.html但是当您从_primary_key
返回时,您会丢失所有补充信息,例如int
。
如何在派生类中设置data-ng-options
的实际值?
答案 0 :(得分:1)
首先,如果您在生产代码上执行此操作,您可能应该在开发人员中烧掉地狱。其次,这是你要做的事情:
class MetaField(type):
def __new__(meta, clsname, bases, attrs):
bases = (Field,) + bases
return super(MetaField, meta).__new__(meta, clsname, bases, attrs)
def __call__(cls, *args, **kw):
cls._primary_key = kw.pop('primary_key', False)
cls._name = kw.pop('name')
return super(MetaField, cls).__call__(*args, **kw)
class Field(object):
def __getattr__(self, item):
if item == 'primary_key':
return self._primary_key
else:
return self.__dict__[item]
def __set__(self, instance, value):
instance.__dict__[self._name] = IntField(value, primary_key=self.primary_key, name=self._name)
class IntField(int):
__metaclass__ = MetaField
class SomeObject(object):
# trying with descriptors here
i = IntField(10, primary_key=True, name='i')
if __name__ == '__main__':
obj = SomeObject()
assert obj.i == 10
assert obj.i.primary_key == True
obj.i = 11
assert obj.i == 11
assert obj.i.primary_key == True
# g2g
这里的关键是,与描述符的情况一样,你需要命名它们。如果您没有为它们命名,则在您需要设置/获取实例变量时无法访问实例变量。如果这不是问题,则不需要名称。但在这种情况下,你做到了。我做了必要的调整。
虽然我确信你很清楚这一点,但你可以通过更轻松的方式来完成你想要完成的事情......这是黑暗面的道路。
答案 1 :(得分:0)
这是__init__
方法的工作。它充当构造函数,并在将类实例化为对象时调用。
class A:
def __init__(self, x, y):
self.x = x
self.y = y
a = A(5, 6)
assert a.x == 5 and a.y == 6
您定义事物的方式,那些是类属性,并且与特定实例无关。