javascript|如何像 JavaScript一样访问Json对象
写在前面
首先我们看一段 JS 的代码:
// 数据为掘金文章详情数据,做了部分数据的删简
result = '{"err_no":0,"err_msg":"success","data":{"article_id":"6985356541389963300","article_info":{"article_id":"6985356541389963300","user_id":"993614678985085","category_id":"6809637769959178254","tag_ids":[6809640445233070094,6809640468997996558],"visible_level":0,"link_url":"","cover_image":"","is_gfw":0,"title":"如何发布 Jar 包到私服","brief_content":"事情是这样的,最近接手一个比较复杂的 Java 项目。项目依赖其他工具包,工具包更新后需要上传到私服;今天就看看如何发布 Jar 包到私服。"},"author_user_info":{"user_id":"993614678985085","user_name":"西红柿蛋炒饭","job_title":"开发工程师","description":"一个 写 Python Java JavaScript 的全栈开发","university":{"university_id":"0","name":"","logo":""}},"category":{"category_id":"6809637769959178254","category_name":"后端","category_url":"backend"},"tags":[{"id":2546553,"tag_id":"6809640445233070094","tag_name":"Java"},{"id":2546571,"tag_id":"6809640468997996558","tag_name":"maven"}]}}'obj = JSON.parse(result)
obj.err_msg// success
obj.data.article_info.title// 如何发布 Jar 包到私服
obj.data.tags[1].tag_name// maven
??在 JavaScript 中可以使用
JSON.parse
快速序列化 JSON 对象。那么问题来了作为同类型语言的 Python 是否可以有类似的功能呢?
答案明显是有的,下面看看 Python 的实现:
import jsonresult = '{"err_no":0,"err_msg":"success","data":{"article_id":"6985356541389963300","article_info":{"article_id":"6985356541389963300","user_id":"993614678985085","category_id":"6809637769959178254","tag_ids":[6809640445233070094,6809640468997996558],"visible_level":0,"link_url":"","cover_image":"","is_gfw":0,"title":"如何发布 Jar 包到私服","brief_content":"事情是这样的,最近接手一个比较复杂的 Java 项目。项目依赖其他工具包,工具包更新后需要上传到私服;今天就看看如何发布 Jar 包到私服。"},"author_user_info":{"user_id":"993614678985085","user_name":"西红柿蛋炒饭","job_title":"开发工程师","description":"一个 写 Python Java JavaScript 的全栈开发","university":{"university_id":"0","name":"","logo":""}},"category":{"category_id":"6809637769959178254","category_name":"后端","category_url":"backend"},"tags":[{"id":2546553,"tag_id":"6809640445233070094","tag_name":"Java"},{"id":2546571,"tag_id":"6809640468997996558","tag_name":"maven"}]}}'obj = json.loads(result)
obj['data']['tags'][1]['tag_name'] # maven
对比一下写法:
- Python:
obj['data']['tags'][1]['tag_name']
- JavaScript:
obj.data.tags[1].tag_name
技术背景
Python 魔术方法
_init_
用于初始化实例对象的方法。new
用于创建对象并返回对象的方法。
new
先创建对象 _init
_ 再初始化对象,调用有先后顺序。下面就是基于__
new
__方法实现的单例模式:class Singleton(object):
_instance = Nonedef __new__(cls, *args, **kwargs):if cls._instance is None:
cls._instance = object.__new__(cls)
return cls._instance
tips:
object.__new__(cls)
是用于创建任何实例对象的方法。classmethod 装饰器
class Foo(object):
bar = "bar"@classmethod
def print_bar(cls):
print(cls.bar)Foo.print_bar() # bar
Foo().print_bar() # bar
??
classmethod
修饰的方法表示类方法,不需要实例化类就可以被类本身调用。cls
表示没用被实例化的类对象本身。功能实现
代码分析
import jsonclass FrozenJSON:
"""Read only facade for navigating a JSON like object using attribute notation """@classmethod
def __new__(cls, *args, **kwargs):
if isinstance(args[1], abc.Mapping):
return super().__new__(cls)
elif isinstance(args[1], abc.MutableSequence):
return [cls(item) for item in args[1]]
else:
return args[1]def __init__(self, mapping):
self._data = {
}
for key, value in mapping.items():
self._data[self.validate_identifier(key)] = valuedef __getattr__(self, name):
if name in self._data:
return FrozenJSON(self._data[name])
raise AttributeError(f"Not found: {name}")@classmethod
def validate_identifier(cls, identifier: str):
idx = 0def validated(__identifier):
validated_identifier = __identifier
# handle identifier is a Python keyword
if keyword.iskeyword(__identifier):
__identifier += "_"
# handle identifier starts with an integer
if __identifier[0].isdigit():
__identifier = f"{str(chr(idx))}_{validated_identifier[1:]}"
if not __identifier.isidentifier():
raise ValueError(f"Could not create valid key from: {__identifier}")
return __identifierreturn validated(identifier)@classmethod
def from_string(cls, json_string):
if is_valid_file_path(json_string):
return cls.from_file_path(json_string)
return cls(json.loads(json_string))
功能演示
result = '{"err_no":0,"err_msg":"success","data":{"article_id":"6985356541389963300","article_info":{"article_id":"6985356541389963300","user_id":"993614678985085","category_id":"6809637769959178254","tag_ids":[6809640445233070094,6809640468997996558],"visible_level":0,"link_url":"","cover_image":"","is_gfw":0,"title":"如何发布 Jar 包到私服","brief_content":"事情是这样的,最近接手一个比较复杂的 Java 项目。项目依赖其他工具包,工具包更新后需要上传到私服;今天就看看如何发布 Jar 包到私服。"},"author_user_info":{"user_id":"993614678985085","user_name":"123","job_title":"开发工程师","description":"一个 写 Python Java JavaScript 的全栈开发","university":{"university_id":"0","name":"","logo":""}},"category":{"category_id":"6809637769959178254","category_name":"后端","category_url":"backend"},"tags":[{"id":2546553,"tag_id":"6809640445233070094","tag_name":"Java"},{"id":2546571,"tag_id":"6809640468997996558","tag_name":"maven"}]}}'FrozenJSON.from_string(result).data.tags[1].tag_name
关键点解释
abc.Mapping
此类对象包括 dict、collections.defaultdict、collections.OrderedDict
以及collections.Counter。 abc.MutableSequence
可变序列主要对象为list。 keyword.iskeyword
用于判断字符串是否为Python
内建关键字。【javascript|如何像 JavaScript一样访问Json对象】更多关于 ABC 抽象类的可以查看 collections.abc 容器的抽象基类
最后
??更多关于 Python 标准库的介绍可以查看 Python 标准库 。之所以放在最后,是因为 Python 很多标准库真的很棒,推荐大家多看多用。
文章图片
??如果对软件测试、接口测试、自动化测试、持续集成、面试经验。感兴趣? 可以进到806549072,群内会有不定期的分享测试资料。还会有技术大牛,业内同行一起交流技术
推荐阅读
- 考研英语阅读终极解决方案——阅读理解如何巧拿高分
- 如何寻找情感问答App的分析切入点
- MediaRecorder前后摄像头同时录像
- mybatisplus如何在xml的连表查询中使用queryWrapper
- MybatisPlus使用queryWrapper如何实现复杂查询
- 事件代理
- 广角叙述|广角叙述 展众生群像——试析鲁迅《示众》的展示艺术
- 爱琐搭配(喜欢复古、冷淡,像这种双环设计的气质耳环)
- 放下心中的偶像包袱吧
- Java|Java OpenCV图像处理之SIFT角点检测详解