来自对象字段的Python字典
时间:2020-03-05 18:53:02 来源:igfitidea点击:
我们是否知道是否有内置函数可以从任意对象构建字典?我想做这样的事情:
>>> class Foo: ... bar = 'hello' ... baz = 'world' ... >>> f = Foo() >>> props(f) { 'bar' : 'hello', 'baz' : 'world' }
注意:它不应包含方法。仅字段。
解决方案
回答
内置的dir将为我们提供对象的所有属性,包括特殊方法,如__str__,__dict__以及我们可能不希望使用的其他方法。但是我们可以执行以下操作:
>>> class Foo(object): ... bar = 'hello' ... baz = 'world' ... >>> f = Foo() >>> [name for name in dir(f) if not name.startswith('__')] [ 'bar', 'baz' ] >>> dict((name, getattr(f, name)) for name in dir(f) if not name.startswith('__')) { 'bar': 'hello', 'baz': 'world' }
因此可以通过定义如下的" props"函数将其扩展为仅返回数据属性而不返回方法:
import inspect def props(obj): pr = {} for name in dir(obj): value = getattr(obj, name) if not name.startswith('__') and not inspect.ismethod(value): pr[name] = value return pr
回答
我已经解决了两个答案的结合:
dict((key, value) for key, value in f.__dict__.iteritems() if not callable(value) and not key.startswith('__'))
回答
请注意,Python 2.7中的最佳实践是使用新型类(Python 3不需要),即
class Foo(object): ...
同样,"对象"和"类"之间也存在差异。要从任意对象构建字典,使用__dict__
就足够了。通常,我们将在类级别声明方法,并在实例级别声明属性,因此__dict__应该没问题。例如:
>>> class A(object): ... def __init__(self): ... self.b = 1 ... self.c = 2 ... def do_nothing(self): ... pass ... >>> a = A() >>> a.__dict__ {'c': 2, 'b': 1}
更好的方法(由robert建议在注释中使用)是内置的vars函数:
>>> vars(a) {'c': 2, 'b': 1}
另外,根据我们想做什么,最好继承自dict。然后班级已经是字典,并且如果我们愿意,可以覆盖getattr
和/或者setattr
来调用并设置字典。例如:
class Foo(dict): def __init__(self): pass def __getattr__(self, attr): return self[attr] # etc...
回答
To build a dictionary from an arbitrary object, it's sufficient to use __dict__.
这会错过对象从其类继承的属性。例如,
class c(object): x = 3 a = c()
hasattr(a,'x')是true,但是'x'不会出现在a中。dict