Python:如何从另一个atribute读取属性';谁的目标?

Python:如何从另一个atribute读取属性';谁的目标?,python,sqlalchemy,Python,Sqlalchemy,我甚至不知道如何寻找这个,这里是一个简单的例子 我有一门课: 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(

我甚至不知道如何寻找这个,这里是一个简单的例子

我有一门课:

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')
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()

并在第一个类中具有处理该数据的所有逻辑。在这里,我不知道如何读取'somefield'和id'的内容,'somefield'可能会有所不同并有另一个名称,这就是为什么我使用它作为参数,每个类的'id'总是相同的。

所有
@property
所做的就是返回一个自定义,它的
\u get\u
方法调用您的函数。所以,你可以直接这么做

我无法对此进行测试,因为我没有在此处安装
sqlalchemy
,但类似于以下内容:

class MyClass(db.Model):
    somefield = db.Column(db.String(255))

    someproperty = MyField(source='somefield')
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()
现在:

或者,如果愿意,可以为所有字段创建一个基类或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')


注意上面的
字段属性(对象)
。描述符必须是新样式的类,并且它们只在新样式的类中工作。在Python3.x中,只有新样式的类,但是如果使用2.x,每次定义一个没有基类的类时,都会得到一个旧样式的类。这只是你不想要老式课程的众多原因之一;他们还错误地处理了一些特殊的方法,打破了多重继承,让你看起来像一个复古的时髦人士,在你睡觉的时候偷偷溜进你的房间,从你的钱包里偷钱。

你是在寻找Python内置的东西还是你可以自己添加的东西?下面有人给了我一个完美的解决方案,非常感谢第一个解决方案非常有效,但我不得不将类FieldProperty:更改为类FieldProperty(对象):。现在我要试试第二个。非常感谢@guinunez:啊,我假设你在Python 3中,因为你把
(对象)
MyField
中去掉了。在Python2中,永远不要关闭
(object)
,除非在非常罕见的情况下,您知道一些古老的库需要它。我会编辑我的答案。@guinunez:无论如何,我上面链接的描述HOWTO绝对值得一读。Guido的博客文章和我找不到的一篇我认为是Ned Batchelder写的博客文章,如果你不能集中注意力的话,可能会有所帮助。还有很多愚蠢的想法,看看它们是否有效。并阅读
属性
类方法
静态方法
装饰器的源代码。如果不知道这一区别,我应该如何使其与python 2和3兼容?。我正在制作一个以django imagekit为灵感的模块,但用于flask和sqlalchemy@guinunez:当您没有其他继承源时,只要始终使用
object
,并且它可以与Python 2和3一起正常工作。(我应该在我的代码中这样做,而不是假设您使用的是3。现在我明白了为什么Guido建议每个人都应该从object继承,即使在Python 3中也是如此……在Python 2.7消失之前,让人们改掉这个习惯是不好的。)