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

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"。我希望它能看到脚本各个部分的当前属性。


当前回答

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

举个更有弹性的例子:

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))

这段代码的输出:

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

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

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

class A(object):
    url = 'http://stackoverflow.com'
    def __init__(self, path):
        self.path = path

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

代码输出:

{'path': '/questions'}

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

其他回答

除了这些答案之外,我还将包括一个函数(python 3),用于输出任何值的几乎整个结构。它使用dir来建立属性名的完整列表,然后对每个名称使用getattr。它会显示值的每个成员的类型,如果可能的话还会显示整个成员:

import json

def get_info(obj):

  type_name = type(obj).__name__
  print('Value is of type {}!'.format(type_name))
  prop_names = dir(obj)

  for prop_name in prop_names:
    prop_val = getattr(obj, prop_name)
    prop_val_type_name = type(prop_val).__name__
    print('{} has property "{}" of type "{}"'.format(type_name, prop_name, prop_val_type_name))

    try:
      val_as_str = json.dumps([ prop_val ], indent=2)[1:-1]
      print('  Here\'s the {} value: {}'.format(prop_name, val_as_str))
    except:
      pass

现在,以下任何一项都应该让你有所了解:

get_info(None)
get_info('hello')

import numpy
get_info(numpy)
# ... etc.
>>> 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有帮助。

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

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

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

>>> 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

做这件事的方法不止一种:

#! /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) )

当运行时,这段代码产生:

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$