且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

ndb模型-检索属性名称的有序集合

更新时间:2023-11-29 15:08:40

据我所知,如果不自己解析源代码,这是不可能的.幸运的是,以python的含电池"心态,这并不难.您可以使用inspect来获取源代码,然后可以使用ast来解析源代码并对其进行排序:

To my knowledge, this isn't possible without parsing the source for yourself. Luckily, with python's "batteries included" mentality, this isn't too hard. You can use inspect to get the source code and then you can use ast to parse the source and order things:

import ast
import inspect

class NodeTagger(ast.NodeVisitor):
    def __init__(self):
        self.class_attribute_names = {}

    def visit_Assign(self, node):
        for target in node.targets:
            self.class_attribute_names[target.id] = target.lineno

    # Don't visit Assign nodes inside Function Definitions.
    def visit_FunctionDef(self, unused_node):
        return None

def order_properties(model):
    properties = model._properties
    source = inspect.getsource(model)
    tree = ast.parse(source)
    visitor = NodeTagger()
    visitor.visit(tree)
    attributes = visitor.class_attribute_names
    model._ordered_property_list = sorted(properties, key=lambda x:attributes[x])
    return model


@order_properties
class Foo(object):
    c = 1
    b = 2
    a = 3

    # Add a _properties member to simulate an `ndb.Model`.
    _properties = {'a': object, 'b': object, 'c': object}

print Foo._ordered_property_list

请注意,这里的方法几乎是通用的.我使用了ndb.Model具有_properties属性的知识,但是可以从dirinspect.getmembers收集信息,因此可以修改order_properties使其完全正常工作.

Note that the approach here is almost general. I used the knowledge that ndb.Models have a _properties attribute, but that information could probably be gleaned from dir or inspect.getmembers so order_properties could be modified so that it works completely generally.