首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >inspect.getmembers按顺序吗?

inspect.getmembers按顺序吗?
EN

Stack Overflow用户
提问于 2010-07-03 04:47:13
回答 6查看 4.8K关注 0票数 26

inspect.getmembers(宾语,谓语)

返回按名称排序的(name, value)对列表中对象的所有成员。

我想使用这个方法,但是我不希望对成员进行排序。我希望它们以定义的相同顺序返回。有没有替代这种方法的方法?

我的用例是创建一个这样的表单:

代码语言:javascript
复制
class RegisterForm(Form):
    username = Field(model_field='username', filters=validators.minlength(3))
    password1 = Field(model_field='password', widget=widgets.PasswordInput)
    password2 = Field(widget=widgets.PasswordInput)
    first_name = Field(model_field='first_name')
    last_name = Field(model_field='last_name')
    address = SubForm(form=AddressForm, model_field='address')

我希望字段以定义的相同顺序呈现。

EN

回答 6

Stack Overflow用户

发布于 2010-07-03 05:16:28

您可以深入查找方法的行号,但不确定其他成员:

代码语言:javascript
复制
import inspect

class A:
    def one(self):
        pass

    def two(self):
        pass

    def three(self):
        pass

    def four(self):
        pass

def linenumber_of_member(m):
    try:
        return m[1].__func__.__code__.co_firstlineno
    except AttributeError:
        return -1

a = A()
l = inspect.getmembers(a)
print(l)
l.sort(key=linenumber_of_member)
print(l)

打印:

代码语言:javascript
复制
[('__doc__', None), ('__module__', '__main__'), ('four', <bound method A.four of <__main__.A instance at 0x0179F738>>), ('one', <bound method A.one of <__main__.A instance at 0x0179F738>>), ('three', <bound method A.three of <__main__.A instance at 0x0179F738>>), ('two', <bound method A.two of <__main__.A instance at 0x0179F738>>)]
[('__doc__', None), ('__module__', '__main__'), ('one', <bound method A.one of <__main__.A instance at 0x0179F738>>), ('two', <bound method A.two of <__main__.A instance at 0x0179F738>>), ('three', <bound method A.three of <__main__.A instance at 0x0179F738>>), ('four', <bound method A.four of <__main__.A instance at 0x0179F738>>)]
票数 14
EN

Stack Overflow用户

发布于 2010-07-03 05:23:39

对象的属性(方法和其他成员)通常是通过对象的特殊__dict__属性来查找的,这是一个标准的Python字典。它不能保证任何特定的顺序。

如果在对象的__dict__中找不到属性,则会搜索该类的属性(方法通常驻留在其中),依此类推,直到遍历完整个继承链。

以下是在交互式提示符中执行的一些自定义检查,以说明这一点(Python 3.1):

代码语言:javascript
复制
>>> class Klass():
...     def test(self):
...             pass
...
>>> k = Klass()
>>> k.__dict__
{}
>>> k.__class__.__dict__.items()
[('test', <function test at 0x00000000024113C8>), ('__dict__', <attribute '__dic
t__' of 'Klass' objects>), ('__module__', '__main__'), ('__weakref__', <attribut
e '__weakref__' of 'Klass' objects>), ('__doc__', None)]

如果我在Klass中放置一个构造函数(__init__)并通过self设置一个属性,它就会在k.__dict__中显示出来。

您可以通过使用自定义元类来规避这一点。文档中包含一个示例,它可以执行您想要的操作。

请参阅此页面底部的OrderedClass example

不知道你有什么版本的Python,所以我假设是最新的。

票数 5
EN

Stack Overflow用户

发布于 2010-07-03 08:19:14

我不认为Python2.6有__prepare__方法,所以我不能把默认的dict换成有序的。但是,我可以使用metaclass__new__方法替换它。与检查行号相比,我认为只使用创建计数器更容易、更高效。

代码语言:javascript
复制
class MetaForm(type):
    def __new__(cls, name, bases, attrs):
        attrs['fields'] = OrderedDict(
            sorted(
                [(name, attrs.pop(name)) for name, field in attrs.items() if isinstance(field, Field)],
                key=lambda t: t[1].counter
            )
        )
        return type.__new__(cls, name, bases, attrs)

class Form(object):
    __metaclass__ = MetaForm

class Field(object):
    counter = 0
    def __init__(self):
        self.counter = Field.counter
        Field.counter += 1
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3169014

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档