是否有一种方法可以获取类实例上存在的属性列表?
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"。我希望它能看到脚本各个部分的当前属性。
当前回答
attributes_list = [attribute for attribute in dir(obj) if attribute[0].islower()]
其他回答
使用__dict__或vars是无效的,因为它会遗漏__slots__。 使用__dict__和__slots__不能工作,因为它从基类中遗漏了__slots__。 使用dir不能工作,因为它包含类属性,如方法或属性,以及对象属性。 使用vars相当于使用__dict__。
这是我最好的:
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
>>> ', '.join(i for i in dir(a) if not i.startswith('__'))
'multi, str'
这当然会打印类定义中的任何方法或属性。你可以通过将i.startwith('__')更改为i.startwith('_')来排除“私有”方法。
>>> 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有帮助。
人们经常提到,要列出一个完整的属性列表,应该使用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)
你要这个干什么?如果不知道你的确切意图,可能很难得到最好的答案。
It is almost always better to do this manually if you want to display an instance of your class in a specific way. This will include exactly what you want and not include what you don't want, and the order will be predictable. If you are looking for a way to display the content of a class, manually format the attributes you care about and provide this as the __str__ or __repr__ method for your class. If you want to learn about what methods and such exist for an object to understand how it works, use help. help(a) will show you a formatted output about the object's class based on its docstrings. dir exists for programatically getting all the attributes of an object. (Accessing __dict__ does something I would group as the same but that I wouldn't use myself.) However, this may not include things you want and it may include things you do not want. It is unreliable and people think they want it a lot more often than they do. On a somewhat orthogonal note, there is very little support for Python 3 at the current time. If you are interested in writing real software you are going to want third-party stuff like numpy, lxml, Twisted, PIL, or any number of web frameworks that do not yet support Python 3 and do not have plans to any time too soon. The differences between 2.6 and the 3.x branch are small, but the difference in library support is huge.