用于内联幻数的Pythonic方式

时间:2013-12-19 06:15:26

标签: python

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

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)

3 个答案:

答案 0 :(得分:9)

在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更加正式化了。


1 不能在这里过于强硬。 globals().update(foo=bar) or bar在技术上是一个表达式,它在全局命名空间中具有赋值的作用,但仍然返回bar ......但这只是肮脏......

2 我确信红宝石程序员可以让我知道为什么我会这样做,但我从来没有觉得有必要......; - )

答案 1 :(得分:1)

可能最不丑的选择是这样的:

def const(**kwargs):
    return kwargs.values()[0]


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

对于python3(其中values()返回view,你无法直接索引):

def const(**kwargs):
    for x in kwargs.values():
        return x

答案 2 :(得分:0)

所以,理想情况下,您想致电:

do_something(x, y, magic_code=1234)

为此,在函数定义中,执行以下操作:

def do_something(x, y, magic_code=int)

演示:

>>> def do_something(x, y, magic_code=int):
    print x, y, magic_code


>>> do_something(1, 2, 123)
1 2 123
>>> do_something(1, 2, magic_code=123)
1 2 123