关于Python列表在对象属性

List attributes of an object

是否有方法获取类实例上存在的属性列表?

1
2
3
4
5
6
7
class new_class():
    def __init__(self, number):
        self.multi = int(number) * 2
        self.str = str(number)

a = new_class(2)
print(', '.join(a.SOMETHING))

期望的结果是输出"multi,str"。我希望看到脚本各个部分的当前属性。


1
2
3
4
5
6
7
8
9
10
>>> class new_class():
...   def __init__(self, number):
...     self.multi = int(number) * 2
...     self.str = str(number)
...
>>> a = new_class(2)
>>> a.__dict__
{'multi': 4, 'str': '2'}
>>> a.__dict__.keys()
dict_keys(['multi', 'str'])

您也可能会发现pprint很有用。


1
2
3
4
5
dir(instance)
# or (same value)
instance.__dir__()
# or
instance.__dict__

然后您可以使用type()测试什么类型,或者如果是使用callable()的方法。


vars(obj)返回对象的属性。


1
2
>>> ', '.join(i for i in dir(a) if not i.startswith('__'))
'multi, str'

当然,这将打印类定义中的任何方法或属性。通过将i.startwith('__')更改为i.startwith('_')可以排除"私有"方法。


检查模块提供了检查对象的简单方法:

The inspect module provides several useful functions to help get
information about live objects such as modules, classes, methods,
functions, tracebacks, frame objects, and code objects.

使用getmembers()可以看到类的所有属性及其值。要排除私有或受保护的属性,请使用.startswith('_')。要排除方法或函数,请使用inspect.ismethod()inspect.isfunction()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import inspect


class NewClass(object):
    def __init__(self, number):
        self.multi = int(number) * 2
        self.str = str(number)

    def func_1(self):
        pass


a = NewClass(2)

for i in inspect.getmembers(a):
    # Ignores anything starting with underscore
    # (that is, private and protected attributes)
    if not i[0].startswith('_'):
        # Ignores methods
        if not inspect.ismethod(i[1]):
            print(i)

注意,ismethod()用于i的第二个元素,因为第一个元素只是一个字符串(其名称)。

offtopic:将camelcase用于类名。


所有之前的答案都是正确的,你有三个选择来回答你的问题。

1、()

2、变量()

3。

1
2
3
4
5
6
>>> dir(a)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'multi', 'str']
>>> vars(a)
{'multi': 4, 'str': '2'}
>>> a.__dict__
{'multi': 4, 'str': '2'}


请参阅已按顺序执行的python shell脚本,这里您将获得用逗号分隔的字符串格式的类的属性。

1
2
3
4
5
6
7
8
>>> class new_class():
...     def __init__(self, number):
...         self.multi = int(number)*2
...         self.str = str(number)
...
>>> a = new_class(4)
>>>",".join(a.__dict__.keys())
'str,multi'<br/>

我使用的是python 3.4


经常提到,要列出完整的属性列表,您应该使用dir()。但请注意,与流行的观点相反,dir()并没有显示出所有的属性。例如,您可能会注意到类的dir()列表中可能缺少__name__,即使您可以从类本身访问它。来自dir()上的文档(python2,python3):

Because dir() is supplied primarily as a convenience for use at an
interactive prompt, it tries to supply an interesting set of names
more than it tries to supply a rigorously or consistently defined set
of names, and its detailed behavior may change across releases. For
example, metaclass attributes are not in the result list when the
argument is a class.

虽然无法保证完整性,但像下面这样的函数往往更为完整,因为dir()返回的列表可能受到许多因素的影响,包括在类或其某个父类上实现__dir__()方法,或自定义__getattr__()__getattribute__()。有关详细信息,请参阅提供的链接。

1
2
3
4
5
def dirmore(instance):
    visible = dir(instance)
    visible += [a for a in set(dir(type)).difference(visible)
                if hasattr(instance, a)]
    return sorted(visible)

你想要这个做什么?如果不知道你的确切意图,可能很难找到最佳答案。

  • 如果您希望以特定的方式显示类的实例,那么手动执行此操作几乎总是更好的。这将完全包括您想要的,而不包括您不想要的,并且订单将是可预测的。

    如果您正在寻找显示类内容的方法,请手动格式化您关心的属性,并将其作为类的__str____repr__方法提供。

  • 如果您想了解对象如何工作的方法和方法,请使用helphelp(a)将根据对象的docstrings向您显示关于对象类的格式化输出。

  • dir用于编程获取对象的所有属性。(访问EDOCX1[7]会做一些我想分组的事情,但我不会使用自己。)但是,这可能不包括你想要的东西,也可能包括你不想要的东西。这是不可靠的,人们认为他们比他们更经常想要它。

  • 在某种程度上是正交的,目前很少支持Python3。如果你对编写真正的软件感兴趣,你会想要第三方的东西,比如numpy、lxml、twisted、pil,或者任何数量的Web框架,这些框架还不支持python 3,并且没有计划在任何时候太早。2.6和3.x分支之间的差异很小,但在库支持方面的差异很大。


有多种方法可以做到:

1
2
3
4
5
6
7
8
9
10
11
12
13
#! /usr/bin/env python3
#
# This demonstrates how to pick the attiributes of an object

class C(object) :

  def __init__ (self, name="q" ):
    self.q = name
    self.m ="y?"

c = C()

print ( dir(c) )

运行时,此代码生成:

1
2
3
4
jeffs@jeff-desktop:~/skyset$ python3 attributes.py
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__',      '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'm', 'q']

jeffs@jeff-desktop:~/skyset$


可以使用dir(your_object)获取属性,使用getattr(your_object, your_object_attr)获取值

用途:

1
2
for att in dir(your_object):
    print (att, getattr(your_object,att))

如果您的对象没有"听写",这尤其有用。如果不是这样,您也可以尝试var(您的_对象)


如在使用obj.__dict__之前所写,可以处理常见的情况,但有些类没有__dict__属性,并且使用__slots__(主要是为了提高内存效率)。

一个更具弹性的方法示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class A(object):
    __slots__ = ('x', 'y', )
    def __init__(self, x, y):
        self.x = x
        self.y = y


class B(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y


def get_object_attrs(obj):
    try:
        return obj.__dict__
    except AttributeError:
        return {attr: getattr(obj, attr) for attr in obj.__slots__}


a = A(1,2)
b = B(1,2)
assert not hasattr(a, '__dict__')

print(get_object_attrs(a))
print(get_object_attrs(b))

此代码的输出:

1
2
{'x': 1, 'y': 2}
{'x': 1, 'y': 2}

注1:python是一种动态语言,它总是更好地了解您试图从中获取属性的类,因为即使这段代码也可能遗漏一些情况。

注2:此代码只输出实例变量,这意味着不提供类变量。例如:

1
2
3
4
5
6
class A(object):
    url = 'http://stackoverflow.com'
    def __init__(self, path):
        self.path = path

print(A('/questions').__dict__)

代码输出:

1
{'path': '/questions'}

此代码不打印url类属性,可能会省略所需的类属性。有时,我们可能认为属性是实例成员,但它不是,也不会使用此示例显示。


请依次看到下面的python shell脚本执行,它将给出从创建类到提取实例字段名的解决方案。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
>>> class Details:
...       def __init__(self,name,age):
...           self.name=name
...           self.age =age
...       def show_details(self):
...           if self.name:
...              print"Name :",self.name
...           else:
...              print"Name :","_"
...           if self.age:
...              if self.age>0:
...                 print"Age  :",self.age
...              else:
...                 print"Age can't be -ve"
...           else:
...              print"Age  :","_"
...
>>> my_details = Details("Rishikesh",24)
>>>
>>> print my_details
<__main__.Details instance at 0x10e2e77e8>
>>>
>>> print my_details.name
Rishikesh
>>> print my_details.age
24
>>>
>>> my_details.show_details()
Name :  Rishikesh
Age  :  24
>>>
>>> person1 = Details("",34)
>>> person1.name
''
>>> person1.age
34
>>> person1.show_details
<bound method Details.show_details of <__main__.Details instance at 0x10e2e7758>>
>>>
>>> person1.show_details()
Name :  _
Age  :  34
>>>
>>> person2 = Details("Rob Pike",0)
>>> person2.name
'Rob Pike'
>>>
>>> person2.age
0
>>>
>>> person2.show_details()
Name :  Rob Pike
Age  :  _
>>>
>>> person3 = Details("Rob Pike",-45)
>>>
>>> person3.name
'Rob Pike'
>>>
>>> person3.age
-45
>>>
>>> person3.show_details()
Name :  Rob Pike
Age can't be -ve
>>>
>>> person3.__dict__
{'
age': -45, 'name': 'Rob Pike'}
>>>
>>> person3.__dict__.keys()
['
age', 'name']
>>>
>>> person3.__dict__.values()
[-45, '
Rob Pike']
>>>


1
attributes_list = [attribute for attribute in dir(obj) if attribute[0].islower()]


__attr__给出了一个实例的属性列表。

1
2
3
4
5
6
7
>>> import requests
>>> r=requests.get('http://www.google.com')
>>> r.__attrs__
['_content', 'status_code', 'headers', 'url', 'history', 'encoding', 'reason', 'cookies', 'elapsed', 'request']
>>> r.url
'http://www.google.com/'
>>>