为什么Python决定反对常量引用?

max*_*max 25 python language-features language-design reference constants

注意:我不是在谈论阻止重新绑定变量.我在谈论防止变量引用的内存的修改,以及通过嵌套容器跟随的任何内存.

我有一个大型数据结构,我想以只读方式将其公开给其他模块.在Python中执行此操作的唯一方法是深层复制我想要公开的特定部分 - 在我的情况下非常昂贵.

我确信这是一个非常普遍的问题,似乎一个恒定的参考将是一个完美的解决方案.但我必须遗漏一些东西.也许在Python中很难实现常量引用.也许他们并不像我认为的那样做.

任何见解将不胜感激.


虽然答案很有帮助,但我还没有看到为什么const难以实现或在Python中难以实现的原因.我猜"非Pythonic"也算是一个有效的理由,但它真的吗?Python确实对私有实例变量进行了加扰(从一开始__)以避免意外错误,并且const在精神上似乎没有那么不同.


编辑:我刚刚提供了一个非常适度的赏金.我正在寻找更多关于为什么Python没有const结束的细节.我怀疑原因是实施起来真的很难; 我想明白为什么这么难.

kni*_*tti 13

它与私有方法相同:因为同意成人的代码作者应该在不需要武力的情况下就界面达成一致.因为真正真正强制执行合同很难,并且这样做半途而废,导致了大量的hackish代码.

请使用Get-只描述符和境界清楚你的文档中,这些数据意味着为只读.毕竟,一个坚定的编码人员可能会找到一种方法来以不同的方式使用你的代码.

  • 我并不担心黑客行为.我只是在帮助自己避免错误.当我传递某个容器时,我调用可能(意外地)修改其内容的各种功能.我想知道这件事. (3认同)

Gar*_*ees 10

PEP 351中,Barry Warsaw提出了一种"冻结"任何可变数据结构的协议,类似于生成frozenset不可变集的方式.冻结的数据结构可以是可清除的,因此可以用作字典中的键.

该提议在python-dev上进行了讨论,Raymond Hettinger的批评最详细.

它不是你想要的,但它是我能找到的最接近的,并且应该让你对Python开发人员关于这个主题的想法有所了解.


Kat*_*iel 8

关于任何语言都有很多设计问题,其中大部分的答案都是"仅仅因为".很明显,像这样的常量会违背Python的意识形态.


但是,您可以使用描述符创建只读类属性.这不是微不足道的,但并不是很难.它的工作方式是你可以使用property装饰器创建属性(看起来像属性但在访问时调用方法的东西); 如果你制作一个getter而不是setter属性,那么你将获得一个只读属性.元类编程的原因是,由于__init__接收到一个完整形式的类实例,实际上你无法在这个阶段将属性设置为你想要的!相反,您必须在创建类时设置它们,这意味着您需要一个元类.

这个食谱的代码:

# simple read only attributes with meta-class programming

# method factory for an attribute get method
def getmethod(attrname):
    def _getmethod(self):
        return self.__readonly__[attrname]

    return _getmethod

class metaClass(type):
    def __new__(cls,classname,bases,classdict):
        readonly = classdict.get('__readonly__',{})
        for name,default in readonly.items():
            classdict[name] = property(getmethod(name))

        return type.__new__(cls,classname,bases,classdict)

class ROClass(object):
    __metaclass__ = metaClass
    __readonly__ = {'a':1,'b':'text'}


if __name__ == '__main__':
    def test1():
        t = ROClass()
        print t.a
        print t.b

    def test2():
        t = ROClass()
        t.a = 2

    test1()
Run Code Online (Sandbox Code Playgroud)

  • @Max:如果你想要嵌套的只读结构,那么是的,你必须每个级别实现一次这个想法,直到你点击不可变.你也可以编写自己的`dict`类来处理只读字典,修改`getitem`和`setitem`.它不会很好(或万无一失),因为它不是编写Python的方式. (2认同)