假设我有一个如下所示的课程,
class TestClass(object):
def __init__(self):
self.name = 'Marty'
self.age = 25
self.place = 'CL'
@property
def country(self):
return 'USA'
@property
def age_group(self):
return '18-25'
我想从所有@properties中创建一个dict。我尝试使用__dict__
和vars
,但@property
仍未显示。我怎样才能包含@property
。
>>> x = TestClass()
>>> x.__dict__
{'age': 25, 'name': 'Marty', 'place': 'CL'}
>>> vars(x)
{'age': 25, 'name': 'Marty', 'place': 'CL'}
我希望将age_group
和country
包含在返回值中作为键和值。
答案 0 :(得分:3)
使用迭代对象属性的字典理解:
obj = TestClass()
object_dict = {attr: getattr(obj, attr) for attr in dir(obj)}
如果你真的只想要问题中不清楚的@property
属性,你可以像这样过滤它们:
object_properties_dict = {attr: getattr(obj, attr) for attr in dir(obj.__class__) if type(getattr(obj.__class__, attr)) is property}
答案 1 :(得分:3)
您可以在实例上调用dir
来获取所需的名称。但是,dir
返回的列表也有一堆你不想要的名称(继承自object
的方法的名称),所以我们需要过滤那些进行。
class TestClass(object):
def __init__(self):
self.name = 'Marty'
self.age = 25
self.place = 'CL'
@property
def country(self):
return 'USA'
@property
def age_group(self):
return '18-25'
x = TestClass()
d = {k: getattr(x, k) for k in dir(x) if not k.startswith('__')}
print(d)
<强>输出强>
{'age': 25, 'age_group': '18-25', 'country': 'USA', 'name': 'Marty', 'place': 'CL'}
这是一种更清洁的方法。我们循环遍历类对象的vars()
,特别是查找property
个实例的项目。然后我们使用itertools.chain
将这些名称与在类的实例上调用vars()
的名称组合。
from itertools import chain
class TestClass(object):
def __init__(self):
self.name = 'Marty'
self.age = 25
self.place = 'CL'
@property
def country(self):
return 'USA'
@property
def age_group(self):
return '18-25'
def do_stuff(self):
return 'hello'
def attributes_and_properties(obj):
props = (k for k, ktype in vars(type(obj)).items()
if isinstance(ktype, property))
return {k: getattr(obj, k) for k in chain(props, vars(obj))}
x = TestClass()
print(attributes_and_properties(x))
<强>输出强>
{'country': 'USA', 'age_group': '18-25', 'name': 'Marty', 'age': 25, 'place': 'CL'}
这种方式优于以前的技术,因为该代码还将在其输出中包含名称不以__
开头的绑定方法,如do_stuff
。