【问题标题】:Print all properties of a Python Class [duplicate]打印 Python 类的所有属性 [重复]
【发布时间】:2011-08-23 14:40:18
【问题描述】:

我有一个 Animal 类,它有几个属性,例如:


class Animal(object):
    def __init__(self):
        self.legs = 2
        self.name = 'Dog'
        self.color= 'Spotted'
        self.smell= 'Alot'
        self.age  = 10
        self.kids = 0
        #many more...

我现在想将所有这些属性打印到一个文本文件中。我现在这样做的丑陋方式是:


animal=Animal()
output = 'legs:%d, name:%s, color:%s, smell:%s, age:%d, kids:%d' % (animal.legs, animal.name, animal.color, animal.smell, animal.age, animal.kids,)

有没有更好的 Pythonic 方式来做到这一点?

【问题讨论】:

标签: python oop


【解决方案1】:

在这个简单的例子中你可以使用vars():

an = Animal()
attrs = vars(an)
# {'kids': 0, 'name': 'Dog', 'color': 'Spotted', 'age': 10, 'legs': 2, 'smell': 'Alot'}
# now dump this in some way or another
print(', '.join("%s: %s" % item for item in attrs.items()))

如果你想在磁盘上存储 Python 对象,你应该查看shelve — Python object persistence

【讨论】:

  • 哦,太好了,从来没有这样使用过vars!我以为它就像locals(),不知道你可以在类/模块上使用它。很有用!
  • vars 仅在您使用 __dict__ 存储属性时才有效(这是 Python 对象的默认行为)。如果您使用的是__slots__,请参考@BasicWolf 的回答
  • 请注意,这样您会得到无序的结果。如果您需要按声明顺序打印,并且不想手动执行,请检查this
  • 你将如何使用它来打印类似:an.name = Dog?我尝试了以下,不起作用。 '''f.write('\n'.join(["{}.{} = '{}'".format(myname.name, (k for k in myname.__dict__.keys()),(v for v in myname.__dict__.values()))]))'''
  • TypeError: vars() argument must have __dict__ attribute
【解决方案2】:

另一种方法是调用dir() 函数(参见https://docs.python.org/2/library/functions.html#dir)。

a = Animal()
dir(a)   
>>>
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__',
 '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', 
 '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 
 '__weakref__', 'age', 'color', 'kids', 'legs', 'name', 'smell']

请注意,dir() 会尝试访问任何可能访问的属性。

然后您可以访问属性,例如通过双下划线过滤:

attributes = [attr for attr in dir(a) 
              if not attr.startswith('__')]

这只是dir() 可以做的一个例子,请查看其他答案以了解正确的做法。

【讨论】:

  • 这可能是正确的方法,但应该指出的是,它所做的是打印出 attributes,而不是 Python 中新式类中称为 Properties 的东西,并且它是基于类的 instance 而不是类本身(因为这些属性在创建类实例并调用 __init__() 之前不存在)。此外,如果稍后创建任何其他属性,显然它们将被省略。
  • 确实如此。但我敢打赌,要教给一个人 Python 动态构造(对象、类型、元类、类)的压倒性力量真的很难,除非你面对它们。
  • 绝对是我想要的。谢谢。
  • 更好的过滤(通过stackoverflow.com/questions/1398022/…上的user235925)[attr for attr in dir(a) if not callable(getattr(Animal,attr)) 而不是 attr.startswith("__")]
  • 这是一种检查任何对象的快速简便的方法,因为不熟悉的对象可能看起来像一个“暗箱”,您可以“揭开”它的方法和属性。
【解决方案3】:

也许您正在寻找类似的东西?

    >>> class MyTest:
        def __init__ (self):
            self.value = 3
    >>> myobj = MyTest()
    >>> myobj.__dict__
    {'value': 3}

【讨论】:

  • 注意,因为这给了你一个字典,如果你想要一个快速的 API 参考print(o.__dict__.keys()),你也可以只看键。
【解决方案4】:

试试ppretty:

from ppretty import ppretty


class Animal(object):
    def __init__(self):
        self.legs = 2
        self.name = 'Dog'
        self.color= 'Spotted'
        self.smell= 'Alot'
        self.age  = 10
        self.kids = 0


print ppretty(Animal(), seq_length=10)

输出:

__main__.Animal(age = 10, color = 'Spotted', kids = 0, legs = 2, name = 'Dog', smell = 'Alot')

【讨论】:

    【解决方案5】:

    这是完整的代码。结果正是您想要的。

    class Animal(object):
        def __init__(self):
            self.legs = 2
            self.name = 'Dog'
            self.color= 'Spotted'
            self.smell= 'Alot'
            self.age  = 10
            self.kids = 0
    
    if __name__ == '__main__':
        animal = Animal()
        temp = vars(animal)
        for item in temp:
            print item , ' : ' , temp[item]
            #print item , ' : ', temp[item] ,
    

    【讨论】:

      【解决方案6】:

      试试beeprint

      它打印出这样的东西:

      instance(Animal):
          legs: 2,
          name: 'Dog',
          color: 'Spotted',
          smell: 'Alot',
          age: 10,
          kids: 0,
      

      我认为正是你需要的。

      【讨论】:

      • 如果您是 SQLAlchemy 用户,则无法正确显示对象的内容。
      • @paulochf...请解释...只是仔细检查...我们在这里谈论的是python而不是SQL...
      • 如果引用的 Python 类是 SqlAlchemy 模型,则可能需要打印其所有属性。
      猜你喜欢
      • 2016-03-21
      • 2010-10-25
      • 2013-07-11
      • 1970-01-01
      • 1970-01-01
      • 2018-06-28
      • 2018-08-04
      • 2016-12-27
      • 1970-01-01
      相关资源
      最近更新 更多