我不知道如何找到这个,这是一个简化的例子
我有一个班级:
class MyField():
def __init__(self, model=None, source=None, id=None):
self.source = source
self.model = model
self.id = id
def somemethod(self):
...
用于其他课程
class MyClass(db.Model):
id = db.Column(db.Integer, primary_key=True)
somefield = db.Column(db.String(255))
@property
def someproperty(self):
specs = MyField(
source=self.somefield,
model=self.__class__.__name__,
id=self.id
)
return specs.somemethod()
这对我来说并不理想,我希望为第二类编写更简单的代码,所以让它看起来像这样:
class MyClass(db.Model):
somefield = db.Column(db.String(255))
someproperty = MyField(source='somefield')
并在第一个类上拥有处理该数据的所有逻辑。在这里我不知道如何阅读'somefield'和id的内容,'somefield'可能会有所不同,并且有另一个名字,这就是为什么我用它作为参数,'id'对每个类来说都是一样的
答案 0 :(得分:1)
@property
所做的只是返回__get__
方法调用您的函数的自定义descriptor。所以,你可以直接这样做。
我无法对此进行测试,因为我在这里没有安装sqlalchemy
,但是这样的话:
class FieldProperty(object):
def __init__(self, field, source):
self.field, self.source = field, source
def __get__(self, obj, typ=None):
if typ is None:
typ = obj.__class__
specs = self.field(
source = getattr(obj, self.source),
model = typ.__name__,
id = obj.id)
return specs.somemethod()
现在:
class MyClass(db.Model):
somefield = db.Column(db.String(255))
someproperty = FieldProperty(MyField, source='somefield')
或者,如果您愿意,可以为所有字段创建基类或mixin,以添加为您执行此操作的类方法:
class BaseField(object):
@classmethod
def make_property(cls, source):
return FieldProperty(cls, source)
现在:
class MyClass(db.Model):
somefield = db.Column(db.String(255))
someproperty = MyField.make_property('somefield')
请注意上面的FieldProperty(object)
。描述符必须是新式类,它们只能用于新式类。在Python 3.x中,新的类就是它们,但是如果你使用2.x,那么每次定义一个没有基类的类时,你就会得到一个旧式的类。这只是你不想要一个旧式课程的众多原因之一;他们还处理一些错误的特殊方法,打破多重继承,让你看起来像一个复古的时髦,潜入你的房间,在你睡觉时偷钱从你的钱包里。