前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >接口数据变更

接口数据变更

原创
作者头像
mariolu
修改2024-05-17 08:54:32
10100
代码可运行
修改2024-05-17 08:54:32
举报
文章被收录于专栏:Python实用主义Python实用主义
运行总次数:0
代码可运行

日常工作中会遇到数据处理需求频繁变更的情况,有时候需要处理大量的Json任务。如果家纺提出一点改动,Python处理数据如何避免大量修改代码。

这个问题,对接数据的同学会经常碰到。我们本文来探讨下如何有效率完成这些工作。

一、名字变更需求

首先这个问题,现在实际生产环境会用到 一些 接口协议:比如说thrift,proto、avro等成熟接口协议。特别是跨部分对接的工作很少直接裸用Json。因为这些成熟的接口协议在数据传输大小、数据存储、序列化反序列化效率上以及跨多种语言支持上有很棒的表现。裸用JSON也不能说没有,因为JSON在人类代码可读性这方面还是有优势。如果不会考虑很重的性能,从基于简单些来说,有时候也会直接用JSON。

那么如果碰到接口字段变更,这里我们分为两种情况考虑减少字段变更带来的代码维护成本:

  • JSON的字段变更
  • Protobuf等字段变更

JSON的字段变更这里我在细化为

  • 名字规范变更
  • 业务需求变更

二、名字规范变更

在业务上线初期,团队可能不会考虑很多代码规范,赶时间上线。但是到了中后期,随着业务代码量膨胀,那么规范代码风格是减少维护成本的重要一环。

我们来看一个python的官方规范,俗称PEP8,其中我们直接跳到名字规范这一节

https://peps.python.org/pep-0008/#descriptive-naming-styles

其中列举了这些不规范的写法

  • b (single lowercase letter)
  • B (single uppercase letter)
  • lowercase
  • lower_case_with_underscores
  • UPPERCASE
  • UPPER_CASE_WITH_UNDERSCORES
  • CapitalizedWords (or CapWords, or CamelCase – so named because of the bumpy look of its letters [4]). This is also sometimes known as StudlyCaps.Note: When using acronyms in CapWords, capitalize all the letters of the acronym. Thus HTTPServerError is better than HttpServerError.
  • mixedCase (differs from CapitalizedWords by initial lowercase character!)
  • Capitalized_Words_With_Underscores (ugly!)

那么如果碰到这样我们怎么进行有效率改造呢

2.1 pyhumps包

这里我介绍官方提供的一个pip包pyhumps。pyhumps提供了驼峰camel,去驼峰decamelize,pascal。kebab写法。比如说jack in the box我们用四种写法分别是:

  • 驼峰:jackInTheBox
  • 去驼峰:jack_in_the_box
  • pascal: JackInTheBox
  • kebab: jack-in-the-box

pyhumps的官方链接https://pypi.org/project/pyhumps/

安装包的方法:

代码语言:bash
复制
pipenv install pyhumps

使用场景:

  • 转换名字
代码语言:python
代码运行次数:0
复制
import humps

humps.camelize("jack_in_the_box")  # jackInTheBox
humps.decamelize("rubyTuesdays")  # ruby_tuesdays
humps.pascalize("red_robin")  # RedRobin
humps.kebabize("white_castle")  # white-castle
  • Json转换词典keys
代码语言:python
代码运行次数:0
复制
import humps

array = [{"attrOne": "foo"}, {"attrOne": "bar"}]
humps.decamelize(array) # [{"attr_one": "foo"}, {"attr_one": "bar"}]

array = [{"attr_one": "foo"}, {"attr_one": "bar"}]
humps.camelize(array)  # [{"attrOne": "foo"}, {"attrOne": "bar"}]

array = [{'attr_one': 'foo'}, {'attr_one': 'bar'}]
humps.kebabize(array)  # [{'attr-one': 'foo'}, {'attr-one': 'bar'}]

array = [{"attr_one": "foo"}, {"attr_one": "bar"}]
humps.pascalize(array)  # [{"AttrOne": "foo"}, {"AttrOne": "bar"}]
  • 检查名字是否遵守规范
代码语言:python
代码运行次数:0
复制
import humps

humps.is_camelcase("illWearYourGranddadsClothes")  # True
humps.is_pascalcase("ILookIncredible")  # True
humps.is_snakecase("im_in_this_big_ass_coat")  # True
humps.is_kebabcase('from-that-thrift-shop')  # True
humps.is_camelcase("down_the_road")  # False

humps.is_snakecase("imGonnaPopSomeTags")  # False
humps.is_kebabcase('only_got_twenty_dollars_in_my_pocket')  # False


# what about abbrevations, acronyms, and initialisms? No problem!
humps.decamelize("APIResponse")  # api_response

三、业务需求变更:

如果裸用Json的情况下,业务要求变更名字。一个减少维护成本最简单的想法就是少hard code名字。名字用全局变量宏替代。比如说GLOBAL_NAME='name1', 业务代码都用GLOBAL_NAME。像这种名字可以放在constants包里面。然后代码哪里需要用到就去import Mymodule.Constants.

实际代码情况会是更复杂的情况。这源自于代码长期迭代,里面风格会变了又变,风格混用,名字各种版本的问题。特别是JSON key这种数据交换媒介,往往是自由风格的字符串。比如说拥有了混合风格的JSON

代码语言:json
复制
{"keyOne": "value1", "key_one": "value2"}

这里所有会更推从用更成熟的数据交换协议,比如说protobuf

比如说proto协议定义如下

代码语言:txt
复制
syntax = "proto2";

package tutorial;

message Person {
  optional string name = 1;
  optional int32 id = 2;
  optional string email = 3;

  enum PhoneType {
    PHONE_TYPE_UNSPECIFIED = 0;
    PHONE_TYPE_MOBILE = 1;
    PHONE_TYPE_HOME = 2;
    PHONE_TYPE_WORK = 3;
  }

  message PhoneNumber {
    optional string number = 1;
    optional PhoneType type = 2 [default = PHONE_TYPE_HOME];
  }

  repeated PhoneNumber phones = 4;
}

message AddressBook {
  repeated Person people = 1;
}

与生成 Java 和 C++ protocol buffer 代码不同,Python protocol buffer 编译器不会直接生成数据访问代码。你将会看到addressbook_pb2.py它为所有消息、枚举和字段以及一些神秘的空类生成特殊描述符,每个类对应一种消息类型:

代码语言:python
代码运行次数:0
复制
class Person(message.Message):
  __metaclass__ = reflection.GeneratedProtocolMessageType

  class PhoneNumber(message.Message):
    __metaclass__ = reflection.GeneratedProtocolMessageType
    DESCRIPTOR = _PERSON_PHONENUMBER
  DESCRIPTOR = _PERSON

class AddressBook(message.Message):
  __metaclass__ = reflection.GeneratedProtocolMessageType
  DESCRIPTOR = _ADDRESSBOOK

Person就好像它将Message基类的每个字段定义为常规字段一样。例如,

代码语言:python
代码运行次数:0
复制
import addressbook_pb2
person = addressbook_pb2.Person()
person.id = 1234
person.name = "John Doe"
person.email = "jdoe@example.com"
phone = person.phones.add()
phone.number = "555-4321"
phone.type = addressbook_pb2.Person.PHONE_TYPE_HOME

请注意,这些分配不仅仅是向通用 Python 对象添加任意新字段。如果尝试分配.proto文件中未定义的字段,AttributeError则会引发错误。如果将字段分配给错误类型的值,TypeError则会引发 a 。此外,在设置字段之前读取字段的值会返回默认值。

代码语言:python
代码运行次数:0
复制
person.no_such_field = 1  # raises AttributeError

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、名字变更需求
  • 二、名字规范变更
    • 2.1 pyhumps包
    • 三、业务需求变更:
    相关产品与服务
    数据保险箱
    数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档