Skip to main content
 首页 » 编程设计

内联魔数(Magic Number)的 Pythonic 方式

2025年05月04日9Renyi-Fan

我的代码有几个神奇的数字,比如来自“外部”的特定错误代码,我只需要一次。所以我可以编码

do_something(x, y, 161) 

或

magic_code = 161 
do_something(x, y, magic_code) 

第二个当然可读性更好,因为它将 161 的含义编码为“magic_code”。因此代码变得更具可读性。但是,它将语义链接放在语句之外。是否有一种易于键入的方式来将其内联?理想的方向是

do_something(x, y, magic_code = 161) 
do_something(x, y, other_magic = 162) 

这当然行不通。

当然,我可以将常量收集到一些特定的枚举中。然而,常量“仅适用于一次调用”。

一些答案​​建议将魔术常量收集到枚举中。我不想那样做。问题是 do_something 调用了一些外部系统,我通过逆向工程收集常量。一旦所有电话都到位,我可能会决定这样做。但此时不这样做更方便。所以我想寻求一种方法来加快我的打字速度,同时仍然保持一定的可读性。

目前我发现的最接近的是

do_something(x, y, 161 if "magic" else nil) 
do_something(x, y, {"magic":161}["magic"]) 
 
def inline_constant(name, value): return value 
do_something(x, y, inline_constant("magic", 161)) 
do_something(x, y, inline_constant("other_magic", 162)) 

它使语义接近于数字,但对我来说看起来很尴尬。

我不想设置模块级常量。我只想要一个一次性的常量。到目前为止我发现的最接近的是

do something(x, y, "magic" and 161) 
do something(x, y, "other magic" and 162) 

请您参考如下方法:

在 python 中,您不能1在表达式中进行赋值……老实说,我真的不明白您为什么要2。最终,无论在哪里定义 do_something 函数,都应该有它接受的神奇常量:

# Magic values 
EARTH = 1 
FIRE = 2 
WATER = 4 
AIR = 8 
HEART = 16 
 
def do_something(a, b, magic): 
   ... 

现在,你可以这样调用它:

do_something("Captain", "Planet", EARTH) 

或者,如果它是从模块导入的:

import my_module 
my_module.do_something("Captain", "Planet", my_module.EARTH) 

如果您在函数外部查看,您不关心 EARTH 有什么值,只关心它对函数有什么特殊意义。

请注意 python3.4(?) 使用 enumerated types 使它更加正式一点.


1can't 在这里用词太强了。 globals().update(foo=bar) or bar 在技术上是一个表达式,它在全局命名空间中具有赋值的效果,并且仍然返回 bar ...但那是只是脏...

2我确信 ruby​​ 程序员可以让我知道我为什么要这样做,但我从来没有觉得有必要……;-)