常量在python中如何储存_global variables:在python中,如何存储常量?只对函数执行一次?...

有些函数需要"常量"值(例如。不设计用于稍后重新定义),即不进行参数化。虽然每个函数的默认参数只存储一次,但是有些参数作为参数并没有太大的意义(例如。成为签名的一部分)。For (a not very useful)例子:

def foo(bar):

my_map = {"rab": barType,"oof": fooType}

return my_map.get(bar,defaultType)()

为每个调用重新定义这样一个常量会浪费CPU时间和RAM空间。其他一些方法是存储诸如模块级全局变量之类的常量,或者使函数成为可调用类,但是可能还有其他方法?

当执行模块级全局方法时,我在(表示为a)常量变量前面加上一个"_",以表明它不存在,不符合任何人的兴趣。尽管如此,我仍然觉得模块名称空间有点"受污染",更不用说使用像全局变量这样令人沮丧的东西了:

_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)()

这些解够勾股定理吗?

还有其他方法吗?

作为一种实践,使用这样的"常量"可以吗?

注意,在我的示例中,这些对象不一定是实际的常量,但是它们的用途是这样使用的(并且可以这样认为)。

正如在其中一个答案中提到的(我也同意),您可能想要添加一条注释,以使它更加具体,即它是一个全局变量,而且,您希望阅读您的代码的人能够很好地理解Python。虽然我承认我也很好奇一个更优雅的解决方案!

全局常量很好。造成问题的是全球状态。

为什么要链接到xkcdsw而不是xkcd?o_0

将其设置为函数的属性:

def foo(bar):

return foo.my_map.get(bar, defaultType)()

foo.my_map = {"rab": barType,"oof": fooType}

,

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

如果这可以在类定义中完成,您能提供一些见解吗?我尝试使用实例、类或静态方法,结果要么是AttributeError,要么是NameError;同样不明显的是,如果可能的话,函数属性是否可以保持"接近"函数定义(以文件中的行数表示)?

这两种方法都有效:gist.github.com/anossov/5411655。

我的错误是,我实际上没有使用实例方法测试它们(我认为我做了——当我尝试使用@staticmethod或classmethod来测试它们时,在某些情况下它会给出"AttributeError: 'instancemethod' object没有属性",这欺骗了我)。所以我真正的问题似乎是使用@classmethod和@staticmethod装饰器。gist.github.com/naxa/5411709

这将工作:gist.github.com/anossov/5411711,但它并不漂亮。

依我之见,模块级常量没有什么问题。

注意,根据PEP8,常数应该都是大写的,就像这样:

_MY_MAP = {"rab": barType,"oof": fooType}

def foo(bar):

return _MY_MAP.get(bar,defaultType)()

标准库中的正则表达式模块使用这种风格,许多已建立的第三方库也使用这种风格。如果你不相信,就去你的site-packages目录和grep:

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

如果模块级全局对外部有意义,我还认为在Python中它是有用的。但是像这样的函数helper并不是很好的结构,因为只有它的名称显示了它的位置和用途。

我明白你的意思。我只是想指出,私有模块级常量相对来说比较常见,而且在Python中可能不被认为是反模式。我想这是品味的问题。

使之尽可能独立。您可以创建一个函数对象(又名函子)类,并给它一个__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,我将不对此进行说明,因为它与其他两个非常相似——但是我希望您能理解我的意思。

你也可以使用闭包:

def make_foo():

my_map = {"rab": barType,"oof": fooType}

def foo(bar):

return my_map.get(bar,defaultType)()

return foo

foo = make_foo()

我还建议将make_foo()改名为foo(),尽管这可能太多了;-)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值