列出对象的属性

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

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) >>> a.__dict__ {'multi': 4, 'str': '2'} >>> a.__dict__.keys() dict_keys(['multi', 'str']) 

你也可以find有帮助的。

 dir(instance) # or instance.__dict__ 

然后你可以testingtype()是什么types,或者是一个callable()方法。

vars(obj)返回一个对象的属性。

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

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

检查模块提供了检查对象的简单方法:

检查模块提供了几个有用的function来帮助获取有关活动对象的信息,如模块,类,方法,函数,回溯,框架对象和代码对象。


使用getmembers()你可以看到你的类的所有属性,以及它们的值。 要排除私人或受保护的属性,请使用.startswith('_') 。 要排除方法或function,请使用inspect.ismethod()inspect.isfunction()

 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) 

请注意, ismethod()用于i的第二个元素,因为第一个只是一个string(它的名字)。

Offtopic:使用CamelCase作为类名。

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

  • 如果要以特定方式显示类的实例,则手动执行此操作几乎总是更好。 这将包括你想要的东西,不包括你不想要的东西,订单将是可预测的。

    如果您正在寻找一种显示类内容的方式,请手动格式化您关心的属性,并将其作为类的__str____repr__方法提供。

  • 如果你想了解一个对象有什么方法和方法来理解它是如何工作的,请使用helphelp(a)将根据其文档显示关于对象类的格式化输出。

  • dir存在以编程方式获取对象的所有属性。 (访问__dict__做一些我会分组的东西,但我不会使用自己。)但是,这可能不包括你想要的东西,它可能包括你不想要的东西。 这是不可靠的,人们认为他们比他们想得更多。

  • 在一个有点正交的说明中,目前对Python 3的支持很less。 如果你有兴趣编写真正的软件,你将需要像numpy,lxml,Twisted,PIL或任何数量的尚不支持Python 3的Web框架的第三方的东西,并没有太多的计划。 2.6和3.x分支之间的差别很小,但是库支持的差异是巨大的。

经常提到要列出一个完整的属性列表,你应该使用dir() 。 但是请注意,与stream行的看法相反, dir()并不能带出所有的属性。 例如,您可能会注意到, __name__可能从类的dir()列表中丢失,即使您可以从类本身访问它。 从dir() ( Python 2 , Python 3 )上的文档:

因为dir()主要是为了方便在交互式提示符下使用而提供的,所以它试图提供一组有趣的名称,而不是试图提供严格或一致定义的名称集,而且其详细行为可能会在不同版本之间发生变化。 例如,当参数是一个类时,元类属性不在结果列表中。

类似下面的函数往往会更完整,尽pipe不能保证完整性,因为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) 

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

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

请依次看下面的Python shell脚本执行,它会给出从创build类到提取实例字段名的解决scheme。

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

如前所述,使用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} 

注1:
Python是一种dynamic语言,它总是更好地知道你试图获得属性的类,因为即使这个代码可能会错过一些情况。

笔记2:
此代码只输出实例variables,表示不提供类variables。 例如:

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

代码输出:

 {'path': '/questions'} 

此代码不会打印url类属性,并可能省略想要的类属性。
有时我们可能会认为一个属性是一个实例成员,但是不会,也不会使用这个例子来显示。

 attributes_list = [attribute for attribute in dir(obj) if attribute[0].islower()]