在 Python 中列出子类实例的属性

List attributes of a sublass instance in Python

我正在尝试在 Python 中构建一些 "ORM like" 行为。为此,我有一个模型 class 并想生成任何类型的子 classes。我的问题是当我尝试列出我的 subclasses 实例的属性时。 这是我的模型 class:

class Model:
    def __init__(self):
        self.className = type(self).__name__

    def listAttributes(self):
        from modules.users.user import User
        instance = User()
        meta = vars(instance)

还有一个用户子class :

class User(models.Model):
    name = models.FieldChar()
    password = models.FieldChar()
    age = models.FieldInteger()

当我从 User 实例调用 listAttributes 方法时,我没有得到我所期望的,但可能是我应该得到的:meta var 仅包含 className.以下是我如何调用该方法:

from modules.users import user
user = user.User()
user.listAttributes()

当我重写 User() 中的 listAttributes 方法时,行为相同:

def listAttributes(self):
    meta = vars(self)
    print(meta)

有没有办法列出我从中调用 listAttributes 方法的对象的属性?

谢谢你的灯!

您可以将 listAttributes 方法设为 class 方法并尝试以下操作:

class Model(object):
    @classmethod
    def listAttributes(cls):
        return [
            a for a in dir(cls) if not
            callable(getattr(cls, a)) and not 
            a.startswith("__")
        ]

如果您只想拥有 "Fields" 类型的属性(FieldChar、FieldInt...),那么您可以为字段创建一个基础 class,例如ModelField 并根据此基本类型检查您的属性:

class Model(object):
    @classmethod
    def listAttributes(cls):
        attributes = []
        for a in dir(cls):
            if ((not callable(getattr(cls, a)) and not
                 a.startswith("__") and
                 getattr(cls, a).__class__.__bases__[0] == ModelField)):
                attributes.append(a)

您甚至可以 return 对象而不仅仅是名称。或者将对象附加到您的模型 class 中的字典(以便在您的代码中更容易使用)。我这样构建我的 ORM:

class ModelField(object):
    ...

class IntField(ModelField):
    ...

class Model(object):
    id = IntField(pk=True)

    def __init__(self, *args, **kwargs):
        try:
            self.modelFields
        except AttributeError:
            self.__class__.introspect()
        for key, modelfield in self.modelFields.items():
            setattr(self, key, kwargs.get(key, None))

    @classmethod
    def introspect(cls):
        cls.modelFields = {}
        for a in dir(cls):
            if ((not callable(getattr(cls, a)) and not
                 a.startswith("__") and
                 getattr(cls, a).__class__.__bases__[0] == ModelField)):
                cls.modelFields[a] = getattr(cls, a)

然后我使用 cls.introspect 来设置 modelFields 字典并使用这个字典来例如使用 ModelField class.

的属性自动生成 db-table 或构造查询