问题:如何在Python中枚举对象的属性?

IC#我们通过反思来做到。在Javascript中,它很简单:

for(var propertyName in objectName)
    var currentPropertyValue = objectName[propertyName];

如何在Python中完成?

I C# we do it through reflection. In Javascript it is simple as:

for(var propertyName in objectName)
    var currentPropertyValue = objectName[propertyName];

How to do it in Python?


回答 0

for property, value in vars(theObject).iteritems():
    print property, ": ", value

请注意,在极少数情况下,有一个__slots__属性,此类通常没有属性__dict__

for property, value in vars(theObject).items():
    print(property, ":", value)

Be aware that in some rare cases there’s a __slots__ property, such classes often have no __dict__.


回答 1

请参阅inspect.getmembers(object[, predicate])

返回按名称排序的(名称,值)对列表中的对象的所有成员。如果提供了可选的谓词参数,则仅包含谓词为其返回真值的成员。

>>> [name for name,thing in inspect.getmembers([])]
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', 
'__delslice__',    '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', 
'__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', 
'__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__','__reduce_ex__', 
'__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', 
'__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 
'insert', 'pop', 'remove', 'reverse', 'sort']
>>> 

See inspect.getmembers(object[, predicate]).

Return all the members of an object in a list of (name, value) pairs sorted by name. If the optional predicate argument is supplied, only members for which the predicate returns a true value are included.

>>> [name for name,thing in inspect.getmembers([])]
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', 
'__delslice__',    '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', 
'__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', 
'__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__','__reduce_ex__', 
'__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', 
'__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 
'insert', 'pop', 'remove', 'reverse', 'sort']
>>> 

回答 2

dir()是简单的方法。看这里:

Python自省指南


回答 3

__dict__对象的属性是其所有其他定义的属性的字典。请注意,Python类可以覆盖getattr 并使内容看起来像属性,而不是in __dict__。还有一些内置函数vars()dir()它们在微妙的方式上有所不同。并且__slots__可以代替__dict__一些不寻常的类。

Python中的对象很复杂。__dict__是开始进行反射式编程的正确位置。dir()如果您是在交互式shell中四处乱逛,那么这是一个开始的地方。

The __dict__ property of the object is a dictionary of all its other defined properties. Note that Python classes can override getattr and make things that look like properties but are not in__dict__. There’s also the builtin functions vars() and dir() which are different in subtle ways. And __slots__ can replace __dict__ in some unusual classes.

Objects are complicated in Python. __dict__ is the right place to start for reflection-style programming. dir() is the place to start if you’re hacking around in an interactive shell.


回答 4

georg scholly短版

print vars(theObject)

for one-liners:

print vars(theObject)

回答 5

如果您正在寻找所有属性的反映,那么上面的答案很好。

如果您只是想获取字典的键(与Python中的“对象”不同),请使用

my_dict.keys()

my_dict = {'abc': {}, 'def': 12, 'ghi': 'string' }
my_dict.keys() 
> ['abc', 'def', 'ghi']

If you’re looking for reflection of all properties, the answers above are great.

If you’re simply looking to get the keys of a dictionary (which is different from an ‘object’ in Python), use

my_dict.keys()

my_dict = {'abc': {}, 'def': 12, 'ghi': 'string' }
my_dict.keys() 
> ['abc', 'def', 'ghi']

回答 6

其他答案完全涵盖了这一点,但我将使其明确。对象可以具有类属性以及静态和动态实例属性。

class foo:
    classy = 1
    @property
    def dyno(self):
        return 1
    def __init__(self):
        self.stasis = 2

    def fx(self):
        return 3

stasis是静态的,dyno是动态的(请参阅属性装饰器),并且classy是类属性。如果我们简单地做,__dict__否则vars我们只会得到静态的。

o = foo()
print(o.__dict__) #{'stasis': 2}
print(vars(o)) #{'stasis': 2}

因此,如果我们希望其他人__dict__都能得到一切(甚至更多)。这包括魔术方法和属性以及法线绑定方法。因此,请避免这些情况:

d = {k: getattr(o, k, '') for k in o.__dir__() if k[:2] != '__' and type(getattr(o, k, '')).__name__ != 'method'}
print(d) #{'stasis': 2, 'classy': 1, 'dyno': 1}

type具有属性修饰方法(动态属性)的调用将为您提供返回值的类型,而不是method。为了证明这一点,让我们用json将其字符串化:

import json
print(json.dumps(d)) #{"stasis": 2, "classy": 1, "dyno": 1}

如果这是一种方法,它将崩溃。

TL; DR。尝试同时调用extravar = lambda o: {k: getattr(o, k, '') for k in o.__dir__() if k[:2] != '__' and type(getattr(o, k, '')).__name__ != 'method'}这三个方法,但不要调用方法或魔术。

This is totally covered by the other answers, but I’ll make it explicit. An object may have class attributes and static and dynamic instance attributes.

class foo:
    classy = 1
    @property
    def dyno(self):
        return 1
    def __init__(self):
        self.stasis = 2

    def fx(self):
        return 3

stasis is static, dyno is dynamic (cf. property decorator) and classy is a class attribute. If we simply do __dict__ or vars we will only get the static one.

o = foo()
print(o.__dict__) #{'stasis': 2}
print(vars(o)) #{'stasis': 2}

So if we want the others __dict__ will get everything (and more). This includes magic methods and attributes and normal bound methods. So lets avoid those:

d = {k: getattr(o, k, '') for k in o.__dir__() if k[:2] != '__' and type(getattr(o, k, '')).__name__ != 'method'}
print(d) #{'stasis': 2, 'classy': 1, 'dyno': 1}

The type called with a property decorated method (a dynamic attribute) will give you the type of the returned value, not method. To prove this let’s json stringify it:

import json
print(json.dumps(d)) #{"stasis": 2, "classy": 1, "dyno": 1}

Had it been a method it would have crashed.

TL;DR. try calling extravar = lambda o: {k: getattr(o, k, '') for k in o.__dir__() if k[:2] != '__' and type(getattr(o, k, '')).__name__ != 'method'} for all three, but not methods nor magic.


声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。