是否有一种方法可以获取类实例上存在的属性列表?
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"。我希望它能看到脚本各个部分的当前属性。
是否有一种方法可以获取类实例上存在的属性列表?
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"。我希望它能看到脚本各个部分的当前属性。
当前回答
请参见以下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']
>>>
其他回答
人们经常提到,要列出一个完整的属性列表,应该使用dir()。但是请注意,与普遍观点相反,dir()并没有显示所有属性。例如,你可能会注意到__name__可能在类的dir()列表中缺失,即使你可以从类本身访问它。从dir()的文档(Python 2, Python 3):
因为提供dir()主要是为了方便在 交互式提示符,它试图提供一组有趣的名称 它不仅仅是试图提供一个严格或一致定义的集合 的名称,其详细行为可能在不同版本之间更改。为 属性时,元类属性不在结果列表中 参数是一个类。
像下面这样的函数往往更完整,尽管不能保证完整性,因为dir()返回的列表可能受到许多因素的影响,包括实现__dir__()方法,或在类或其父类之一上自定义__getattr__()或__getattribute__()。详情请参阅所提供的链接。
def dirmore(instance):
visible = dir(instance)
visible += [a for a in set(dir(type)).difference(visible)
if hasattr(instance, a)]
return sorted(visible)
获取对象的属性
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
如前所述,使用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类属性,可能会省略所需的类属性。 有时,我们可能认为属性是实例成员,但它不是,也不会在本例中显示。
你可以使用dir(your_object)来获取属性,使用getattr(your_object, your_object_attr)来获取值
用法:
for att in dir(your_object):
print (att, getattr(your_object,att))
如果你的对象没有__dict__,这特别有用。如果不是这样,你也可以尝试var(your_object)
dir(instance)
# or (same value)
instance.__dir__()
# or
instance.__dict__
然后可以用type()测试类型是什么,或者用callable()测试是否为方法。