“ 当我用一个词时,Humpty Dumpty用一种相当鄙视的语气说,这意味着我选择它的意思,既不多也不少。问题是,爱丽丝说,你是否可以说出很多不同的词。
问题是,Humpty Dumpty说,这是主人 - 这就是全部。”
有时候,读过一点CS而不是很多CS(或者只是一种CS的太多)的人会在comp.lang.python上弹出并浪费大量精力试图告诉大家Python的使用情况一些它并没有真正使用的调用模型。事实证明,他们并不真正了解Python的模型,而且他们常常也不了解他们最喜欢的模型。
但是,没关系,你需要知道的唯一事情是Python的模型既不是“按值调用”也不是“按引用调用”(因为任何尝试将这些术语用于Python都要求你使用非标准的单词定义“ -值“和” - 参考“)。最准确的描述是CLU的“ 按对象调用 ”或“ 通过共享调用 ”。或者,如果您愿意,“ 按对象引用调用 ”。
如果你还没有这样做,你也应该阅读这篇文章。
以下摘录取自旧的comp.lang.python线程。有趣的部分是CLU文本,它们提供了Python调用模型的非常简洁的描述。
(有一天,我会把它变成一篇合适的文章...)
日期:2003年5月14日星期三08:48:08 +0200 >见 > > http://wombat.doc.ic.ac.uk/foldoc/foldoc.cgi?call-by-value > >您所描述的是按价值调用。 有趣的是,你引用FOLDOC,因为FOLDOC没有 在CLU中可以看到Python的模型作为call-by-value 条目: http://wombat.doc.ic.ac.uk/foldoc/foldoc.cgi?CLU “通过分享呼叫传递参数,类似于 call-by-value,除了参数是对象 并且只有在它们可变的情况下才能改变。“ 注意使用“相似”和“除外”这两个词。 有关CLU的对象和参数传递模型的简要说明, 见[1]。我想你会发现它很适合Python的模型。 Liskov等人的CLU参考手册[2]说(第14页): “我们通过sharing_调用传递技术_call的参数, 因为参数对象是在。之间共享的 调用者和被调用的例程。这种技术没有 对应于大多数传统的论证传递技术 (它类似于在LISP中传递的论点)。特别是它 不是因为价值的调用,因为 由被调用的例程形成的调用者将可以看到。 它不是通过引用调用,因为没有给出访问权限 调用者的变量,但仅限于某些对象。“ 注意使用“不”和重复使用“它不是”。 我要强调一下: “特别是因为突变而不是值得称呼 由被调用例程执行的参数将被显示 呼叫者,召集者。并且因为访问而不是参考 没有给出调用者的变量,而仅仅是某些变量 对象“。 CLU是在七十年代中期设计的,这本参考手册 发表于1979年。在其他文献中,CLU设计师有些 - 次将这个模型称为“按对象调用”[3],或者他们仔细 通过谈论“对象”而不是价值观来忽略这个问题 “引用其他对象的对象”而不是引用[1],但是 我找不到一个他们离开的地方“特别是 它不是通过价值来调用“它”是按价值调用“。 那你七十年代初被困的借口是什么?;-) </ F> 1)http://www.cs.berkeley.edu/~jcondit/pl-prelim/liskov77clu.pdf 2)http://www.lcs.mit.edu/publications/pubs/pdf/MIT-LCS-TR-225.pdf 3)http://www.lcs.mit.edu/publications/pubs/pdf/MIT-LCS-TR-561.pdf
日期:2003年5月14日星期三15:49:09 +0200 >同样有趣的是[分享号码]缺失 你读过“为什么这个定义丢失?” 页? (FOLDOC维护者添加了应该写的文章的链接 有一天,并跟踪链接获得的点击次数,所以他们 可以专注于人们真正想要阅读的事情) >为了一个很好的语义介绍,我会说 > >编程语言要点 > Daniel P. Friedman,Mitchell Wand,Christopher Thomas Haynes 如果你只有计划等 >我不熟悉CLU 我建议阅读参考文献3。 http://www.lcs.mit.edu/publications/pubs/pdf/MIT-LCS-TR-561.pdf CLU是OO语言发展的重要里程碑; 从上面的论文中引用利斯科夫本人的话: “关于CLU的工作,以及其他相关工作 Alphard,有助于明确数据抽象的概念 并使其精确。因此,这个概念被广泛使用 程序设计中的组织原则已成为一个 现代编程方法论的基石。“ 如果你不知道你的历史等 >但我认为这是对Python的论证传递的描述 >语义是误导。 你读过参考文献1吗? http://www.cs.berkeley.edu/~jcondit/pl-prelim/liskov77clu.pdf 如果您的PDF阅读器坏了,以下是相关部分 该文件(由我添加的任何拼写错误等)。 “CLU语义的基本元素是_objects_和 _variables_。对象是创建的数据实体 由CLU程序操纵。变量只是使用的名称 在程序中引用对象。 在CLU中,每个对象都有一个特定的_type_,它具有特征 它的行为。类型定义了一组创建的操作 并操纵该类型的对象。可以创建对象 并且只能通过其类型的操作进行操作。 对象可以_refer_到对象。例如,一个记录对象 指的是作为记录组件的对象。 这个概念是逻辑的,而不是物理的遏制。在 特别是,有两个不同的记录对象可能 引用(或_share_)相同的组件对象。如果是 一个循环结构,甚至可能是一个对象 “包含”本身。因此,可以具有递归数据 结构定义和共享数据对象没有显式 参考类型。/.../ CLU对象独立于过程激活而存在。空间 for对象是从动态存储区域/.../ In中分配的 理论上,所有物体永远存在。在实践中, 当对象不是时,对象使用的空间可以被回收 任何CLU计划都可以访问更长时间 对象可能表现出时变行为。这样的对象, 称为_mutable_对象,具有可以修改的状态 某些操作无需改变身份 宾语。/.../ 如果一个可变对象_m_由另外两个对象_x_和 _y_,然后通过_x_对_m_进行修改 _m_通过_y_进行检查。/.../ 调用不表现出时变行为的对象 _immutable_个对象或常量。常数的例子是 整数,布尔值,字符和字符串。a的价值 常量对象无法修改。例如,新字符串 可以从旧的计算,但现有的字符串不计算 更改。类似地,没有一个整数运算修改 整数作为参数传递给它们。 变量是CLU程序中用于_denote_特定的名称 执行时的对象。与许多常见的变量不同 编程语言,_are_对象_concon_ 值,CLU变量只是程序员使用的名称 引用对象。因此,有两个变量是可能的 表示(或_share_)同一个对象。CLU变量很多 与LISP中的那些一样,与其他的指针变量相似 语言。但是,CLU变量是_not_对象; 他们 不能用其他变量表示或引用 对象。/.../ CLU中的基本操作是_assignment_和_procedure invocation_。赋值原语'x:= E',其中_x_是a 变量和_E_是一个表达式,导致_x_表示 由_E_的评估产生的对象。例如,如果 _E_是一个简单的变量_y_,然后是赋值'x:= y' 导致_x_表示_y_表示的对象。对象是 _not_复制后,_x_和_y_将为_shared_。分配 不会影响任何对象的状态。(回想一下'rs:= v'不是真正的赋值,而是'put.s的缩写(r, V)”。) 过程调用涉及从中传递参数对象 调用被调用过程并返回结果对象 调用者的过程。一个正式的论点 程序被认为是程序的局部变量 并通过赋值初始化为结果对象 来自对参数表达式的评价。这样论证 对象在调用者和被调用过程之间共享。 一个过程可以修改可变参数对象(例如记录), 但当然它不能修改不可变的(例如整数)。 过程无法访问其调用者的变量。 程序调用可以直接用作语句; 那些 返回对象也可以用作表达式。随意 允许递归程序。“ 将“CLU”替换为“Python”,将“record”替换为“instance”和“procedure” 使用“功能或方法”,您将获得非常准确的描述 Python的对象模型。 如果您不同意,请告诉我们Python的不同之处。很 具体。 </ F>
日期:2003年5月15日星期四15:55:57 +0200 蒂姆彼得斯写道: >所以它 - 不管你信不信,有时不同的人意味着不同 >用相同的词语<wink>。 这就是为什么你应该只使用URL和URL来识别概念。 >歪曲“按价值呼吁”的意思是“内部地址” >对象是价值“即使在功能世界中也不常见, >虽然。 好吧,我想你可以在理论上重视分配的人为数字 一个对象和对象本身一样多。 “乔,我想我们的儿子可能会在树林里迷路” “别担心,我有他的社会安全号码” </ F>
日期:2003年5月15日星期四23:11:53 +0200 >不,这正是应用于Python值时的call-by-value意味着什么 >(实际上是r值)。尝试此操作时会发生什么: > > >>> y = [1,2,3] > >>> x = y > >>> x [:] = [-1] * 3 > >>> y > [-1,-1,-1] > >相同的行为,没有函数调用。 除了“x [:] =”*是*方法调用。 x [:] = [-1] * 3将切片对象和([-1] * 3)的结果传递给 x .__ setitem__方法,使用标准调用机制 (这就是语言参考中“被提问的对象”的内容 手段) “xy =”也是一个方法调用(__setattr__)。 所以是“x [y] =”(__ setitem__,再次)。 但是,“x = y”不是。 (三十年前,CLU也看起来有语法糖 喜欢不知情观察者的任务,但实际上还没有 另一种调用程序的方法。这里没什么新鲜的。) </ F>
日期:2003年5月15日星期四23:39:30 +0200 >根据约书亚,我和R5RS。R5RS说 > >“当稍后调用某个实际的程序时 >参数,lambda表达式所在的环境 >被评估将通过绑定变量来扩展 >在正式的论点清单中,新鲜的地点, >将存储相应的实际参数值 >在那些位置,以及身体中的表达 将按顺序评估lambda表达式的> >在扩展的环境中。“ > >根据定义,这是按值调用的。 但这不是Python的工作原理。 在Python中,形式参数列表中的变量绑定到 实际的参数对象。对象在调用者之间是_shared_ 和被叫者; 没有“新鲜的地点”或涉及额外的“商店”。 (当然,这就是为什么CLU人称这种机制为“呼叫 - 分享“。他们是真正的计算机科学家,为一个人工作 真正的计算机科学实验室;-) 和顺便说一下,Python函数不能在扩展环境中运行, 无论是。功能体对周围环境的访问非常有限 环境。但这是另一个故事。 </ F>
日期:2003年5月16日星期五00:25:45 +0200 >只是在这里,我不同意你的意见。我考虑Python值 >他们自己是对象引用 如果你继续发明自己的术语,你永远不会赢得这个 参数: http://www.python.org/doc/current/ref/objects.html “对象,价值观和类型” _Objects_是Python的数据抽象。一个中的所有数据 Python程序由对象或关系表示 对象之间。 每个对象都有一个标识,一个类型和一个值。一个对象 _identity_一旦创建就永远不会改变; 你可以 把它想象成对象在内存中的地址。/.../一个对象 _type_也是不可更改的。它确定了那些操作 一个对象支持(例如,``它有一个长度?'')还有 定义该类型对象的可能值。/.../ 某些对象的_value_可以更改。值可以的对象 改变据说是_mutable_; 价值不合的对象 创建后可更改的名称为_immutable_。 (这与CLU论文中的术语基本相同,除了 他们使用术语“状态”而不是Python的“价值”) ...所以我猜你一直在说的是Python 使用按身份调用,而不是按州调用。很公平。 </ F>
日期:2003年5月16日星期五01:05:37 +0200 >这是使用CLU值(对象)的按值调用的描述 >参考)。 所以?如果,在doug-speak中,对象引用是相同的 值,这也是对象引用的描述。 您的观点是,您可以重新定义单词以使其具有意义 任何你想要的?我想我们已经注意到了...... </ F>