在Python中,如何只存储一次函数的“常量”?

问题描述 投票:0回答:4

某些函数需要不被参数化的“常量”值(即不被设计为以后重新定义)。虽然默认参数对于每个函数仅存储一次,但有些参数作为参数(即作为签名的一部分)并不是很有意义。对于(不是很有用)的例子:

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__ 设为

classmethod
,以避免创建实例的需要: class foo: my_map = {"rab": barType, "oof": fooType} @classmethod def __call__(cls,bar): return cls.my_map.get(bar,defaultType)()

这些解决方案足够Pythonic吗?

还有其他方法可以做到这一点吗?

使用这样的“常量”作为练习是否可以?

注意

我的示例中的这些对象不一定是实际的常量,而是根据其目的使用(并且可以认为)。

python global-variables constants
4个回答
18
投票
属性

: def foo(bar): return foo.my_map.get(bar, defaultType)() foo.my_map = {"rab": barType, "oof": fooType}

在我看来,可调用类或闭包不够简单。


6
投票

请注意,根据

PEP 8

,常量应全部大写,如下所示: _MY_MAP = {"rab": barType, "oof": fooType} def foo(bar): return _MY_MAP.get(bar,defaultType)()

标准库中的正则表达式模块使用这种风格,许多成熟的第三方库也采用这种风格。如果您不相信,只需转到您的 
site-packages

目录并 grep:

egrep "^_?[A-Z]+ =" *



3
投票

def make_foo(): my_map = {"rab": barType, "oof": fooType} def foo(bar): return my_map.get(bar,defaultType)() return foo foo = make_foo()



1
投票
function object

(又名 functor)类并给它一个 __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

,我不会对此进行说明,因为它与其他两个非常相似 - 但我希望你能明白我的想法。

    

© www.soinside.com 2019 - 2024. All rights reserved.