设为首页 收藏本站
查看: 751|回复: 0

[经验分享] python模块介绍-json

[复制链接]

尚未签到

发表于 2015-4-26 08:52:45 | 显示全部楼层 |阅读模式
  #参考资料:《The Python Standard Library by Example》
  12.9 json 模块
  JSON就是JavaScript Object Notation,这个模块完成了python对象和JSON字符串的互相转换。适用于Python的版本2.6和更高版本。   
json模块提供了一个类似pickle的API,转换内存中的Python对象为JavaScript对象符号(JSON)序列。JSON具有有许多语言的实现(尤其是JavaScript)。在AJAX应用中,广泛的使用在Web服务器和客户端之间,
  12.9.1 编码解码简单数据类型
  JSON编码识别python的如下类型:(string, unicode, int,float, list, tuple, and dict),比如:
  import json
  data = [ { 'a':'A', 'b':(2, 4), 'c':3.0 } ]
  print 'DATA:', repr(data)
  data_string = json.dumps(data)
  print 'JSON:', data_string
  执行结果:
  $ python json_simple_types.py
  DATA: [{'a': 'A', 'c': 3.0, 'b': (2, 4)}]
  JSON: [{"a": "A", "c": 3.0, "b": [2, 4]}]
  可以json的表示和python的repr差不多。这里还要注意一点,字典中,把可变对象往后靠,是不是有什么规则?
  下例进行编码再解码:
  import json
  data = [ { ’a’:’A’, ’b’:(2, 4), ’c’:3.0 } ]
  print ’DATA :’, data
  data_string = json.dumps(data)
  print ’ENCODED:’, data_string
  decoded = json.loads(data_string)
  print ’DECODED:’, decoded
  print ’ORIGINAL:’, type(data[0][’b’])
  print ’DECODED :’, type(decoded[0][’b’])
  执行结果:
  $ python json_simple_types_decode.py
  DATA : [{’a’: ’A’, ’c’: 3.0, ’b’: (2, 4)}]
  ENCODED: [{"a": "A", "c": 3.0, "b": [2, 4]}]
  DECODED: [{’a’: ’A’, ’c’: 3.0, ’b’: [2, 4]}]
  ORIGINAL:
  DECODED :
  这里元组:(2, 4), 编码再解码之后,成了列表
  12.9.2 编码解码简单数据类型
  JSON跟pickle比的另一个好处是结果的可读性比较好。pickle函数接受多个参数,以使输出甚至更好。下例实现了排序功能:
  import json
  data = [ { ’a’:’A’, ’b’:(2, 4), ’c’:3.0 } ]
  print ’DATA:’, repr(data)
  unsorted = json.dumps(data)
  print ’JSON:’, json.dumps(data)
  print ’SORT:’, json.dumps(data, sort_keys=True)
  first = json.dumps(data, sort_keys=True)
  second = json.dumps(data, sort_keys=True)
  print ’UNSORTED MATCH:’, unsorted == first
  print ’SORTED MATCH :’, first == second
  执行结果:
  $ python json_sort_keys.py
  DATA: [{’a’: ’A’, ’c’: 3.0, ’b’: (2, 4)}]
  JSON: [{"a": "A", "c": 3.0, "b": [2, 4]}]
  SORT: [{"a": "A", "b": [2, 4], "c": 3.0}]
  UNSORTED MATCH: False
  SORTED MATCH : True
  对于多层嵌套的数据结构,还可以使用缩进:
  import json
  data = [ { ’a’:’A’, ’b’:(2, 4), ’c’:3.0 } ]
  print ’DATA:’, repr(data)
  print ’NORMAL:’, json.dumps(data, sort_keys=True)
  print ’INDENT:’, json.dumps(data, sort_keys=True, indent=2)
  执行结果:
  $ python json_indent.py
  DATA: [{’a’: ’A’, ’c’: 3.0, ’b’: (2, 4)}]
  NORMAL: [{"a": "A", "b": [2, 4], "c": 3.0}]
  INDENT: [
  {
  "a": "A",
  "b": [
  2,
  4
  ],
  "c": 3.0
  }
  ]
  当缩进不是负数的时候,和pprint的效果差不多。
  像这样详细的输出,因此它不适合在产品环境中使用。可以调整分离编码输出数据使它甚至超过了默认的紧凑。
  import json
  data = [ { ’a’:’A’, ’b’:(2, 4), ’c’:3.0 } ]
  print ’DATA:’, repr(data)
  print ’repr(data) :’, len(repr(data))
  plain_dump = json.dumps(data)
  print ’dumps(data) :’, len(plain_dump)
  small_indent = json.dumps(data, indent=2)
  print ’dumps(data, indent=2) :’, len(small_indent)
  with_separators = json.dumps(data, separators=(’,’,’:’))
  print ’dumps(data, separators):’, len(with_separators)
  执行结果:
  $ python json_compact_encoding.py
  DATA: [{’a’: ’A’, ’c’: 3.0, ’b’: (2, 4)}]
  repr(data) : 35
  dumps(data) : 35
  dumps(data, indent=2) : 76
  dumps(data, separators): 29
  12.9.3 编码字典
  JSON字典的键值是字符串。试图编码非字符串作为键值会产生一个例外,是TypeError 或者ValueError,取决于加载的模块是纯Python版本加载还是C的加速版本,可以让json忽略这些非字符串的键值。
  import json
  data = [ { ’a’:’A’, ’b’:(2, 4), ’c’:3.0, (’d’,):’D tuple’ } ]
  print ’First attempt’
  try:
  print json.dumps(data)
  except (TypeError, ValueError), err:
  print ’ERROR:’, err
  print
  print ’Second attempt’
  print json.dumps(data, skipkeys=True)
  执行结果:
  import json
  data = [ { ’a’:’A’, ’b’:(2, 4), ’c’:3.0, (’d’,):’D tuple’ } ]
  print ’First attempt’
  try:
  print json.dumps(data)
  except (TypeError, ValueError), err:
  print ’ERROR:’, err
  print
  print ’Second attempt’
  print json.dumps(data, skipkeys=True)
  12.9.4 自定义类型
  到目前为止,所有的例子使用了Python的内置类型,因为这些都是由JSON本身支持的。如果需要编码自定义类,有两种方法。比如有如下对象:
  class MyObj(object):
  def __init__(self, s):
  self.s = s
  def __repr__(self):
  return ’’ % self.s
  编码MyObj实例的最简单的方法是定义一个函数来转换未知类型为已知类型。它不需要做编码,因此它应该只是转换一个对象到另一个。
  import json
  import json_myobj
  obj = json_myobj.MyObj(’instance value goes here’)
  print ’First attempt’
  try:
  print json.dumps(obj)
  except TypeError, err:
  print ’ERROR:’, err
  def convert_to_builtin_type(obj):
  print ’default(’, repr(obj), ’)’
  # Convert objects to a dictionary of their representation
  d = { ’__class__’:obj.__class__.__name__,
  ’__module__’:obj.__module__,
  }
  d.update(obj.__dict__)
  return d
  print
  print ’With default’
  print json.dumps(obj, default=convert_to_builtin_type)
  执行结果:
  $ python json_dump_default.py
  First attempt
  ERROR:  is not JSON serializable
  With default
  default(  )
  {"s": "instance value goes here", "__module__": "json_myobj",
  "__class__": "MyObj"}
  要解码的结果并创建一个MyObj中()实例,使用object_hook参数到loads()绑上给解码器,这样的类可以从模块导入并用来创建实例。
  每个从输入数据流中解码的字典调用object_hook,把字典转换为其他数据类型。Hook函数程序应该接收的对象而不是字典。
  import json
  def dict_to_object(d):
  if '__class__' in d:
  class_name = d.pop('__class__')
  module_name = d.pop('__module__')
  module = __import__(module_name)
  print 'MODULE:', module.__name__
  class_ = getattr(module, class_name)
  print 'CLASS:', class_
  args = dict( (key.encode('ascii'), value)
  for key, value in d.items())
  print 'INSTANCE ARGS:', args
  inst = class_(**args)
  else:
  inst = d
  return inst
  encoded_object = '''
  [{"s": "instance value goes here",
  "__module__": "json_myobj", "__class__": "MyObj"}]
  '''
  myobj_instance = json.loads(encoded_object,
  object_hook=dict_to_object)
  print myobj_instance
  运行结果:
  $ python json_load_object_hook.py
  MODULE: json_myobj
  CLASS:
  INSTANCE ARGS: {’s’: ’instance value goes here’}
  []
  由于JSON字符串值转换为Unicode对象,他们需要重新编码   
为ASCII字符串,才可以作为类构造的关键字参数。
  12.9.5 编码和解码类
  json模块提供了编码和解码类。使用这些类可访问额外的API来定制自己的行为。
  JSONEncoder使用了一个可迭代接口编码数据的“chunks”,从而在不需要在内存表示整个数据,更加容易写文件或网络socket。
  import json
  encoder = json.JSONEncoder()
  data = [ { ’a’:’A’, ’b’:(2, 4), ’c’:3.0 } ]
  for part in encoder.iterencode(data):
  print ’PART:’, part
  执行结果:
  $ python json_encoder_iterable.py
  PART: [
  PART: {
  PART: "a"
  PART: :
  PART: "A"
  PART: ,
  PART: "c"
  PART: :
  PART: 3.0
  PART: ,
  PART: "b"
  PART: :
  PART: [2
  PART: , 4
  PART: ]
  PART: }
  PART: ]
  encode()方法基本上等同于’ ’.join(encoder.iterencode()),不过事先多了一些错误检查。要编码的任意对象,使用前面类似convert_to_builtin_type的方法重载default()。
  import json
  import json_myobj
  class MyEncoder(json.JSONEncoder):
  def default(self, obj):
  print 'default(', repr(obj), ')'
  # Convert objects to a dictionary of their representation
  d = { '__class__':obj.__class__.__name__,
  '__module__':obj.__module__,
  }
  d.update(obj.__dict__)
  return d
  obj = json_myobj.MyObj('internal data')
  print obj
  print MyEncoder().encode(obj)
  执行结果:
  $ python json_encoder_default.py
  
  default(  )
  {"s": "internal data", "__module__": "json_myobj", "__class__":
  "MyObj"}
  解码文本,然后转换对象到字典,比之前的实现要稍微多一点步骤
  import json
  class MyDecoder(json.JSONDecoder):
  def __init__(self):
  json.JSONDecoder.__init__(self,
  object_hook=self.dict_to_object)
  def dict_to_object(self, d):
  if ’__class__’ in d:
  class_name = d.pop(’__class__’)
  module_name = d.pop(’__module__’)
  module = __import__(module_name)
  print ’MODULE:’, module.__name__
  class_ = getattr(module, class_name)
  print ’CLASS:’, class_
  args = dict( (key.encode(’ascii’), value)
  for key, value in d.items())
  print ’INSTANCE ARGS:’, args
  inst = class_(**args)
  else:
  inst = d
  return inst
  encoded_object = ’’’
  [{"s": "instance value goes here",
  "__module__": "json_myobj", "__class__": "MyObj"}]
  ’’’
  myobj_instance = MyDecoder().decode(encoded_object)
  print myobj_instance。
  执行结果:
  $ python json_decoder_object_hook.py
  MODULE: json_myobj
  CLASS:
  INSTANCE ARGS: {’s’: ’instance value goes here’}
  []
  12.9.6 流和文件
  函数load() 和dump()用于读写文件类似的对象。
  import json
  from StringIO import StringIO
  data = [ { ’a’:’A’, ’b’:(2, 4), ’c’:3.0 } ]
  f = StringIO()
  json.dump(data, f)
  print f.getvalue()
  
  执行结果:
  $ python json_dump_file.py
  [{"a": "A", "c": 3.0, "b": [2, 4]}]
  虽然不优化为一次只读取的部分数据,load()提供了从流输入生成对象逻辑。
  import json
  from StringIO import StringIO
  f = StringIO(’[{"a": "A", "c": 3.0, "b": [2, 4]}]’)
  print json.load(f)
  执行结果:
  $ python json_load_file.py
  [{’a’: ’A’, ’c’: 3.0, ’b’: [2, 4]}]
  12.9.7 混合数据流
  JSONDecoder包括raw_decode(),这个方法可以解码包含更多数据的数据结构   
,比如带后续文本的JSON数据。返回值是解码后的输入数据和索引。
  (obj, end, remaining)
  encoded_object = ’[{"a": "A", "c": 3.0, "b": [2, 4]}]’
  extra_text = ’This text is not JSON.’
  print ’JSON first:’
  data = ’ ’.join([encoded_object, extra_text])
  obj, end, remaining = get_decoded_and_remainder(data)
  print ’Object :’, obj
  print ’End of parsed input :’, end
  print ’Remaining text :’, repr(remaining)
  print
  print ’JSON embedded:’
  try:
  data = ’ ’.join([extra_text, encoded_object, extra_text])
  obj, end, remaining = get_decoded_and_remainder(data)
  except ValueError, err:
  print ’ERROR:’, err
  执行结果:
  $ python json_mixed_data.py
  JSON first:
  Object : [{’a’: ’A’, ’c’: 3.0, ’b’: [2, 4]}]
  End of parsed input : 35
  Remaining text : ’ This text is not JSON.’
  JSON embedded:
  ERROR: No JSON object could be decoded
  注意,对象必须在输入的开始
  其他参考资料:
  json (http://docs.python.org/library/json.html)
  JavaScript Object Notation (http://json.org/)
  simplejson (http://code.google.com/p/simplejson/)
  simplejson (http://code.google.com/p/simplejson/)

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-60741-1-1.html 上篇帖子: 《趣学Python编程》 下篇帖子: python语法31[基本数据类型和流程控制]
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表