您知道是否有一个内置函数可以从任意对象构建字典吗?我想这样做:
>>> class Foo:
... bar = 'hello'
... baz = 'world'
...
>>> f = Foo()
>>> props(f)
{ 'bar' : 'hello', 'baz' : 'world' }
注意:它不应该包括方法。只有字段。
您知道是否有一个内置函数可以从任意对象构建字典吗?我想这样做:
>>> class Foo:
... bar = 'hello'
... baz = 'world'
...
>>> f = Foo()
>>> props(f)
{ 'bar' : 'hello', 'baz' : 'world' }
注意:它不应该包括方法。只有字段。
当前回答
正如上面的一条评论中提到的,vars目前不是通用的,因为它不适用于具有__slots__而不是普通__dict__的对象。此外,一些对象(例如,str或int等内置对象)既没有__dict__也没有__slots__。
目前,一个更通用的解决方案可能是:
def instance_attributes(obj: Any) -> Dict[str, Any]:
"""Get a name-to-value dictionary of instance attributes of an arbitrary object."""
try:
return vars(obj)
except TypeError:
pass
# object doesn't have __dict__, try with __slots__
try:
slots = obj.__slots__
except AttributeError:
# doesn't have __dict__ nor __slots__, probably a builtin like str or int
return {}
# collect all slots attributes (some might not be present)
attrs = {}
for name in slots:
try:
attrs[name] = getattr(obj, name)
except AttributeError:
continue
return attrs
例子:
class Foo:
class_var = "spam"
class Bar:
class_var = "eggs"
__slots__ = ["a", "b"]
>>> foo = Foo()
>>> foo.a = 1
>>> foo.b = 2
>>> instance_attributes(foo)
{'a': 1, 'b': 2}
>>> bar = Bar()
>>> bar.a = 3
>>> instance_attributes(bar)
{'a': 3}
>>> instance_attributes("baz")
{}
咆哮:
遗憾的是,这还没有内置到vars中。Python中的许多内建承诺是问题的“解决方案”,但总有一些特殊情况没有得到处理……在任何情况下,最终都必须手动编写代码。
其他回答
Dataclass(来自Python 3.7)是另一个可用于将类属性转换为dict的选项。Asdict可以与数据类对象一起使用 为了转换。
例子:
@dataclass
class Point:
x: int
y: int
p = Point(10, 20)
asdict(p) # it returns {'x': 10, 'y': 20}
我认为最简单的方法是为类创建一个getitem属性。如果需要写入对象,可以创建自定义setattr。下面是一个getitem的例子:
class A(object):
def __init__(self):
self.b = 1
self.c = 2
def __getitem__(self, item):
return self.__dict__[item]
# Usage:
a = A()
a.__getitem__('b') # Outputs 1
a.__dict__ # Outputs {'c': 2, 'b': 1}
vars(a) # Outputs {'c': 2, 'b': 1}
Dict将对象属性生成到字典中,可以使用字典对象获取所需的项。
Vars()很棒,但不适用于对象的嵌套对象
将对象的嵌套对象转换为dict:
def to_dict(self):
return json.loads(json.dumps(self, default=lambda o: o.__dict__))
我给出了两个答案的组合:
dict((key, value) for key, value in f.__dict__.iteritems()
if not callable(value) and not key.startswith('__'))
回答晚了,但为了完整性和谷歌人的利益:
def props(x):
return dict((key, getattr(x, key)) for key in dir(x) if key not in dir(x.__class__))
这将不会显示类中定义的方法,但仍然会显示字段,包括那些分配给lambdas的字段或那些以双下划线开头的字段。