作为学习Python的Java程序员,我应该注意什么?

我的编程背景大部分都是用Java编写的,而且我仍然在使用Java进行大部分编程。 不过,我开始在工作中学习一些边项目的Python,我想尽可能地独立于Java背景学习它 – 也就是说,我不想仅仅用Python编程Java。 我应该注意些什么?

一个简单的例子 – 在浏览Python教程的时候,我发现一个函数默认的可变参数(例如列表)被持久化(记住从调用到调用)。 对于我来说,这对于Java程序员来说是非常直观的,而且很难让我的头脑清醒。 (如果你不明白这个例子,请看这里和这里 )

有人还向我提供了这个清单,我发现这个清单很有帮助,但是很短。 任何人都有其他Java程序员如何滥用Python的例子…? 或者Java程序员会错误地假设或理解有困难?

编辑 :好吧,简要概述了我链接到的文章,以防止重复的答案(如蜥蜴比尔build议)的原因。 (请让我知道,如果我在表述中犯了一个错误,我刚刚开始使用Python,所以我可能不完全理解所有的概念,而且一个免责声明 – 这些将会非常简短,所以如果你不明白检查链接时得到了什么。)

  • Java中的静态方法不会转换为Python类方法
  • Java中的switch语句转换为Python中的哈希表
  • 不要使用XML
  • 吸气剂和吸附剂是邪恶的(嘿,我只是引用:))
  • 代码重复通常是Java中的一个必要的罪恶(例如方法重载),但不是Python

(如果你觉得这个问题很有意思,那么请查看链接:)这是相当不错的。)

  • 不要把所有东西都放进课堂 。 Python的内置列表和字典将带你走得更远。
  • 不要担心每个模块保留一个类 。 按目的划分模块,而不是按课程划分。
  • 对行为使用inheritance,而不是接口 。 不要为“Dog”和“Cat”创build一个“动物”类来inheritance,只要你有一个通用的“make_sound”方法即可。

只要这样做:

class Dog(object): def make_sound(self): return "woof!" class Cat(object): def make_sound(self): return "meow!" class LolCat(object): def make_sound(self): return "i can has cheezburger?" 

引用的文章有一些很好的build议,很容易被错误引用和误解。 还有一些不好的build议。

留下Java。 开始新鲜。 “不要相信你的[基于Java的]本能”。 在任何编程学科中,说事情都是“反直觉”是一个坏习惯。 当学习一种新的语言,开始新鲜,并放弃你的习惯。 你的直觉一定是错的。

语言是不同的 。 否则,他们会是不同语法的同一种语言,会有简单的翻译。 因为没有简单的翻译,所以没有简单的映射。 这意味着直觉是无益和危险的。

  • “Java中的静态方法不会转化为Python类方法”。 这种东西实际上是有限的,无益的。 Python有一个静态方法装饰器。 它也有一个classmethod装饰器,为此Java没有相应的东西。

    顺便说一句,顺便说一句,还包括更多有用的build议,不必在课堂上包装所有东西。 “Java静态方法的惯用翻译通常是一个模块级function”。

  • Java中的Java switch语句可以通过几种方式实现。 首先,通常是if elif elif elif构造。 这篇文章对这方面没有帮助。 如果你确定这个速度太慢(并且可以certificate这一点),你可以使用一个Python字典作为一个从值到代码块的稍微更快的映射。 盲目地将开关翻译成字典(没有想到)是一个非常糟糕的build议。

  • 不要使用XML。 没有意义,当脱离上下文。 在上下文中,它意味着不要依赖XML来增加灵活性。 Java依赖于描述XML中的东西; 例如,WSDL文件重复从检查代码中显而易见的信息。 Python依赖于自省,而不是用XML重新expression一切。

    但是Python有优秀的XML处理库。 一些。

  • Python中并不需要 Getters和Setter,它们是Java所需要的。 首先,你在Python中有更好的自省,所以你不需要getter和setter来帮助build立dynamic的bean对象。 (为此,您使用collections.namedtuple )。

    然而,你有属性装饰器,将getter(和setter)绑定到一个属性类构造。 重点是Python喜欢裸体属性; 必要时,我们可以将getter和setter绑定,看起来好像有一个简单的属性。

    另外,如果属性不够复杂的话,Python还有描述符类。

  • 代码重复通常是Java中的一个必要的罪恶(例如方法重载),但不是Python。 正确。 Python使用可选参数而不是方法重载。

    子弹点继续谈论closures; 这不像简单的build议明智地使用缺省参数值那样有帮助。

在Java中你可能习惯的一件事是你不能在Python中find的是严格的隐私。 这并不是什么值得注意的事情,因为这是不值得去寻找的东西(当我刚开始的时候,我为了一个相当于“私有”的Python而search了多长时间,我感到尴尬)。 相反,Python比Java更透明,更容易反省。 这有时被称为“我们都是在这里同意的成年人”的哲学。 有几个约定和语言机制可以帮助防止意外使用“非公共”方法等等,但是Python的信息隐藏的整个思维模式实际上是不存在的。

我能想到的最大的一个是不理解或不完全利用鸭子打字。 在Java中,您需要预先指定非常明确和详细的types信息。 在Python中,打字既是dynamic的,也是很隐含的。 哲学是,你应该考虑你的程序比名义types更高的水平。 例如,在Python中,您不使用inheritance来为可替代性build模。 作为鸭子打字的结果,可replace性是默认的。 inheritance只是程序员重用实现的方便之处。

类似的,Pythonic的成语是“乞求宽恕,不要求许可”。 显式打字被认为是邪恶的。 不要先检查参数是否属于某种types。 只要尝试做任何你需要做的参数。 如果它不符合正确的界面,它将抛出一个非常明显的例外,你将能够很快find问题。 如果有人传递了一个名义上意想不到的types的参数,但是具有与您所期望的相同的接口,那么您已经获得了免费的灵活性。

从Java POV来看,最重要的一点是,不要为所有的东西做类。 有很多情况下程序方法更简单和更短。

其次,最重要的是你必须克服一个对象的types控制它可能做什么的概念; 相反, 代码控制什么对象必须能够在运行时支持(这是由于鸭子打字)。

哦,尽可能地使用本地列表和字典(不是自定义的后代)。

在Python中处理exception的方式与在Java中处理exception的方式不同。 而在Java中,build议是只在特殊情况下使用exception,而Python则不然。

在Python中,Iterator使用exception机制来表示没有更多的项目,但是这样的devise在Java中并不被认为是好的做法。

正如Alex Martelli在他的书“ Python in the Nutshell ”中提到的那样 ,其他语言(适用于Java)的exception机制是LBYL (在你跳跃之前):在尝试操作之前,事先检查所有可能使操作无效。

和Python一样,这个方法是EAFP(请求宽恕比允许更容易)

“不要使用类的一切”的callback:callback。

执行callback的Java方法依赖于传递实现callback接口的对象(例如ActionListener及其actionPerformed()方法)。 Python中不需要这样的东西,你可以直接传递方法甚至是本地定义的函数:

 def handler(): print("click!") button.onclick(handler) 

甚至lambda:

 button.onclick(lambda: print("click!\n"))