这个问题在这里已经有了答案:是否有一个内置函数可以打印对象的所有当前属性和值? (29 个回答) 去年关闭。
有没有办法获取类实例中存在的属性列表?
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”。我希望它可以查看脚本各个部分的当前属性。
NewClass
。如果您使用像 new_class
这样的命名约定,您可能会违背人们的期望。
help()
函数有助于获取有关类、函数、内置函数、模块等的信息
>>> 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(instance)
# or (same value)
instance.__dir__()
# or
instance.__dict__
然后您可以使用 type()
测试什么类型,或者使用 callable()
测试是否是方法。
boston
数据集上获得所有可用属性的函数 - __dict__
是空的,而实际上有 5 个可用属性
之前的所有答案都是正确的,您有三个选项可以满足您的要求
dir() vars() __dict__
>>> 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'}
vars(foo)
返回 foo.__dict__
vars(obj)
返回对象的属性。
inspect 模块提供了几个有用的函数来帮助获取有关活动对象的信息,例如模块、类、方法、函数、回溯、框架对象和代码对象。
使用 getmembers()
,您可以查看类的所有属性及其值。要排除私有或受保护的属性,请使用 .startswith('_')
。要排除方法或函数,请使用 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
inst = NewClass(2)
for i in inspect.getmembers(inst):
# 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
的第二个元素,因为第一个元素只是一个字符串(其名称)。
Offtopic:使用 CamelCase 作为类名。
>>> ', '.join(i for i in dir(a) if not i.startswith('__'))
'multi, str'
这当然会打印类定义中的任何方法或属性。您可以通过将 i.startwith('__')
更改为 i.startwith('_')
来排除“私有”方法
您可以使用 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()
。但请注意,与普遍看法相反,dir()
并没有带出 所有 属性。例如,您可能会注意到类的 dir()
列表中可能缺少 __name__
,即使您可以从类本身访问它。来自 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)
有不止一种方法可以做到:
#! /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$
你要这个干什么?如果不知道您的确切意图,可能很难为您提供最佳答案。
如果您想以特定方式显示类的实例,手动执行此操作几乎总是更好。这将准确包括您想要的内容,而不包括您不想要的内容,并且顺序将是可预测的。如果您正在寻找一种显示类内容的方法,请手动格式化您关心的属性,并将其作为类的 __str__ 或 __repr__ 方法提供。
如果您想了解对象存在哪些方法等以了解其工作原理,请使用帮助。 help(a) 将根据其文档字符串向您显示有关对象类的格式化输出。
dir 用于以编程方式获取对象的所有属性。 (访问 __dict__ 会做一些我认为相同但我不会使用自己的事情。)但是,这可能不包括你想要的东西,它可能包括你不想要的东西。这是不可靠的,人们认为他们比他们更想要它。
在某种程度上正交的说明,目前对 Python 3 的支持很少。如果您对编写真正的软件感兴趣,您将需要第三方的东西,例如 numpy、lxml、Twisted、PIL 或任何数量的尚不支持 Python 3 并且没有计划很快推出的 Web 框架。 2.6 和 3.x 分支之间的差异很小,但库支持的差异很大。
请查看已按顺序执行的python shell脚本,在这里您将获得一个以逗号分隔的字符串格式的类的属性。
>>> 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
a.__dict__.keys()
。但是,如果您想知道一个对象是否具有特定属性,您可以使用 hasattr
。
除了这些答案之外,我还将包含一个函数(python 3),用于几乎吐出任何值的整个结构。它使用 dir
建立属性名称的完整列表,然后对每个名称使用 getattr
。它显示值的每个成员的类型,并在可能的情况下还显示整个成员:
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.
获取对象的属性
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}
注意 1:Python 是一种动态语言,最好了解您尝试从中获取属性的类,因为即使此代码也可能会遗漏某些情况。
注意2:此代码仅输出实例变量,这意味着未提供类变量。例如:
class A(object):
url = 'http://stackoverflow.com'
def __init__(self, path):
self.path = path
print(A('/questions').__dict__)
代码输出:
{'path': '/questions'}
此代码不会打印 url
类属性,并且可能会省略想要的类属性。
有时我们可能认为属性是实例成员,但它不是,也不会在本示例中显示。
__dict__
和 __slots__
,因此您可能想同时尝试这两种方法,而不仅仅是 dict。
使用 __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
请按顺序看下面的 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']
>>>
attributes_list = [attribute for attribute in dir(obj) if attribute[0].islower()]
__attrs__
给出实例的属性列表。
>>> 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/'
>>>
__attr__
,但在代码中使用 __attrs__
。都不适合我(werkzeug.datastructures.FileStorage)
不定期副业成功案例分享
pprint.pprint(a.__dict__)
对属性进行了漂亮的打印。__slots__
而不是__dict__
,这将不起作用,并且如果它同时具有两者,则将模糊地部分起作用。