是否有“pythonic”(即规范,官方,PEP8批准等)方式在python
内部(和外部)API中重用字符串文字?
例如,我正在使用一些(不一致的)JSON处理代码(数千行),其中有各种JSON“struct
s”我们汇编,解析等。其中一个反复出现的问题在代码审查期间出现的是使用相同内部参数名称的不同JSON struct
,导致混淆并最终导致错误,例如:
pathPacket['src'] = "/tmp"
pathPacket['dst'] = "/home/user/out"
urlPacket['src'] = "localhost"
urlPacket['dst'] = "contoso"
这两个(示例)数据包具有数十个相同名称的字段,但它们代表非常不同类型的数据。此实现没有代码重用理由。人们通常使用代码完成引擎来获取JSON struct
的成员,这最终导致难以调试的问题,因为错误输入的字符串文字导致功能问题,并且不会触发错误早前。当我们必须更改这些API时,需要花费大量时间来查找字符串文字以找出哪些JSON struct
使用哪些字段。
python
社区的成员之间是否有更好的解决方法?如果我在C++
中执行此操作,则前面的示例将类似于:
const char *JSON_PATH_SRC = "src";
const char *JSON_PATH_DST = "dst";
const char *JSON_URL_SRC = "src";
const char *JSON_URL_DST = "dst";
// Define/allocate JSON structs
pathPacket[JSON_PATH_SRC] = "/tmp";
pathPacket[JSON_PATH_DST] = "/home/user/out";
urlPacket[JSON_URL_SRC] = "localhost";
urlPacket[JSON_URL_SRC] = "contoso";
我最初的做法是:
abc
创建无法初始化为对象的抽象基类,并使用只读常量填充它。from abc import ABCMeta
class Custom_Structure:
__metaclass__ = ABCMeta
@property
def JSON_PATH_SRC():
return self._JSON_PATH_SRC
@property
def JSON_PATH_DST():
return self._JSON_PATH_DST
@property
def JSON_URL_SRC():
return self._JSON_URL_SRC
@property
def JSON_URL_DST():
return self._JSON_URL_DST
答案 0 :(得分:4)
通常这样做的方式是:
JSON_PATH_SRC = "src"
JSON_PATH_DST = "dst"
JSON_URL_SRC = "src"
JSON_URL_DST = "dst"
pathPacket[JSON_PATH_SRC] = "/tmp"
pathPacket[JSON_PATH_DST] = "/home/user/out"
urlPacket[JSON_URL_SRC] = "localhost"
urlPacket[JSON_URL_SRC] = "contoso"
表示“常量”的大写是它的方式。您会在标准库中看到这一点,甚至建议在PEP8中使用
常量通常在模块级别定义并全部写入 带下划线分隔单词的大写字母。例子包括
MAX_OVERFLOW
和TOTAL
。
Python没有真正的常量,并且它似乎在没有它们的情况下幸存下来。如果它让您觉得在使用ABCmeta
属性的类中包装它会更加舒适,请继续。实际上,我非常确定abc.ABCmeta
不会不阻止对象初始化。实际上,如果它 ,那么使用property
将无效! property
个对象属于类,但是要从实例访问。对我来说,它只是看起来像很多非常小的收获。
答案 1 :(得分:3)
我认为制作常量的最简单方法就是将它们设置为模块中的变量(而不是修改它们)。
JSON_PATH_SRC = "src"
JSON_PATH_DST = "dst"
JSON_URL_SRC = "src"
JSON_URL_DST = "dst"
然后,如果你需要从另一个模块引用它们,它们已经为你命名。
>>> that_module.JSON_PATH_SRC
'src'
>>> that_module.JSON_PATH_DST
'dst'
>>> that_module.JSON_URL_SRC
'src'
>>> that_module.JSON_URL_DST
'dst'
答案 2 :(得分:1)
创建一组常量的最简单方法是将它们放入模块中,并根据需要导入它们。例如,您可以使用
的constants.py
模块
JSON_PATH_SRC = "src"
JSON_PATH_DST = "dst"
JSON_URL_SRC = "src"
JSON_URL_DST = "dst"
您的代码将执行类似
的操作from constants import JSON_URL_SRC
...
urlPacket[JSON_URL_SRC] = "localhost"
如果您希望更好地定义常量分组,您可以将它们粘贴到专用包中的单独模块中,允许您像constants.json.url.DST
那样访问它们,或者您可以使用{{3} }秒。 Enum
类允许您将相关的常量集合分组到单个命名空间中。您可以像这样写一个模块constants.py
:
from enum import Enum
class JSONPath(Enum):
SRC = 'src'
DST = 'dst'
class JSONUrl(Enum):
SRC = 'src'
DST = 'dst'
OR
from enum import Enum
class JSON(Enum):
PATH_SRC = 'src'
PATH_DST = 'dst'
URL_SRC = 'src'
URL_DST = 'dst'
你如何区分你的常数取决于你。你可以拥有一个巨大的枚举,每个类别一个或两者之间。您可以像这样访问代码:
from constants import JSONURL
...
urlPacket[JSONURL.SRC.value] = "localhost"
OR
from constants import JSON
...
urlPacket[JSON.URL_SRC.value] = "localhost"