Python 列出对象的属性

Python 列出对象的属性,python,class,python-3.x,Python,Class,Python 3.x,有没有办法获取类实例上存在的属性列表 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”。我想让它看到脚本各个部分的当前属性 >>> ', '.join(i

有没有办法获取类实例上存在的属性列表

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”。我想让它看到脚本各个部分的当前属性

>>> ', '.join(i for i in dir(a) if not i.startswith('__'))
'multi, str'
这当然会打印类定义中的任何方法或属性。您可以通过将
i.startwith(''''u'')
更改为
i.startwith(''u'')
来排除“私有”方法


您可能也会发现有帮助。

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

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

    如果您正在寻找一种显示类内容的方法,请手动格式化您关心的属性,并为您的类提供
    \uuuuu str\uuuuuu
    \uuuu repr\uuuu
    方法

  • 如果您想了解对象的工作方式,可以使用
    help
    <代码>帮助(a)将根据对象的docstring显示有关对象类的格式化输出

  • dir
    用于以编程方式获取对象的所有属性。(访问
    \uuuu dict\uuuuuuu
    会做一些我想分组的事情,但我不会使用我自己)。但是,这可能不包括您想要的东西,也可能包括您不想要的东西。这是不可靠的,人们认为他们想要的比他们想要的多得多

  • 从某种程度上讲,目前对Python3的支持非常少。如果你对编写真正的软件感兴趣,你会想要第三方的东西,比如numpy、lxml、Twisted、PIL或任何数量的web框架,这些框架还不支持Python3,也不打算太快。2.6和3.x分支之间的差异很小,但在库支持方面的差异很大


然后,您可以使用
type()
测试类型,或者使用
callable()
测试方法是否为vars(obj)返回对象的属性。

执行此操作的方法不止一种:

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

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

因为提供dir()主要是为了方便在 交互式提示,它尝试提供一组有趣的名称 不仅仅是试图提供一个严格或一致定义的集合 其详细行为可能会随着版本的不同而变化。对于 例如,当 论点是一个类

像下面这样的函数往往更完整,尽管不能保证完整性,因为
dir()
返回的列表可能会受到许多因素的影响,包括实现
\uuuuuuuu dir()
方法,或者自定义
\uuuu getattr\uuuuuuuuu()
\uuuuuuuuu getattribute\uuuuuuuuuu()
在类或其家长之一上。有关更多详细信息,请参阅提供的链接

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

请按顺序查看下面的Python shell脚本执行,它将给出从创建类到提取实例字段名的解决方案

>>> 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']
>>>
>课程详细信息:
...       定义初始(自我、姓名、年龄):
...           self.name=name
...           self.age=年龄
...       def显示_详细信息(自我):
...           如果self.name:
...              打印“名称:”,self.Name
...           其他:
...              打印“名称:”,“\uux”
...           如果自我年龄:
...              如果自我年龄>0:
...                 打印“年龄:”,self.Age
...              其他:
...                 打印“不可能的年龄-ve”
...           其他:
...              打印“年龄:”,“ux”
... 
>>>my_details=详细信息(“Rishikesh”,24)
>>> 
>>>打印我的详细信息
>>> 
>>>打印我的详细信息
里希凯什
>>>打印我的详细信息
24
>>> 
>>>我的详细信息。显示详细信息()
姓名:Rishikesh
年龄:24
>>> 
>>>person1=详细信息(“,34)
>>>人名
''
>>>人的年龄
34
>>>人员1.显示详细信息
>>> 
>>>人员1.显示详细信息()
姓名:_
年龄:34
>>>
>>>person2=详细信息(“Rob Pike”,0)
>>>人名
“罗布派克”
>>> 
>>>人2.年龄
0
>>> 
>>>人员2.显示详细信息()
姓名:罗布派克
年龄:_
>>> 
>>>person3=详细信息(“Rob Pike”,-45)
>>> 
>>>人名
“罗布派克”
>>> 
>>>人的年龄
-45
>>> 
>>>人员3.显示详细信息()
姓名:罗布派克
年龄是不可能的
>>>
>>>第三个人__
{'age':-45,'name':'Rob Pike'}
>>>
>>>人员3.指令键()
[‘年龄’、‘姓名’]
>>>
>>>人员3.指令值()
[-45,‘罗伯·派克’]
>>>

如使用
obj之前所写。uuuu dict\uuuu
可以处理常见情况,但某些类没有
\uuuuuu dict\uuu
属性和用途(主要是为了内存效率)

更具弹性的方法示例:

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}
注1:
Python是一种动态语言,了解试图从中获取属性的类总是更好的,因为即使是这段代码也可能遗漏某些情况

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

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

print(A('/questions').__dict__)
代码输出:

{'path': '/questions'}
此代码不打印
url
类属性,可能会忽略所需的类属性。
有时,我们可能认为某个属性是实例成员,但它不是,也不会在本例中显示。

:

inspect模块提供了几个有用的函数来帮助 信息
{'x': 1, 'y': 2}
{'x': 1, 'y': 2}
class A(object):
    url = 'http://stackoverflow.com'
    def __init__(self, path):
        self.path = path

print(A('/questions').__dict__)
{'path': '/questions'}
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)
>>> 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/>
>>> 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/'
>>>
>>> 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'}
for att in dir(your_object):
    print (att, getattr(your_object,att))
class new_class():
    def __init__(self, number):
    self.multi = int(number) * 2
    self.str = str(number)

new_object = new_class(2)                
print(dir(new_object))                   #total list attributes of new_object
attr_value = new_object.__dict__         
print(attr_value)                        #Dictionary of attribute and value for new_class                   

for attr in attr_value:                  #attributes on  new_class
    print(attr)

['__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']

{'multi': 4, 'str': '2'}

multi
str
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.
from typing import Dict

def get_attrs( x : object ) -> Dict[str, object]:
    mro      = type( x ).mro()
    attrs    = { }
    has_dict = False
    sentinel = object()

    for klass in mro:
        for slot in getattr( klass, "__slots__", () ):
            v = getattr( x, slot, sentinel )

            if v is sentinel:
                continue

            if slot == "__dict__":
                assert not has_dict, "Multiple __dicts__?"
                attrs.update( v )
                has_dict = True
            else:
                attrs[slot] = v

    if not has_dict:
        attrs.update( getattr( x, "__dict__", { } ) )

    return attrs