Python dictionary from an object's fields
您知道是否有内置函数可以从任意对象构建字典吗?我想这样做:
1 2 3 4 5 6 7 | >>> class Foo: ... bar = 'hello' ... baz = 'world' ... >>> f = Foo() >>> props(f) { 'bar' : 'hello', 'baz' : 'world' } |
注:不应包括方法。只有字段。
注意,python 2.7中的最佳实践是使用新样式的类(不需要和python 3一起使用),即
1 2 | class Foo(object): ... |
。
另外,"对象"和"类"也有区别。要从任意对象构建字典,使用
1 2 3 4 5 6 7 8 9 10 | >>> 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} |
一个更好的方法(由罗伯特在评论中提出)是内置的
1 2 | >>> vars(a) {'c': 2, 'b': 1} |
。
或者,根据您的意愿,从
1 2 3 4 5 6 7 | class Foo(dict): def __init__(self): pass def __getattr__(self, attr): return self[attr] # etc... |
。
与
1 2 3 4 5 6 7 8 9 | >>> 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' } |
因此,通过这样定义
1 2 3 4 5 6 7 8 9 | 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 |
号
我已经解决了两个答案的组合:
1 2 | dict((key, value) for key, value in f.__dict__.iteritems() if not callable(value) and not key.startswith('__')) |
To build a dictionary from an arbitrary object, it's sufficient to use
__dict__ .
号
这会丢失对象从其类继承的属性。例如,
1 2 3 | class c(object): x = 3 a = c() |
hasattr(a,'x')为真,但'x'不出现在__
我想我会花些时间向你展示如何通过
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | class A(object): d = '4' e = '5' f = '6' def __init__(self): self.a = '1' self.b = '2' self.c = '3' def __iter__(self): # first start by grabbing the Class items iters = dict((x,y) for x,y in A.__dict__.items() if x[:2] != '__') # then update the class items with the instance items iters.update(self.__dict__) # now 'yield' through the items for x,y in iters.items(): yield x,y a = A() print(dict(a)) # prints"{'a': '1', 'c': '3', 'b': '2', 'e': '5', 'd': '4', 'f': '6'}" |
。
此代码的关键部分是
正如注释所解释的,我们首先要做的是抓取类项,并防止以"uuuu"开头的任何事情。
创建了
这些将为您提供一个完整的类+实例成员字典。现在只剩下迭代它们并产生返回。
另外,如果您打算大量使用它,您可以创建一个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | def iterable(cls): def iterfn(self): iters = dict((x,y) for x,y in cls.__dict__.items() if x[:2] != '__') iters.update(self.__dict__) for x,y in iters.items(): yield x,y cls.__iter__ = iterfn return cls @iterable class B(object): d = 'd' e = 'e' f = 'f' def __init__(self): self.a = 'a' self.b = 'b' self.c = 'c' b = B() print(dict(b)) |
号
迟些回答,但提供了完整性和谷歌的好处:
1 2 | def props(x): return dict((key, getattr(x, key)) for key in dir(x) if key not in dir(x.__class__)) |
。
这不会显示类中定义的方法,但它仍然会显示字段,包括分配给lambda的字段或以双下划线开头的字段。
我认为最简单的方法是为类创建getitem属性。如果需要写入对象,可以创建自定义setattr。以下是getitem的示例:
1 2 3 4 5 6 7 8 9 10 11 12 | 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将对象属性生成到字典中,dictionary对象可用于获取所需的项。
使用
如果您使用的是python3.5或更高版本,您可以使用
1 2 3 | >>> import jsons >>> jsons.dump(f) {'bar': 'hello', 'baz': 'world'} |
号
如果要列出部分属性,请重写
1 2 3 4 5 6 7 8 9 | def __dict__(self): d = { 'attr_1' : self.attr_1, ... } return d # Call __dict__ d = instance.__dict__() |
号
如果您的
Python3:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | class DateTimeDecoder(json.JSONDecoder): def __init__(self, *args, **kargs): JSONDecoder.__init__(self, object_hook=self.dict_to_object, *args, **kargs) def dict_to_object(self, d): if '__type__' not in d: return d type = d.pop('__type__') try: dateobj = datetime(**d) return dateobj except: d['__type__'] = type return d def json_default_format(value): try: if isinstance(value, datetime): return { '__type__': 'datetime', 'year': value.year, 'month': value.month, 'day': value.day, 'hour': value.hour, 'minute': value.minute, 'second': value.second, 'microsecond': value.microsecond, } if isinstance(value, decimal.Decimal): return float(value) if isinstance(value, Enum): return value.name else: return vars(value) except Exception as e: raise ValueError |
号
现在您可以在自己的类中使用上面的代码:
1 2 3 4 5 6 7 | class Foo(): def toJSON(self): return json.loads( json.dumps(self, sort_keys=True, indent=4, separators=(',', ': '), default=json_default_format), cls=DateTimeDecoder) Foo().toJSON() |
号