在Python中,如何仅存储一次函数的“常量”?
有些函数需要使用“常量”值(也就是说,这些值不打算在后面重新定义),而且这些值不应该作为参数传入。虽然默认参数对于每个函数只存储一次,但有些值作为参数传入并没有太大意义(也就是说,它们不应该成为函数的“签名”部分)。举个(不太有用的)例子:
def foo(bar):
my_map = {"rab": barType, "oof": fooType}
return my_map.get(bar,defaultType)()
每次调用时重新定义这样的常量会浪费CPU时间和内存空间。还有其他方法可以存储这些常量,比如把它们作为模块级的全局变量,或者把函数做成一个可调用的类,但可能还有其他方法,对吧?
当使用模块级全局变量的方法时,我会在我的(本意是)常量变量前加一个“_”,以表明它并不是为了让其他人使用。不过,我还是觉得模块的命名空间有点“污染”,更不用说使用一些像全局变量这样被不鼓励的东西的“羞耻”了:
_my_map = {"rab": barType, "oof": fooType}
def foo(bar):
return _my_map.get(bar,defaultType)()
或者使用把它变成一个类的方法。我把__call__
设为一个类方法,这样就不需要创建实例了:
class foo:
my_map = {"rab": barType, "oof": fooType}
@classmethod
def __call__(cls,bar):
return cls.my_map.get(bar,defaultType)()
这些解决方案够“Pythonic”吗?
还有其他方法可以做到这一点吗?
使用这样的“常量”作为一种实践是否合适?
注意:我例子中的这些对象不一定是真正的常量,但根据它们的用途可以被视为常量。
4 个回答
3
你还可以使用闭包:
def make_foo():
my_map = {"rab": barType, "oof": fooType}
def foo(bar):
return my_map.get(bar,defaultType)()
return foo
foo = make_foo()
6
在我看来,模块级别的常量是没有问题的。
根据PEP 8的规定,常量应该全部用大写字母,比如这样:
_MY_MAP = {"rab": barType, "oof": fooType}
def foo(bar):
return _MY_MAP.get(bar,defaultType)()
标准库中的正则表达式模块就使用这种风格,很多知名的第三方库也是这样做的。如果你还不相信,可以去你的site-packages
目录看看,使用grep命令搜索一下:
egrep "^_?[A-Z]+ =" *
18
把它设置为一个函数的属性:
def foo(bar):
return foo.my_map.get(bar, defaultType)()
foo.my_map = {"rab": barType, "oof": fooType}
我觉得可调用的类或者闭包太复杂了。