Python的想法3 [英] Ideas for Python 3

查看:65
本文介绍了Python的想法3的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开始一个新线程,所以我们可以在我之前的帖子Prothon的优点之后避免一些非生产性的
参数。按照Hahn先生的要求,我将避免使用Prothon这个名字。在这个新闻组的任何帖子的

主题中。请忽略旧帖子。


我也更新了我的网页 http://ece.arizona.edu/~edatools/Python

对Python 3有一些好主意的人欢迎贡献。

我希望GvR不会因为称它为Python 3而起诉我。 :>)


以下是原始提案:


<对Prothon语法的批评>


...这个简化有很多方面的b $ b方面,但对我而言,方法的统一

和函数是最大的好处。


所有方法看起来都像函数(学生已经理解)。

原型(类)看起来像模块。这将使教学OOP

变得更加简单,特别是对于我最关心的学生和专业工程师

(非CIS)。我教电子设计

工具,而非编程。目前的计划是包括一些基本的
Python,没有OOP。如果我可以在另外4个小时内添加OOP,我会这样做。


我写了一个关于原型语法的提案,我相信它已经捕获了

对于Prothon的优点是什么,而不是从Python中彻底离开了
。请参阅PrototypeSyntax.htm
http://ece.arizona.edu / ~edatools / Python / 我想从Python专家那里得到关于这个

语法的潜在问题的反馈
。主要问题是将现有的Python

程序自动转换为新语法。我是其中一个用户不会在Python中使用现有的库提供
,无论一些

替代语言有多好。


我还希望得到用户对他们喜欢的内容的反馈,或者

不喜欢这个提议。我将在

优点和缺点中总结这些反馈。提案部分。


以下是语法提案的一些摘录。请参阅上面的链接

以获得更好的格式化。


- Dave


建议的原型语法

=========================

< snip>


简化类的示例(原型)

==================== ========================


动物 - >哺乳动物 - >猫科动物 - >猫

------- ------- ------- -------

numAnimals numMammals numFelines numCats < br $> b $ b home home

__init __()__ init __()__ init __()__ init __()

.sound .sound

。名字

show()show()show()show()

talk()talk()

proto Animal(对象):#继承原始对象。

numAnimals = 0

home =" Earth"

....

<参见OOP章节在 http://ece.arizona.edu/~edatools/Python/

完整示例。>

....

proto Cat(猫):

numCats = 0

__init__ :( n =" unknown",s =" Meow"):

Feline .__ init __()

Cat.numCats + = 1

.name = n#设置实例变量。

.sound = s

show :():#定义静态方法。

Feline.show()

print" Cats:",Cat.numCats

talk :():

print"我的名字是..." .name

打印我是来自%s的%s %(。genus,.home)

Mammal.talk()#调用未绑定的函数。

print __self__ ###诊断检查。

cat1 = Cat()#创建实例。
带有cat1的
:#修改实例变量。

home =" Tucson"

genus =" feline"

name =" Garfield"

cat1.talk()
我的名字是......加菲猫

我来自图森的猫科动物

哺乳动物的声音:喵喵

< __ main__.Cat对象位于0x00A894B0>




来自当前Python的更改

===== ======================

- 关键字类已更改为proto。

- 全部方法具有相同的形式,与简单的功能相同。

- 重新排列函数标题行。 def - > :括号是

可选。

- self替换为一个前导点,并从arg

列表中删除。

- 当前实例可用,如果需要通过__self__

- 实例可以在with块中修改其属性。


的好处建议的语法

===========================

- 统一所有函数形式(绑定,未绑定,静态,类,

lambda)。所有都将具有与普通函数相同的形式

定义。这将使教学OOP变得更容易。学生将已经了解功能和模块
。 OOP是一个小小的进步。

原型看起来就像一个模块(除了实例

变量)。请参阅下面的原型和模块之间的相似之处。


- 使用显式的__self__变量可以避免神奇的第一个
参数,并且可以更容易地解释实例变量。请参阅下面的

部分,比较

Python中的实例变量与简化形式的简要说明。 OOP的完整演示,例如学习Python中的页面

295-390,第2版。

页面的数量可能是1/2。基本的演示不仅更简单,而且我们可以消除很多关于lambda函数,静态方法,

等的讨论。


- 原型的所有属性(包括数据和函数)将在一个整齐的列中显示为

,这样可以更轻松地查找特定属性

直观扫描一个程序。理解程序的结构

几乎和查看UML图一样快。


- Lambda关键字将消失。使用普通

函数语法的匿名函数可以非常紧凑。 (:x,y:x + y)


- 使用

__self__作为隐藏变量,方法定义不会变得混乱,减少打字。 />

- 更改实例的众多属性将更加方便。 (需要用例)


- 将Python程序迁移到Python 3将是自动的,并且可靠的是
。 ???

建议语法的优点和缺点

==================== ================

无类别


Con:建议的语法不是纯粹无类别的。这很重要

因为...... ???


统一方法和功能


Pro1:更少学习。


Con1:专家不在乎。初学者不需要高级方法

语法。


Pro2:用标准函数语法替换lambda。


Con2:???


明确__self__


Pro1:允许统一方法和功能。


Con1:???


Pro2:实例变量的解释更简单。


Con2:使用__self__而不是特殊第一个参数更少

显式。


Pro3:方法定义中打字减少,杂乱少。


Con3 :可以使用s或_而不是自我最小化打字和

杂乱。


" Assignment"函数定义的语法


Pro1:在一列中一目了然地查看所有变量。


Con1:???


Pro2:强调数据和函数之间的相似性

对象的属性。


Con2:???


符号代替def关键字


Pro:允许lambda函数包含在统一中。


Con:符号永远不会像关键字一样清晰。


带块


Pro:保存在每一行输入对象名称。 />

Con:在创建原型后很容易修改原型

创建将导致更多无纪律的编程。


与教学OOP相关的问题

===============================

原型和模块之间的平行

---------------------------------- ------

学生需要了解原型的百分之九十是

已经从他们对功能和模块的研究中得到了解。甚至

最好通过与模块的并行

情况进行比较来解释一些棘手的问题。

< snip>


Python中实例变量的说明

--------------------- ----------------------

"""类中函数内的一些变量有一个

self。字首。这是为了区分函数

中的局部变量和实例变量。通过搜索函数调用

的实例,可以在调用函数时找到这些实例变量

。这种方式的工作原理是从一个

实例调用该函数会导致该实例作为函数调用的第一个参数传递给

。因此,如果你调用cat1.talk(),那相当于

Cat.talk(cat1)如果你调用cat1.set_vars(" Garfield"," Meow"),那就是

相当于Cat.set_vars(cat1,Garfield,Meow)


当前实例自动神奇地插入参数作为

第一个参数,在你可以提供的任何其他参数之前调用

调用一个绑定的方法。到一个实例。注意:

区分实例和类在这里很重要。如果你从一个类调用一个函数,那么该函数不会绑定到任何一个

实例,你必须在第一个显式提供实例。

参数(Cat.talk(cat1))


变量名称self只是一个约定。只要你把第一个参数中的

同名,就像在定义的正文中一样,它可以是self或s甚至_单个下划线很方便如果你想要最大限度地抑制混乱,那么
。 """


简化实例变量的说明

------------------- -------------------------

"""原型函数内部的一些变量有一个

前导点。这是为了区分函数

中的局部变量和实例变量。当一个函数从一个实例调用时,一个特殊的全局变量__self__自动分配给该实例(__ self__ = cat1)然后当函数

需要一个实例变量(.sound)它使用__self__就像你在
点击它前面那样(__ self __。sound)前导点

只是一个缩写,以避免在任何地方输入__self__。 """


========== END ==============

解决方案

Mike,感谢您对这个

提案进行了非常彻底和深思熟虑的审核。


On Mon,26 Apr 2004 22:00:50 -0400,Mike C. Fletcher

< mc ****** @ rogers.com>写道:

David MacQuigg写道:
...

所有方法看起来都像函数(学生已经理解)。

我认为说你已经使用隐式定义的目标制作了所有函数
方法可能更合适,但我认为声明
在技术上仍然是正确的。 / blockquote>


没有实例变量的函数与在类外定义的函数

相同。在这种情况下,判断它是否是方法或函数的唯一方法是查看周围的代码。 方法

是那些倾向于推迟非CIS学生的神秘词汇之一。

当需要区分方法和功能时我会使用它,

但我不喜欢术语功能。它强调了与学生已经知道的相似的


提出的语法的好处
=== ========================
- 统一所有函数形式(绑定,未绑定,静态,类,
lambda) 。所有都将具有与正常功能定义相同的形式。这将使教学OOP变得更容易。学生将已经了解功能和模块。 OOP是一个小小的进步。
原型看起来就像一个模块(实例
变量除外)。请参阅下面的原型和模块之间的Parallels。


这很好。不是我会急于采用一种语言因为
它很好,但很好。我很好奇一件事:

proto x(对象):
flog :( x,y):
.x = x
a = x ()
b = x()
a.flog = b.flog
a.flog()
打印bx

换句话说,如何如果没有这样的东西并且只有最后一次访问,那么我是否对一个绑定的方法/函数有一个引用?确定
隐含目标是什么?为了清楚起见,我假设你要在某个地方存储*以便:

a = module.do
a()

有效。




绑定和非绑定函数的工作方式与Python类似。这是因为我需要特殊的绑定语法,因此我需要与Prothon不同。

- 使用显式的__self__变量避免了神奇的第一个参数,并且更容易解释实例变量。请参阅下面的部分,比较Python中的实例变量与简化形式的简要说明。 OOP的完整演示,如学习Python中的第295-390页,第2版。
页数可能是1/2。基本的演示不仅更简单,而且我们可以消除很多关于lambda函数,静态方法,
等的讨论。


这是一个清洗IMO ,明确的自我具有轻微优势
明确优于隐形理由。你现在必须解释
魔法__self__来自哪里,而不是当你访问实例的方法时自我约束。它们都是魔术,Python的东西只是明确可见。不过,既然你正在深入编写这种新语言,它将成为Whateverthon程序员的第一天性。

就个人而言,我所说的那一刻。 GOT"方法的概念
(Python是我的第一个OO语言)看到的是自我。在一个函数的参数列表中,通过执行x.method查找,它意识到它只是一个参数进入了
函数。也就是说,它看起来就像任何其他功能,参数只是一个参数,没有什么特别的,没有什么需要任何额外的知识,除了它如何绑定(并且那是'
漂亮简单)。来自结构+功能背景它完全有意义。




我假设没有其他背景,除了学生将会知道的内容

学习Python直到引入OOP。在这一点上,

他们对函数和全局变量有很好的理解。


我已经看过很多关于显性的讨论了。 Python中的self,

我必须得出结论,大多数都缺少真正的问题,

这是因为某些函数有一个特殊的事实,所以很复杂/>
第一个参数和其他人不同意。通过将显微镜聚焦在设置全局

变量与插入特殊的第一个参数之类的小东西上,很难比较替代品




我在比较复杂性时要做的是看基本的长度

但完整的教科书解释替代方案。我已经在本文末尾复制了

我在

OOP章节中对实例变量的解释 http://ece.arizona.edu/~edatools/Python/ 我还要

尽最大努力写出Python的

实例变量的等效解释。欢迎评论。另外,如果有人可以为Python的语法编写更好的解释,请发布。

- 全部原型的属性(数据和函数)将在一个整齐的列中,使得在视觉扫描程序时更容易找到特定的属性。理解程序的结构几乎和看UML图一样快。


不能说我觉得它特别引人注目,不是如果<无论如何,引入标点符号是成本。毕竟,我认识的大多数人都使用语法着色编辑器。




我们是否要假设语法着色是常态?这将在以下内容的可读性上产生一个

的差异:我使用IDLE作为我的Python

编辑器,我喜欢它,所以也许我只是服用语法着色为

授予。


对于函数def语法,我们应该考虑其他形式,

取决于多少清晰度或者我们想要的紧凑。任何这些

都是可以接受的:


func1 = function(x,y):

func1 = func(x, y):

func1 = def(x,y):

func1 = :( x,y):

func1 =:x, y:

:x,y:


最后一个表格用于我们现在有lambda x,y:


这里的符号和关键字的选择似乎是个人偏好的问题。我唯一的客观标准是

表格应该尽可能短,并且合理地接近

正常表格。详细程度是我不使用lambda的原因之一。

- Lambda关键字将消失。使用普通
函数语法的匿名函数可以非常紧凑。 (:x,y:x + y)


这个特殊的例子几乎尖叫不要这样做,不是吗?
:( x ,y):x + y我可以看到它是一种改进,但打哈欠,真的。使
函数定义表达式而不是语句具有相同的效果。顺便问一下,你怎么知道你的lambda什么时候结束?
如果用作表达式我需要收集()s?




我很长一段时间才意识到lamdas只比命名函数有一个优势......它们可以塞进狭小的空间。这里

就是一个例子:


L = [(lambda x:x ** 2),(lambda x:x ** 3),(lambda) x:x ** 4),(lambda

x:x ** 5)]


如果目的是节省空间,不会这样更好的是:


L = [:x:x ** 2,:x:x ** 3,:x:x ** 4:x:x ** 5]


我假设parens是可选的。是否有解析问题我是没有看到的?
我会添加parens只是因为我喜欢外观

func1 = :( x,y):


我也很高兴完全弃用lambda 。

- 使用
__ self__作为隐藏变量,方法定义不会变得混乱,减少打字。

我个人更喜欢明确暗示,但我知道有很多人在保存几个按键时很重要。




见上文关于显性的讨论。我没有看到任何优势

self.something的明确性.something - *提供*

领先的点不用于任何其他目的__self__的缩写




击键对我来说也不是什么大问题,但在这种情况下,

我们经常使用这种语法,我可以看到它会在哪里显着。

- 改变众多实例的属性将更加方便。 (需要使用案例)


这很好,但老实说,如果你在案件中做了很多这样的事情,那么琐碎的事情足以保证你应该加入无论如何,可能会使用域建模系统进行重构。尽管如此,如果你修改使用这样的工作:

x:
.this = 32
.that = 43
temp = ''这个''重复
.something = temp [:55]

即只是改变块的隐含目标,而不强制将所有
变量分配给对象,这似乎是一个很好的功能。




我'我不确定我是否理解你使用上面的主要点。我是否b $ b假设.something附加到x,当

with block完成后,temp被丢弃了?这将与使用

前导点作为__self__的缩写相冲突。为什么我们在这里关心

临时变量?如果它真的很重要,那么当我们完成时,仅仅是del x.temp会不会更容易?

Pro2:用标准函数语法替换lambda。

Con2:???


很好,但不需要为该保存重新定义拼写以使
定义本身是一个表达式,它将函数作为值返回,并允许用户删除名称。即a = def(y,z):如果你可以将结果分配给一个变量并且弄清楚你想要如何处理缩进延续的事情,那么y + z也可以正常工作

功能结束时。




权衡比较紧凑而不是符号上的关键字。

我不喜欢看到任何客观标准,除了lambda语法

应该类似于正常的sytnax。

明确__self __ < Pro1:允许统一方法和功能。

Con1:???


隐藏(隐含)魔法需要用户在将函数/方法视为一等对象时学习规则以确定目标是什么。真的没什么大不了的。

Pro2:实例变量的解释更简单。


嗯,不能说我认为这是一个巨大的教学胜利。一个函数
接受一个参数self并可以设置对象的属性,或者
函数可以访问一个神奇的全局参数。 __self__,它可以设置
属性。我同意对于
模块和类变量有相同的概念是很好的,但是看到这是一个巨大的胜利假设,我认为,那些被教导的人来自一个 ;全局和函数
背景而不是结构和函数背景。一种类型习惯于改变它们的执行环境,另一种类型只是改变那些作为
参数传递给函数的东西。




我假设除了Python之外没有其他任何背景

我们介绍OOP。那时,学生将理解全局变量和函数。我通过提供基本解释需要多少文本来衡量简洁性。请参阅

结尾处的示例。

Pro3:方法定义中输入更少,更简洁。<康文3:可以使用s或_而不是自我最大限度地减少打字和杂乱。


这是一个反击,而不是骗局。类似地,明确优于内隐。只是一个柜台,而不是骗局。 con将是:存在隐含来源的变量。或者太多标点符号。不要以为
要么是一个巨大的问题。

" Assignment"函数定义的语法

Pro1:在一列中一目了然地查看所有变量。

Con1:???


看起来不是一个特别强大的专业人士。 IOW似乎很少受益。至于con,眼睛,特别是在语法着色编辑器中非常好地选择关键字,而标点符号往往会模糊到其他标点符号。

Pro2:强调数据和函数之间的相似性作为对象的属性。

Con2:???


我看到亲,似乎约。对我来说也一样。

With Block

Pro:保存在每一行输入对象名称。

Con:制作它在创建原型之后太容易修改原型会导致更多无纪律的编程。


如指定的那样,它只对琐碎的作业有用。如果您在引入.x表示法以节省击键时遇到了麻烦,那么为什么不能简单地使用alter __self__来阻止块,这样您仍然可以区分临时和实例变量?




我在方法调用中专门为绑定对象使用__self__。


我最关心的是不希望在原型定义中的每个变量赋值中使引导点成为b / b
的标准。如果我们要用

来突出显示实例变量,并对学生说这是你已经知道的(模块)与你的内容之间的关键差异。 />
将学习下一个(原型),然后我不希望原型定义中的每个其他

变量看起来就像实例一样

变量。


我已经在我的提案中加入了块来取悦Prothon

人,但除非有人能提出用例,他们不是值得他们造成的混乱。

归根结底,这看起来好像是3个单独的提案:

*我喜欢.x符号的普遍适用性,从某种角度看它似乎简单而优雅
o我不喜欢隐含的__self__,但那是'不可或缺的
建议的一部分,所以洗了


如果我们能想出一个替代品我不需要多个

函数表单,我想考虑一下。

o我想要澄清如何存储对
另一个对象''(绑定)方法(在Python代码中用于存储的*非常常见),例如回调)


bf = cat1.func#其中cat1是一个不是原型的实例。

*我真的不喜欢:():函数定义表示法,
可读性计数。为什么混乱这个提案呢?


这对我来说很好看,但我可能不是美元的最佳判断。我会收集其他一些意见。如果足够

人们更喜欢def():(或def:对于lambda形式),我会改变

提案。


它是否会影响您的偏好?parens

可选?我会在正常的

函数中使用它们来实现enhnace可读性,但是将它们留在lambdas上。

*我对于这些东西是中立的:东西,我会的我更喜欢与Ruby类似的真正的块机制(如果我们使用隐式目标),
指定块的.x目标的能力


我从来没有理解Ruby代码块优于Python的优势

函数,但这是一个单独的讨论。

所以,.x符号似乎是这样的会很好,但没有别的
真的让我为此跳起来......

那就是说,我可能会愿意使用一种正在运行的语言使用支持语法的解析器/编译器的PythonVM。我对将Python代码自动翻译成新的
表单完全不感兴趣。这就是可以通过在同一个VM上运行来处理的事情,就像其他任何事情一样容易,然后您可以避免大量的迁移问题。


我不明白。如果你需要使用用Python 2编写的模块,

你需要至少某种包装才能使调用看起来像Python 3一样b $ b。好像有任何变化这不是后退

兼容使用Python 2至少需要可迁移。来自

早期版本,使用一些自动翻译器。这是我在考虑新语法时假设的主要

约束。这不是一个重要的要求吗?

所以,就像营销数据点一样;我不相信这显然是优越的,但我愿意尝试在.x方面尝试与Python不同的语言,看它是否值得。




再次感谢您的时间和精力。


- 戴夫


说明Python中的实例变量

===================================== ======

"""类中函数内的一些变量有一个

self。字首。这是为了区分函数

中的局部变量和实例变量。通过搜索函数调用

的实例,可以在调用函数时找到这些实例变量

。这种方式的工作原理是从一个

实例调用该函数会导致该实例作为函数调用的第一个参数传递给

。因此,如果你调用cat1.talk(),那相当于

Cat.talk(cat1)如果你调用cat1.set_vars(" Garfield"," Meow"),那就是

相当于Cat.set_vars(cat1,Garfield,Meow)


当前实例自动神奇地插入参数作为

第一个参数,在你可以提供的任何其他参数之前调用

调用一个绑定的方法。到一个实例。注意:

区分实例和类在这里很重要。如果你从一个类调用一个函数,那么该函数不会绑定到任何一个

实例,你必须在第一个显式提供实例。

参数(Cat.talk(cat1))


变量名称self只是一个约定。只要你把第一个参数中的

同名,就像在定义的正文中一样,它可以是self或s甚至_单个下划线很方便如果你想要最大限度地抑制混乱,那么
。 """


简化实例变量的说明

=================== =========================

"""原型函数内部的一些变量有一个

前导点。这是为了区分函数

中的局部变量和实例变量。当一个函数从一个实例调用时,一个特殊的全局变量__self__自动分配给该实例(__ self__ = cat1)然后当函数

需要一个实例变量(.sound)它使用__self__就像你在
点击它前面那样(__ self __。sound)前导点

只是一个缩写,以避免在任何地方输入__self__。 """


David MacQuigg写道:

[...]
我花了很长时间才意识到lamdas只比命名函数有一个优势 - 它们可以塞进狭小的空间。这里是一个例子:

L = [(lambda x:x ** 2),(lambda x:x ** 3),(lambda x:x ** 4), (lambda
x:x ** 5)]

如果目的是为了节省空间,那么这不会更好:

L = [ :x:x ** 2,:x:x ** 3,:x:x ** 4:x:x ** 5]



L = map(lambda x: lambda y:x ** y,范围(2,6))


差不多。或者写mapc(地图currying)并且有:


L = mapc(pow,范围(2,6))


比你的例子短,不容易出错,没有明显的lambda;)


干杯,

Michael


>>>>> "迈克尔" == Michael Walter< cm@leetspeak.org>写道:


Michael>几乎。或者写mapc(地图currying)并且有:


注意 - 名称mapc非常具有误导性,因为它看起来太多

就像Lisp mapc (mapcar,等同于普通的python地图)。


-

Ville Vainio http://tinyurl.com/2prnb


I am starting a new thread so we can avoid some of the non-productive
argument following my earlier post "What is good about Prothon". At
Mr. Hahn''s request, I will avoid using the name "Prothon" in the
subject of any post to this newsgroup. Please ignore the old thread.

I''ve also updated my webpage http://ece.arizona.edu/~edatools/Python
Anyone with some good ideas for "Python 3" is welcome to contribute.
I hope GvR won''t sue me for calling it "Python 3" :>)

Here is the original proposal:

< snip criticism of Prothon syntax >

... There are a number of
aspects to this simplification, but for me the unification of methods
and functions is the biggest benefit.

All methods look like functions (which students already understand).
Prototypes (classes) look like modules. This will make teaching OOP
much simpler, especially for the students and professional engineers
(non-CIS) that I am most concerned about. I teach electronic design
tools, not programming. Current plans are to include some basic
Python, no OOP. If I could add OOP with another 4 hours, I would do
it.

I''ve written a proposal for a prototype syntax that I believe captures
the essense of what is good in Prothon, while not departing too
radically from Python. see PrototypeSyntax.htm at
http://ece.arizona.edu/~edatools/Python/ I would like to get
feedback from Python experts on the potential problems with this
syntax. The major question is automatic translation of existing Python
programs to the new syntax. I''m one of those users who would not give
up the existing libraries in Python, no matter how good some
alternative language may be.

I would also like to get feedback from users on what they like or
dislike about this proposal. I will summarize this feedback in the
"Pros and Cons" section of the proposal.

Below are some excerpts from the syntax proposal. Please see the link
above for better formatting.

-- Dave

Proposed Prototype Syntax
=========================
< snip >

Example of Simplified Classes ( Prototypes )
============================================

Animal --> Mammal --> Feline --> Cat
------- ------- ------- -------
numAnimals numMammals numFelines numCats
home genus
__init__() __init__() __init__() __init__()
.sound .sound
.name
show() show() show() show()
talk() talk()
proto Animal(object): # Inherit from the primitive object.
numAnimals = 0
home = "Earth"
....
<see the "OOP Chapter" at http://ece.arizona.edu/~edatools/Python/
for the complete example.>
....
proto Cat(Feline):
numCats = 0
__init__ :( n = "unknown", s = "Meow" ):
Feline.__init__()
Cat.numCats += 1
.name = n # Set instance variables.
.sound = s
show :(): # Define a "static method".
Feline.show()
print " Cats:", Cat.numCats
talk :():
print "My name is ...", .name
print "I am a %s from %s" % (.genus, .home)
Mammal.talk() # Call an unbound function.
print __self__ ### Diagnostic check.

cat1 = Cat() # Create instance.
with cat1: # Modify instance variables.
home = "Tucson"
genus = "feline"
name = "Garfield"

cat1.talk() My name is ... Garfield
I am a feline from Tucson
Mammal sound: Meow
<__main__.Cat object at 0x00A894B0>



Changes from Current Python
===========================
-- Keyword class is changed to proto.
-- All methods have the same form, identical to a simple function.
-- Function header lines are re-arranged. def --> : Parentheses are
optional.
-- self is replaced with a leading dot, and eliminated from the arg
list.
-- Current instance is available if ever needed via __self__
-- Instances can have their attributes modified in a with block.

Benefits of Proposed Syntax
===========================
-- Unification of all function forms ( bound, unbound, static, class,
lambda ). All will have the same form as a normal function
definition. This will make it easier to teach OOP. Students will
already understand functions and modules. OOP is a small step up. A
prototype will look just like a module ( except for the instance
variables ). See Parallels between Prototypes and Modules below.

-- Using an explicit __self__ variable avoids the magic first
argument, and makes it easier to explain instance variables. See the
sections below comparing a brief explanation of instance variables in
Python vs the simplified form. A full presentation of OOP, like pages
295-390 in Learning Python, 2nd ed. will likely be 1/2 the number of
pages. Not only is the basic presentation simpler, but we can
eliminate a lot of discussion of lambda functions, static methods,
etc.

-- All attributes of a prototype ( both data and functions ) will be
in a neat column, making it easier to find a particular attribute when
visually scanning a program. Understanding the structure of a program
will be almost as quick as seeing a UML diagram.

-- Lambda keyword will be gone. An anonymous function using normal
function syntax can be extremely compact. ( :x,y:x+y )

-- Method definitions will be less cluttered and less typing with
__self__ as a hidden variable.

-- Changing numerous attributes of an instance will be more
convenient. ( need use case )

-- Migration of Python programs to Python 3 will be automatic and
reliable. ???

Pros and Cons of the Proposed Syntax
====================================
Classlessness

Con: The proposed syntax is not purely classless. This is important
because ... ???

Unification of Methods and Functions

Pro1: Less to learn.

Con1: Experts don''t care. Beginners don''t need advanced method
syntax.

Pro2: Replace lambdas with standard function syntax.

Con2: ???

Explicit __self__

Pro1: Allows the unification of methods and functions.

Con1: ???

Pro2: Explanation of instance variables is simpler.

Con2: Using __self__ instead of a special first argument is less
explicit.

Pro3: Less typing and less clutter in method definitions.

Con3: Can use "s" or "_" instead of "self" to minimize typing and
clutter.

"Assignment" Syntax for Function Definitions

Pro1: See all the variables at a glance in one column.

Con1: ???

Pro2: Emphasize the similarity between data and functions as
attributes of an object.

Con2: ???

Symbol instead of def Keyword

Pro: Allows lambda functions to be included in the unification.

Con: Symbols are never as clear as keywords.

With Block

Pro: Saves typing the object name on each line.

Con: Making it too easy to modify prototypes after they have been
created will lead to more undisciplined programming.

Issues relevant to teaching OOP
===============================
Parallels between Prototypes and Modules
----------------------------------------
Ninety percent of what students need to know about prototypes is
already understood from their study of functions and modules. Even
some tricky issues are best explained by comparing to a parallel
situation with modules.
< snip >

Explanation of Instance Variables in Python
-------------------------------------------
""" Some of the variables inside the functions in a class have a
self. prefix. This is to distinguish local variables in the function
from "instance variables". These instance variables will be found
when the function is called, by searching the instance which called
the function. The way this works is that calling the function from an
instance causes that instance to be passed as the first argument to
the function call. So if you call cat1.talk(), that is equivalent to
Cat.talk(cat1) If you call cat1.set_vars( "Garfield", "Meow"), that is
equivalent to Cat.set_vars(cat1, "Garfield", "Meow")

The "current instance" argument is auto-magically inserted as the
first argument, ahead of any other arguments that you may provide in
calling a method that is "bound" to an instance. Note: The
distinction between instances and classes is important here. If you
call a function from a class, that function is not bound to any
instance, and you have to supply the instance explicitly in the first
argument ( Cat.talk(cat1) )

The variable name self is just a convention. As long as you put the
same name in the first argument as in the body of the definition, it
can be self or s or even _ The single underscore is handy if you
want to maximally suppress clutter. """

Explanation of Simplified Instance Variables
--------------------------------------------
""" Some of the variables inside the functions in a prototype have a
leading dot. This is to distinguish local variables in the function
from "instance variables". When a function is called from an instance
( cat1.talk() ) a special global variable __self__ is automatically
assigned to that instance ( __self__ = cat1 ) Then when the function
needs an instance variable ( .sound ) it uses __self__ just as if you
had typed it in front of the dot ( __self__.sound ) The leading dot
is just an abbreviation to avoid typing __self__ everywhere. """

========== END ==============

解决方案

Mike, thanks for a very thorough and thoughtful review of this
proposal.

On Mon, 26 Apr 2004 22:00:50 -0400, "Mike C. Fletcher"
<mc******@rogers.com> wrote:

David MacQuigg wrote:
...

All methods look like functions (which students already understand).

I think it might be more proper to say that you''ve made all functions
methods with an implicitly defined target, but I suppose the statement
is still technically true.



A function with no instance variables is identical to a function
defined outside a class. In that case, the only way to tell if it is
a method or a function is to look at the surrounding code. "Method"
is one of those mystery words that tend to put off non-CIS students.
I use it when it is necessary to distinguish a method from a function,
but otherwise I prefer the term function. It emphasizes the
similarity to what the students already know.

Benefits of Proposed Syntax
===========================
-- Unification of all function forms ( bound, unbound, static, class,
lambda ). All will have the same form as a normal function
definition. This will make it easier to teach OOP. Students will
already understand functions and modules. OOP is a small step up. A
prototype will look just like a module ( except for the instance
variables ). See Parallels between Prototypes and Modules below.


This is nice. Not "I''m going to rush out to adopt a language because of
it" nice, but nice enough. I''m curious about one thing:

proto x( object ):
flog :( x, y ):
.x = x
a = x()
b = x()
a.flog = b.flog
a.flog()
print b.x

In other words, how do I hold a reference to a bound method/function if
there are no such things and only the "last access" determines what the
implicit target is? Just to be clear, I''m assuming you''re going to have
storage *somewhere* so that:

a = module.do
a()

works.



Bound and unbound functions work just like in Python. This is where I
differ with Prothon, on the need for special binding syntax.

-- Using an explicit __self__ variable avoids the magic first
argument, and makes it easier to explain instance variables. See the
sections below comparing a brief explanation of instance variables in
Python vs the simplified form. A full presentation of OOP, like pages
295-390 in Learning Python, 2nd ed. will likely be 1/2 the number of
pages. Not only is the basic presentation simpler, but we can
eliminate a lot of discussion of lambda functions, static methods,
etc.


This is a wash IMO, with the explicit "self" having a slight edge on
"Explicit is better than Implicit" grounds. You now have to explain
where the magic __self__ comes from instead of how self is bound when
you access the instance''s method. They''re both magic, the Python stuff
is just explicitly visible. Still, since you''re coding it deep into
this new language, it''ll be first nature to the Whateverthon programmer.

On a personal note, the moment where I "got" the concept of methods
(Python was my first OO language) was seeing "self" in the argument list
of a function and realising that it''s just a parameter curried into the
function by doing x.method lookup. That is, it just looked like any
other function, the parameter was just a parameter, nothing special,
nothing requiring any extra knowledge save how it got bound (and that''s
pretty darn simple). Coming from a structures+functions background it
made complete sense.



I assume no background other than what the students will know from
studying Python up to the point of introducing OOP. At this point,
they have a good understanding of functions and global variables.

I''ve seen a lot of discussion on the "explicitness" of self in Python,
and I have to conclude that most of it is missing the real problem,
which is complexity from the fact that some functions have a special
first argument and others don''t. It is hard to compare alternatives
by focusing our microscope on something as small as setting a global
variable vs inserting a special first argument.

What I would do in comparing complexity is look at the length of basic
but complete "textbook explanations" of the alternatives. I''ve copied
at the end of this post the explanation of instance variables from my
OOP chapter at http://ece.arizona.edu/~edatools/Python/ I''ve also
made my best effort to write an equivalent explanation of Python''s
instance variables. Comments are welcome. Also, if anyone can write
a better explanation for Python''s syntax, please post it.

-- All attributes of a prototype ( both data and functions ) will be
in a neat column, making it easier to find a particular attribute when
visually scanning a program. Understanding the structure of a program
will be almost as quick as seeing a UML diagram.


Can''t say I find it particularly compelling as an argument, not if
introducing punctuation-itis is the cost, anyway. Most people I know
use syntax colouring editors, after all.



Do we want to assume syntax coloring is the norm? This will make a
difference in the readability of :( ): I use IDLE for my Python
editor, and I love it, so maybe I''m just taking syntax coloring for
granted.

For the function def syntax, we should consider alternative forms,
depending on how much clarity or compactness we want. Any of these
would be acceptable:

func1 = function( x, y ):
func1 = func( x, y ):
func1 = def( x, y ):
func1 = :( x, y ):
func1 = : x, y :
:x,y:

The last form would be used where we now have lambda x,y:

It seems like the choice of symbols and keywords here is a matter of
personal preference. The only objective criteria I have is that the
short form should be as short as possible and reasonably close to the
normal form. Verbosity is one of the reasons I don''t use lambda.

-- Lambda keyword will be gone. An anonymous function using normal
function syntax can be extremely compact. ( :x,y:x+y )


That particular example almost screams "don''t do this", doesn''t it?
:(x,y): x+y I can see as an improvement, but yawn, really. Making
function definitions expressions rather than statements would have the
same effect. By the way, how do you know when your lambda is finished?
I gather the ()s are required if using as an expression?



It took me a long time to realize that lamdas have only one advantage
over named functions - they can be crammed into a tight space. Here
is an example:

L = [(lambda x: x**2), (lambda x:x**3), (lambda x:x**4), (lambda
x:x**5)]

If the purpose is to save space, wouldn''t this be better as:

L = [:x:x**2, :x:x**3, :x:x**4 :x:x**5]

I''m assuming the parens are optional. Is there a parsing problem I''m
not seeing? I would add parens simply because I like the appearance
of func1 = :( x, y ):

I would also be happy with just deprecating lambdas entirely.

-- Method definitions will be less cluttered and less typing with
__self__ as a hidden variable.


I personally prefer explicit to implicit, but I know there''s lots of
people who are big into saving a few keystrokes.



See discussion above on explicitness. I''m not seeing any advantage in
the explicitness of self.something over .something -- *provided* that
the leading dot is not used for any other purpose than an abbreviation
for __self__.

Keystrokes are not a big issue for me either, but in this case, where
we have such frequent use of the syntax, I can see where it would be
significant.

-- Changing numerous attributes of an instance will be more
convenient. ( need use case )


That''s nice, but honestly, if you''re doing a lot of this in cases
trivial enough to warrant the addition you should likely be refactoring
with a domain-modelling system anyway. Still, if you modify the with to
work something like this:

with x:
.this = 32
.that = 43
temp = ''this''*repeat
.something = temp[:55]

i.e. to just alter the implicit target of the block, not force all
variables to be assigned to the object, it seems a nice enough feature.



I''m not sure I understand your use of the leading dots above. Do I
assume that .something gets attached to x, and temp is discarded when
the with block is finished? This will conflict with the use of
leading dots as an abbreviation for __self__. Why do we care about
temp variables here? If it really matters, wouldn''t it be easier to
just del x.temp when we are done?

Pro2: Replace lambdas with standard function syntax.

Con2: ???


Fine, but no need to redefine the spelling for that save to make the
definition itself an expression that returns the function as a value and
allows one to drop the name. i.e. a = def ( y,z ): y+z would work just
as well if you could assign the result to a variable and figured out how
you wanted to handle the indentation-continuation thing to know when the
function ended.



The tradeoff is compactness vs preference for a keyword over a symbol.
I don''t see any objective criteria, except that the lambda syntax
should be similar to the normal sytnax.

Explicit __self__

Pro1: Allows the unification of methods and functions.

Con1: ???


Is hidden (implicit) magic that requires the user to learn rules as to
what the target is when treating functions/methods as first-class
objects. Not a big deal, really.

Pro2: Explanation of instance variables is simpler.

Con2: Using __self__ instead of a special first argument is less
explicit.


Um, can''t say I see this as a huge pedagogical win. A function either
takes an argument self and can set attributes of the object, or a
function has access to a magical "global" __self__ on which it can set
attributes. I''ll agree that it''s nice having the same concept for
module and class variables, but seeing that as a huge win assumes, I
think, that those being taught are coming from a "globals and functions"
background rather than a structures and functions background. One type
is accustomed to altering their execution environment, the other to
altering solely those things which are passed into the function as
parameters.



I am assuming no background at all other than Python up to the point
where we introduce OOP. At that point, students will understand both
global variables and functions. I measure simplicity by how much text
it takes to provide a basic explanation. See the samples at the end of
this post.

Pro3: Less typing and less clutter in method definitions.

Con3: Can use "s" or "_" instead of "self" to minimize typing and
clutter.


That''s a counter, not a con. Similarly "Explicit is better than
Implicit" is only a counter, not a con. A con would be: "presence of
variable of implicit origin" or "too much punctuation". Don''t think
either is a huge concern.

"Assignment" Syntax for Function Definitions

Pro1: See all the variables at a glance in one column.

Con1: ???


Doesn''t seem a particularly strong pro. IOW seems pretty minimal in
benefit. As for a con, the eye, particularly in a syntax-colouring
editor picks out keywords very well, while punctuation tends to blur
into other punctuation.

Pro2: Emphasize the similarity between data and functions as
attributes of an object.

Con2: ???


I see the pro, seems approx. the same to me.

With Block

Pro: Saves typing the object name on each line.

Con: Making it too easy to modify prototypes after they have been
created will lead to more undisciplined programming.


As specified, makes it only useful for trivial assignments. If you''re
going to all the trouble of introducing .x notation to save keystrokes,
why not simply have with alter __self__ for the block so you can still
distinguish between temporary and instance variables?



I''m using __self__ exclusively for the bind object in a method call.

My biggest concern is not wanting to make leading dots the norm on
every variable assignment in a prototype definition. If we are going
to highlight the instance variables, and say to students "This is the
key difference between what you already know (modules) and what you
are going to learn next (prototypes), then I don''t want every other
variable in the prototype definition to look just like the instance
variables.

I''ve included the with blocks in my proposal to please the Prothon
folks, but unless someone can come up with a use case, they are not
worth the confusion they are causing.
In the final analysis, this really seems like about 3 separate proposals:

* I like the .x notation''s universal applicability, it does seem
simple and elegant from a certain point of view
o I don''t like the implicit __self__, but that''s an integral
part of the proposal, so a wash
If we can come up with an alternative that doesn''t require multiple
function forms, I would like to consider it.
o I''d want clarification of how to store a reference to
another object''s (bound) method (which is *extremely* common
in Python code for storing, e.g. callbacks)
bf = cat1.func # where cat1 is an instance not a prototype.
* I really dislike the :( ): function definition notation,
"Readability Counts". Why clutter the proposal with that?
It looks good to me, but I''m probably not the best judge of
aesthetics. I''ll collect some other opinions on this. If enough
people prefer def ( ): ( or def : for the lambda form), I''ll change
the proposal.

Does it make a difference in your preference that the parens are
optional? I would use them to enhnace readability on normal
functions, but leave them out on lambdas.
* I''m neutral on the with: stuff, I''d much prefer a real block
mechanism similar to Ruby with (if we''re using implicit targets),
the ability to specify the .x target for the block
I''ve never understood the advantage of Ruby code blocks over Python
functions, but that is a separate discussion.
So, the .x notation seems like it would be nice enough, but nothing else
really makes me jump up and down for it...

That said, I''d probably be willing to use a language that was running on
the PythonVM with a parser/compiler that supported the syntax. I''d be
totally uninterested in automated translation of Python code to the new
form. That''s the kind of thing that can be handled by running on the
same VM just as easily as anything else and you then avoid lots of
migration headaches.
I don''t understand. If you need to use modules written in Python 2,
you would need at least some kind of wrapper to make the calls look
like Python 3. It seems like any changes that are not "backward
compatible" with Python 2 will need to be at least "migratable" from
earlier versions, using some automatic translator. That is the major
constraint I have assumed in thinking about new syntax. Is this not a
vital requirement?
So, just as a marketing data-point; I''m not convinced that this is
markedly superior, but I''d be willing to try a language that differed
from Python in just the .x aspects to see whether it was worthwhile.



Thanks again for your time and effort.

-- Dave

Explanation of Instance Variables in Python
===========================================
""" Some of the variables inside the functions in a class have a
self. prefix. This is to distinguish local variables in the function
from "instance variables". These instance variables will be found
when the function is called, by searching the instance which called
the function. The way this works is that calling the function from an
instance causes that instance to be passed as the first argument to
the function call. So if you call cat1.talk(), that is equivalent to
Cat.talk(cat1) If you call cat1.set_vars( "Garfield", "Meow"), that is
equivalent to Cat.set_vars(cat1, "Garfield", "Meow")

The "current instance" argument is auto-magically inserted as the
first argument, ahead of any other arguments that you may provide in
calling a method that is "bound" to an instance. Note: The
distinction between instances and classes is important here. If you
call a function from a class, that function is not bound to any
instance, and you have to supply the instance explicitly in the first
argument ( Cat.talk(cat1) )

The variable name self is just a convention. As long as you put the
same name in the first argument as in the body of the definition, it
can be self or s or even _ The single underscore is handy if you
want to maximally suppress clutter. """

Explanation of Simplified Instance Variables
============================================
""" Some of the variables inside the functions in a prototype have a
leading dot. This is to distinguish local variables in the function
from "instance variables". When a function is called from an instance
( cat1.talk() ) a special global variable __self__ is automatically
assigned to that instance ( __self__ = cat1 ) Then when the function
needs an instance variable ( .sound ) it uses __self__ just as if you
had typed it in front of the dot ( __self__.sound ) The leading dot
is just an abbreviation to avoid typing __self__ everywhere. """


David MacQuigg wrote:

[...]
It took me a long time to realize that lamdas have only one advantage
over named functions - they can be crammed into a tight space. Here
is an example:

L = [(lambda x: x**2), (lambda x:x**3), (lambda x:x**4), (lambda
x:x**5)]

If the purpose is to save space, wouldn''t this be better as:

L = [:x:x**2, :x:x**3, :x:x**4 :x:x**5]


L = map(lambda x: lambda y: x**y,range(2,6))

Almost. Or write mapc ("map currying") and have:

L = mapc(pow,range(2,6))

Shorter than your example, less mistake-prone, no obvious lambda at all ;)

Cheers,
Michael


>>>>> "Michael" == Michael Walter <cm@leetspeak.org> writes:

Michael> Almost. Or write mapc ("map currying") and have:

Note - the name mapc is very misleading, because it looks too much
like Lisp mapc (mapcar, equicalent to normal python map).

--
Ville Vainio http://tinyurl.com/2prnb


这篇关于Python的想法3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆