在python中,如何只为函数存储“常量”?
某些函数需要“常量”值(即,未设计为稍后重新定义),这些值不会被参数化。 虽然默认参数对于每个函数只存储一次,但有些参数并不是很有意义(即成为签名的一部分)。 对于(不是很有用)的例子:
def foo(bar):
my_map = {"rab": barType, "oof": fooType}
return my_map.get(bar,defaultType)()
它浪费了CPU时间和RAM空间来为每次调用重新定义这样一个常量。 其他一些方法是将这些常量存储为模块级全局变量或将该函数设为可调用类,但是可能有其他方法,也许?
当采用模块级别的全局方式时,我用“_”来加我的(意思是一个)常量变量,以表明它不存在任何人的兴趣。 尽管如此,我仍然觉得模块命名空间稍微有点“污染”,而不是说使用某些令人沮丧的东西作为全局变量的羞耻感:
_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足够吗?
还有其他方法可以做到这一点吗?
作为使用这种“常量”的做法,它甚至可以吗?
请注意 ,我的示例中的这些对象不一定是实际的常量,而是根据其用途使用(并可以认为)。
将其设置为该函数的一个属性:
def foo(bar):
return foo.my_map.get(bar, defaultType)()
foo.my_map = {"rab": barType, "oof": fooType}
一个可调用的类或一个闭包不是简单的IMO。
恕我直言,模块级别的常量没有错。
请注意,根据PEP8,常数应该全部大写,如下所示:
_MY_MAP = {"rab": barType, "oof": fooType}
def foo(bar):
return _MY_MAP.get(bar,defaultType)()
标准库中的正则表达式模块使用这种风格,并且许多已建立的第三方库也可以使用。 如果您不确定,只需转到您的site-packages
目录和grep:
egrep "^_?[A-Z]+ =" *
做出尽可能独立的东西。 你可以创建一个函数对象(aka函数)类并给它一个__call__()
方法或一个classmethod
(但可能不是两个):
class bazType(object): pass
class barType(object): pass
class fooType(object): pass
class Foo(object):
_DEFAULT_TYPE = bazType
_MY_MAP = {"rab": barType, "oof": fooType}
def __call__(self, bar):
return self._MY_MAP.get(bar, self._DEFAULT_TYPE)()
@classmethod
def foo(cls, bar):
return cls._MY_MAP.get(bar, cls._DEFAULT_TYPE)()
# using classmethod
print Foo.foo("rab")
# using __call__ method
foo = Foo()
print foo("baz")
# alternative way to use classmethod
foo = Foo.foo
print foo("oof")
另一种方法是定义一个staticmethod
,我不会说明这个方法,因为它与其他两个类似 - 但你可以得到我希望的想法。
上一篇: In python, how to store 'constants' for functions only once?