命名规范与正则表达式

根据 Google Python Style Guide,Python 中的参数名一般为 lower_with_under 风格。而根据 Google Java Style Guide, Java 中的参数名一般为 lowerCamelCase 风格。那么问题来了,假如你写了一个 Python 算法服务供 Java 后端调用,设计接口的时候参数名应该采用什么命名风格呢?我工作中就遇到过这个问题。使用 Python 风格吧,后端同学用起来不方便;使用 Java 风格吧,作为一个强迫症我又很难受。有没有两全其美的办法呢?

后端在调用接口的时候,使用 json 格式传递参数,算法接收到之后将 json 串反序列化为字典。借助正则表达式,我们可以把字典的 key 由 Java 风格转化为 Python 风格:

1
2
3
4
5
6
7
8
9
10
11
12
import re

def camel_to_snake(camelCase: str) -> str:
"""
convert CamelCase string into snake_case string.
"""
pattern = re.compile(r'([a-z]|\d)([A-Z])')
snake_case = re.sub(
pattern=pattern,
repl=r'\1_\2',
string=camelCase).lower()
return snake_case

等等……我们不会是要遍历字典,逐个转换吧?如果是字典套字典的情况呢?难不成还写个递归?写这样的代码不会挨打吗?其实大可不必如此,我们可以在接收到 json 串之后先用正则表达式匹配出 key,一次性转换,然后再将 json 反序列化。

1
2
3
4
5
6
7
8
9
10
11
def json_camel_to_snake(camelCaseJsonStr: str) -> str:
"""
convert CamelCase keys inside a json string into snake_case keys.
"""
pattern = re.compile(r'"\s*(\w+)\s*"\s*:')
snake_case_json_str = re.sub(
pattern=pattern,
repl=lambda s: '"' + camel_to_snake(s.group(1)) + '":',
string=camelCaseJsonStr
)
return snake_case_json_str

进一步地,我们的算法服务的返回结果也可以在序列化为 json 串后,用正则表达式把所有的 key 从 Python 风格一键转化为 Java 风格,然后再传给用户。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def snake_to_camel(snake_case: str) -> str:
"""
convert snake_case string into CamelCase string.
"""
pattern = re.compile(r'(_\w)')
camelCase = re.sub(
pattern=pattern,
repl=lambda s: s.group(1)[1].upper(),
string=snake_case
)
return camelCase

def json_snake_to_camel(snake_case_json_str: str) -> str:
"""
convert snake_case keys inside a json string into CamelCase keys.
"""
pattern = re.compile(r'"\s*(\w+)\s*"\s*:')
camelCaseJsonStr = re.sub(
pattern=pattern,
repl=lambda s: '"' + snake_to_camel(s.group(1)) + '":',
string=snake_case_json_str
)
return camelCaseJsonStr

完。