作为学习Python的Java程序员,我应该注意些什么?
我之前主要用Java编程,现在大部分工作还是在用Java。不过,我开始学习Python,想用它来做一些工作上的小项目。我希望能尽量不受Java背景的影响来学习Python,也就是说,我不想只是把Java的写法搬到Python里。请问我应该注意哪些方面呢?
举个简单的例子,在看Python教程的时候,我发现函数的默认可变参数(比如列表)会在多次调用中被记住。这对我这个Java程序员来说有点反直觉,让我很难理解。(如果你不明白这个例子,可以看看这里和这里。)
还有人给我提供了这个列表,我觉得挺有帮助,但内容有点少。有没有其他人能分享一些Java程序员在使用Python时容易出错的例子?或者是一些Java程序员可能会错误假设或理解困难的地方?
补充说明:好的,我简单总结一下我链接的文章中提到的原因,以避免答案重复(这是Bill the Lizard的建议)。(如果我表述有误,请告诉我,我刚开始学习Python,可能还不太理解所有概念。而且需要说明的是,这些总结会非常简短,如果你不明白,可以去看看链接。)
- Java中的静态方法在Python中并不等同于类方法
- Java中的switch语句在Python中对应的是哈希表
- 不要使用XML
- 获取器和设置器是邪恶的(嘿,我只是引用一下 :))
- 在Java中,代码重复往往是必要的(比如方法重载),但在Python中不是这样
(如果你觉得这个问题有趣,还是去看看那个链接吧。:) 内容挺不错的。)
7 个回答
在Java中,你可能习惯了严格的隐私保护,但在Python中就没有这种严格的规定。这并不是说你需要特别注意什么,而是说你根本不需要去找类似的东西(我刚开始学Python的时候,花了很长时间在找'private'的对应写法上,真是尴尬!)。相反,Python比Java更透明,也更容易进行代码检查。这个特点有时被称为“我们都是成年人”哲学。虽然Python有一些约定和机制来帮助防止意外使用那些“非公开”的方法,但整体来说,Python几乎没有信息隐藏的这种思维方式。
这篇文章里有一些不错的建议,但也有容易被误解的地方,还有一些不太好的建议。
放下Java,重新开始。不要相信你在[Java基础]上的直觉。说某些事情“违反直觉”在任何编程领域都是个坏习惯。当学习一门新语言时,要从头开始,抛掉旧习惯。你的直觉一定是错的。
不同的编程语言是不同的。否则,它们就会是同一种语言,只是语法不同,那样就会有简单的翻译工具。因为没有简单的翻译工具,所以也没有简单的对应关系。这意味着依赖直觉是没用的,甚至是危险的。
在Java中的静态方法并不能直接对应到Python的类方法。这种说法其实很有限,也不太有帮助。Python有一个staticmethod装饰器,还有一个classmethod装饰器,而Java没有类似的东西。
顺便提一下,这一点还包括了一个更有帮助的建议,就是不要把所有东西都不必要地包裹在类里。“Java静态方法的习惯性翻译通常是模块级别的函数”。
Java中的
switch
语句可以用几种方式实现。首先,它通常是一个if elif elif elif
的结构。文章在这方面并没有提供帮助。如果你非常确定这太慢(并且能证明),你可以使用Python字典作为从值到代码块的稍微快一点的映射。盲目地把switch翻译成字典(不加思考)是个很糟糕的建议。不要使用XML。单独拿出来说没有意义。在上下文中,它的意思是不要依赖XML来增加灵活性。Java依赖用XML来描述东西;例如,WSDL文件重复了从代码中检查出来的明显信息。而Python则依赖于自省,而不是把所有东西都重述一遍在XML中。
不过,Python有很棒的XML处理库,有好几个。
在Python中,getter和setter并不是像在Java中那样必需的。首先,Python有更好的自省能力,所以你不需要getter和setter来帮助创建动态的bean对象。(为此,你可以使用collections.namedtuple)。
不过,你可以使用property装饰器,将getter(和setter)打包成类似属性的结构。关键是Python更喜欢直接的属性;在必要时,我们可以将getter和setter打包,看起来就像是一个简单的属性。
另外,如果属性不够复杂,Python还有描述符类。
在Java中,代码重复往往是个必要的坏事(例如方法重载),但在Python中不是。没错,Python使用可选参数来代替方法重载。
这个要点还提到了闭包;但其实用明智的默认参数值来解决问题更简单。
- 别把所有东西都放到类里。Python自带的列表和字典能帮你解决很多问题。
- 不用担心每个模块只放一个类。模块可以根据功能来划分,而不是只看类的数量。
- 用继承来实现行为,而不是接口。别为了让“狗”和“猫”这两个类继承一个“动物”类而去创建它,只是为了有一个通用的“发声”方法。
只需这样做:
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?"