我的代码有几个神奇的数字,比如“外部”的特定错误代码,我只需要一次。所以我可以编码
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)
答案 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