代码之家  ›  专栏  ›  技术社区  ›  max

为什么python决定不使用常量引用?

  •  25
  • max  · 技术社区  · 14 年前

    注意:我不是说要防止变量重新绑定。我说的是防止修改变量引用的内存,以及通过遵循嵌套容器可以从中访问的任何内存。

    我有一个大的数据结构,我想以只读的方式将它公开给其他模块。在Python中实现这一点的唯一方法是深度复制我想公开的特定部分——在我的例子中,这是非常昂贵的。

    我相信这是一个很常见的问题,似乎一个恒定的参考值是完美的解决方案。但我一定错过了什么。也许常量引用很难在Python中实现。也许他们不像我想的那样做。

    任何见解都会受到赞赏。


    虽然答案很有用,但我还没有看到一个单一的原因来解释为什么const在python中既难以实现,也无法工作。我想“联合国蟒蛇”也算是一个合理的理由,但它真的是吗?python确实会对私有实例变量进行加扰(从 __ )避免意外的错误,以及 const 精神上似乎没有什么不同。


    编辑:我只是提供了一个非常谦虚的赏金。我在寻找更多关于为什么Python最终没有const的细节。我怀疑原因是很难实现完美的工作;我想理解为什么它如此困难。

    5 回复  |  直到 14 年前
        1
  •  10
  •   Gareth Rees    14 年前

    PEP 351 巴里华沙提出了一个“冻结”任何可变数据结构的协议,类似于 frozenset 生成不可变集。冻结的数据结构将是可散列的,因此可以用作字典中的键。

    建议是 discussed on python-dev Raymond Hettinger's criticism 最详细的。

    这不完全是你想要的,但它是我能找到的最接近的,并且应该给你一些关于这个主题的Python开发人员的想法。

        2
  •  13
  •   knitti freethinker    14 年前

    与私有方法相同: as consenting adults 代码的作者应该在不需要强制的情况下就接口达成一致。因为真的 真的? 执行合同是 坚硬的 而以半途而废的方式进行则会导致大量的黑客代码。

    使用get only描述符,并在文档中清楚地说明这些数据是 意味 只读。毕竟,一个坚定的编码人员可能会找到一种方法,以不同的方式使用你的代码,不管你怎么想。

        3
  •  8
  •   Katriel    14 年前

    任何一种语言都有许多设计问题,大多数问题的答案是“仅仅因为”。很明显,像这样的常量会违背Python的思想。


    但是,可以使用 descriptors . 这不是小事,但并不难。它的工作方式是,可以使用 property decorator;如果生成getter而不是setter属性,则将获得只读属性。元类编程的原因是因为 __init__ 接收 完全成形 类的实例,在这个阶段实际上不能将属性设置为所需的属性!相反,您必须在创建类时设置它们,这意味着您需要一个元类。

    代码来自 this recipe :

    # 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()
    
        4
  •  1
  •   fungusakafungus    14 年前

    虽然一个编写代码的程序员是一个同意的成年人,但两个使用同一代码的程序员很少是同意的成年人。更重要的是,如果他们不重视代码的美观,但他们的最后期限或研究基金。

    对于这样的成年人,有一些类型的安全,由热情的 Traits

    你可以调查一下 Constant and ReadOnly 特点。

        5
  •  1
  •   Community CDub    7 年前

    对于一些额外的想法,这里有一个关于Java的类似问题:
    Why is there no Constant feature in Java?

    当问到为什么蟒蛇 决定反对 常量引用,我认为考虑如何在语言中实现它们是很有帮助的。如果python有某种特殊声明, 康斯特 ,创建无法更改的变量引用?为什么不允许变量被声明为float/int/whateththen……这些当然有助于防止编程错误。在这里,添加类和方法修饰符(如protected/private/public/etc)将有助于强制编译类型检查,以防非法使用这些类。很快,我们就失去了Python的美丽、简洁和优雅,而我们正在编写C++的一些杂种孩子的代码。

    python目前还通过引用传递所有内容。这将是某种特殊的传递引用,但要标记它以防止修改……这是一个非常特殊的情况(正如Python的道所指出的,只是“un pythonic”)。

    如前所述,在不实际更改语言的情况下,这种类型的行为可以通过类和描述符实现。它可能无法阻止坚决黑客的修改,但我们是同意的成年人。巨蟒不一定 决定 反对将其作为一个包含的模块(“包括电池”)来提供——对它的需求从来就不够。

    推荐文章